From c3c3ca763b04e03de1210e6f995d491d4bedc1fd Mon Sep 17 00:00:00 2001 From: Rajesh Kumar Date: Mon, 27 Jan 2025 17:07:55 +0530 Subject: [PATCH 01/30] AC-13818::Make ES8 to be default for 2.4.8 instead of ES7 --- app/code/Magento/Elasticsearch/composer.json | 2 +- .../System/Config/TestConnection.php | 35 - app/code/Magento/Elasticsearch7/README.md | 28 - .../Model/Adapter/IndexNameResolverTest.php | 282 ------- .../DataProvider/Base/SuggestionsTest.php | 298 -------- .../Aggregation/IntervalTest.php | 325 --------- .../Test/Unit/SearchAdapter/AdapterTest.php | 354 --------- .../Test/Unit/Setup/InstallConfigTest.php | 87 --- .../Test/Unit/Setup/ValidatorTest.php | 93 --- .../Magento/Elasticsearch7/etc/config.xml | 22 - .../System/Config/TestConnection.php | 35 + .../LICENSE.txt | 0 .../LICENSE_AFL.txt | 0 .../DynamicTemplates/IntegerMapper.php | 18 +- .../DynamicTemplates/MapperInterface.php | 5 +- .../DynamicTemplates/PositionMapper.php | 18 +- .../Adapter/DynamicTemplates/PriceMapper.php | 18 +- .../Adapter/DynamicTemplates/StringMapper.php | 18 +- .../Adapter/DynamicTemplatesProvider.php | 10 +- .../Model/Adapter/Elasticsearch.php | 51 ++ .../FieldName/Resolver/DefaultResolver.php | 10 +- .../Model/Client/Elasticsearch.php | 358 +++++---- app/code/Magento/Elasticsearch8/README.md | 26 + .../SearchAdapter/Adapter.php | 87 +-- .../SearchAdapter/Mapper.php | 17 +- ...chUsingElasticSearch8ByProductSkuTest.xml} | 29 +- .../Resolver/DefaultResolverTest.php | 28 +- .../Unit/Model/Client/ElasticsearchTest.php | 453 +++++------- .../composer.json | 11 +- .../etc/adminhtml/system.xml | 46 +- .../Magento/Elasticsearch8/etc/config.xml | 22 + .../etc/di.xml | 131 ++-- .../etc/module.xml | 2 +- .../etc/search_engine.xml | 2 +- .../registration.php | 2 +- composer.json | 3 +- composer.lock | 689 +++++++++++++++--- 37 files changed, 1288 insertions(+), 2327 deletions(-) delete mode 100644 app/code/Magento/Elasticsearch7/Block/Adminhtml/System/Config/TestConnection.php delete mode 100644 app/code/Magento/Elasticsearch7/README.md delete mode 100644 app/code/Magento/Elasticsearch7/Test/Unit/Model/Adapter/IndexNameResolverTest.php delete mode 100644 app/code/Magento/Elasticsearch7/Test/Unit/Model/DataProvider/Base/SuggestionsTest.php delete mode 100644 app/code/Magento/Elasticsearch7/Test/Unit/Model/SearchAdapter/Aggregation/IntervalTest.php delete mode 100644 app/code/Magento/Elasticsearch7/Test/Unit/SearchAdapter/AdapterTest.php delete mode 100644 app/code/Magento/Elasticsearch7/Test/Unit/Setup/InstallConfigTest.php delete mode 100644 app/code/Magento/Elasticsearch7/Test/Unit/Setup/ValidatorTest.php delete mode 100644 app/code/Magento/Elasticsearch7/etc/config.xml create mode 100644 app/code/Magento/Elasticsearch8/Block/Adminhtml/System/Config/TestConnection.php rename app/code/Magento/{Elasticsearch7 => Elasticsearch8}/LICENSE.txt (100%) rename app/code/Magento/{Elasticsearch7 => Elasticsearch8}/LICENSE_AFL.txt (100%) rename app/code/Magento/{Elasticsearch7 => Elasticsearch8}/Model/Adapter/DynamicTemplates/IntegerMapper.php (56%) rename app/code/Magento/{Elasticsearch7 => Elasticsearch8}/Model/Adapter/DynamicTemplates/MapperInterface.php (69%) rename app/code/Magento/{Elasticsearch7 => Elasticsearch8}/Model/Adapter/DynamicTemplates/PositionMapper.php (60%) rename app/code/Magento/{Elasticsearch7 => Elasticsearch8}/Model/Adapter/DynamicTemplates/PriceMapper.php (60%) rename app/code/Magento/{Elasticsearch7 => Elasticsearch8}/Model/Adapter/DynamicTemplates/StringMapper.php (61%) rename app/code/Magento/{Elasticsearch7 => Elasticsearch8}/Model/Adapter/DynamicTemplatesProvider.php (80%) create mode 100644 app/code/Magento/Elasticsearch8/Model/Adapter/Elasticsearch.php rename app/code/Magento/{Elasticsearch7 => Elasticsearch8}/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolver.php (80%) rename app/code/Magento/{Elasticsearch7 => Elasticsearch8}/Model/Client/Elasticsearch.php (57%) create mode 100644 app/code/Magento/Elasticsearch8/README.md rename app/code/Magento/{Elasticsearch7 => Elasticsearch8}/SearchAdapter/Adapter.php (52%) rename app/code/Magento/{Elasticsearch7 => Elasticsearch8}/SearchAdapter/Mapper.php (58%) rename app/code/Magento/{Elasticsearch7/Test/Mftf/Test/StorefrontQuickSearchUsingElasticSearchByProductSkuTest.xml => Elasticsearch8/Test/Mftf/Test/StorefrontQuickSearchUsingElasticSearch8ByProductSkuTest.xml} (75%) rename app/code/Magento/{Elasticsearch7 => Elasticsearch8}/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolverTest.php (95%) rename app/code/Magento/{Elasticsearch7 => Elasticsearch8}/Test/Unit/Model/Client/ElasticsearchTest.php (60%) rename app/code/Magento/{Elasticsearch7 => Elasticsearch8}/composer.json (68%) rename app/code/Magento/{Elasticsearch7 => Elasticsearch8}/etc/adminhtml/system.xml (65%) create mode 100644 app/code/Magento/Elasticsearch8/etc/config.xml rename app/code/Magento/{Elasticsearch7 => Elasticsearch8}/etc/di.xml (68%) rename app/code/Magento/{Elasticsearch7 => Elasticsearch8}/etc/module.xml (91%) rename app/code/Magento/{Elasticsearch7 => Elasticsearch8}/etc/search_engine.xml (90%) rename app/code/Magento/{Elasticsearch7 => Elasticsearch8}/registration.php (89%) diff --git a/app/code/Magento/Elasticsearch/composer.json b/app/code/Magento/Elasticsearch/composer.json index 2b9b6fa2569..26f357d7608 100644 --- a/app/code/Magento/Elasticsearch/composer.json +++ b/app/code/Magento/Elasticsearch/composer.json @@ -12,7 +12,7 @@ "magento/module-store": "*", "magento/module-catalog-inventory": "*", "magento/framework": "*", - "magento/elasticsearch": "^1.0.0" + "elasticsearch/elasticsearch": "^8.15" }, "suggest": { "magento/module-config": "*" diff --git a/app/code/Magento/Elasticsearch7/Block/Adminhtml/System/Config/TestConnection.php b/app/code/Magento/Elasticsearch7/Block/Adminhtml/System/Config/TestConnection.php deleted file mode 100644 index fe9fc76e06b..00000000000 --- a/app/code/Magento/Elasticsearch7/Block/Adminhtml/System/Config/TestConnection.php +++ /dev/null @@ -1,35 +0,0 @@ - 'catalog_search_engine', - 'hostname' => 'catalog_search_elasticsearch7_server_hostname', - 'port' => 'catalog_search_elasticsearch7_server_port', - 'index' => 'catalog_search_elasticsearch7_index_prefix', - 'enableAuth' => 'catalog_search_elasticsearch7_enable_auth', - 'username' => 'catalog_search_elasticsearch7_username', - 'password' => 'catalog_search_elasticsearch7_password', - 'timeout' => 'catalog_search_elasticsearch7_server_timeout', - ]; - - return array_merge(parent::_getFieldMapping(), $fields); - } -} diff --git a/app/code/Magento/Elasticsearch7/README.md b/app/code/Magento/Elasticsearch7/README.md deleted file mode 100644 index c4b2ddfdeec..00000000000 --- a/app/code/Magento/Elasticsearch7/README.md +++ /dev/null @@ -1,28 +0,0 @@ -# Magento_Elasticsearch7 module - -Magento_Elasticsearch7 module allows using ElasticSearch engine 7.x version for the product searching capabilities. - -The module implements Magento_Search library interfaces. - -## Installation details - -The Magento_Elasticsearch7 module is one of the base Magento 2 modules. Disable or uninstall this module is not recommends. - -For information about a module installation in Magento 2, see [Enable or disable modules](https://experienceleague.adobe.com/docs/commerce-operations/installation-guide/tutorials/manage-modules.html). - -## Structure - -`SearchAdapter/` - the directory that contains solutions for adapting ElasticSearch query searching. - -For information about a typical file structure of a module in Magento 2, see [Module file structure](https://developer.adobe.com/commerce/php/development/build/component-file-structure/#module-file-structure). - -## Additional information - -For information about significant changes in patch releases, see [2.4.x Release information](https://experienceleague.adobe.com/docs/commerce-operations/release/notes/overview.html). - -More information about ElasticSearch are at articles: - -- [Configuring Catalog Search](https://experienceleague.adobe.com/docs/commerce-admin/catalog/catalog/search/search-configuration.html). -- [Installation Guide/Elasticsearch](https://experienceleague.adobe.com/docs/commerce-operations/installation-guide/prerequisites/search-engine/overview.html). -- [Configure and maintain Elasticsearch](https://experienceleague.adobe.com/docs/commerce-operations/configuration-guide/search/overview-search.html). -- Magento Commerce Cloud - [set up Elasticsearch service](https://experienceleague.adobe.com/docs/commerce-cloud-service/user-guide/configure/service/elasticsearch.html). diff --git a/app/code/Magento/Elasticsearch7/Test/Unit/Model/Adapter/IndexNameResolverTest.php b/app/code/Magento/Elasticsearch7/Test/Unit/Model/Adapter/IndexNameResolverTest.php deleted file mode 100644 index 5b35623b709..00000000000 --- a/app/code/Magento/Elasticsearch7/Test/Unit/Model/Adapter/IndexNameResolverTest.php +++ /dev/null @@ -1,282 +0,0 @@ -objectManager = new ObjectManagerHelper($this); - $objects = [ - [ - DynamicTemplatesProvider::class, - $this->createMock(DynamicTemplatesProvider::class) - ] - ]; - $this->objectManager->prepareObjectManager($objects); - $this->connectionManager = $this->getMockBuilder(ConnectionManager::class) - ->disableOriginalConstructor() - ->onlyMethods([ - 'getConnection', - ]) - ->getMock(); - - $this->clientConfig = $this->getMockBuilder(Config::class) - ->disableOriginalConstructor() - ->addMethods(['getIndexSettings']) - ->onlyMethods([ - 'getIndexPrefix', - 'getEntityType', - ]) - ->getMock(); - - $this->logger = $this->getMockBuilder(LoggerInterface::class) - ->disableOriginalConstructor() - ->getMockForAbstractClass(); - - $this->client = $this->getMockBuilder(Elasticsearch::class) - ->setConstructorArgs([ - 'options' => $this->getClientOptions(), - 'elasticsearchClient' => null - ]) - ->getMock(); - - $this->connectionManager->expects($this->any()) - ->method('getConnection') - ->willReturn($this->client); - - $this->clientConfig->expects($this->any()) - ->method('getIndexPrefix') - ->willReturn('indexName'); - $this->clientConfig->expects($this->any()) - ->method('getEntityType') - ->willReturn('product'); - $this->entityType = 'product'; - $this->storeId = 1; - - $objectManager = new ObjectManagerHelper($this); - $this->model = $objectManager->getObject( - IndexNameResolver::class, - [ - 'connectionManager' => $this->connectionManager, - 'clientConfig' => $this->clientConfig, - 'logger' => $this->logger, - 'options' => [], - ] - ); - } - - /** - * Test getIndexNameForAlias() method - */ - public function testGetIndexNameForAlias() - { - $this->clientConfig->expects($this->any()) - ->method('getIndexPrefix') - ->willReturn('indexName'); - - $this->assertEquals( - 'indexName_product_1', - $this->model->getIndexNameForAlias($this->storeId, $this->entityType) - ); - } - - /** - * Test getIndexName() method with prepared index - */ - public function testGetIndexNameWithPreparedIndex() - { - $preparedIndex = ['1' => 'product']; - - $this->assertEquals( - 'product', - $this->model->getIndexName($this->storeId, $this->entityType, $preparedIndex) - ); - } - - /** - * Test getIndexName() method without prepared index - */ - public function testGetIndexNameWithoutPreparedIndexWithIndexName() - { - $preparedIndex = []; - - $this->assertEquals( - 'indexName_product_1_v1', - $this->model->getIndexName($this->storeId, $this->entityType, $preparedIndex) - ); - } - - /** - * Test getIndexPattern() method - */ - public function testGetIndexPattern() - { - $this->assertEquals( - 'indexName_product_1_v', - $this->model->getIndexPattern($this->storeId, $this->entityType) - ); - } - - /** - * Test getIndexFromAlias() method - */ - public function testUpdateAliasWithOldIndex() - { - $this->client->expects($this->any()) - ->method('getAlias') - ->with('indexName_product_1') - ->willReturn( - [ - 'indexName_product_1_v2' => [ - 'aliases' => [ - 'indexName_product_1' => [], - ], - ], - ] - ); - - $this->client->expects($this->any()) - ->method('existsAlias') - ->with('indexName_product_1') - ->willReturn(true); - - $this->assertEquals( - 'indexName_product_1_v2', - $this->model->getIndexFromAlias($this->storeId, $this->entityType) - ); - } - - public function testConnectException() - { - $this->expectException(LocalizedException::class); - - $connectionManager = $this->getMockBuilder(ConnectionManager::class) - ->disableOriginalConstructor() - ->onlyMethods([ - 'getConnection', - ]) - ->getMock(); - - $connectionManager->expects($this->any()) - ->method('getConnection') - ->willThrowException(new \Exception('Something went wrong')); - - $this->objectManager->getObject( - IndexNameResolver::class, - [ - 'connectionManager' => $connectionManager, - 'clientConfig' => $this->clientConfig, - 'logger' => $this->logger, - 'options' => [] - ] - ); - } - - /** - * Test getIndexName() indexerId 'catalogsearch_fulltext' - */ - public function testGetIndexNameCatalogSearchFullText() - { - $this->assertEquals( - 'product', - $this->model->getIndexMapping('catalogsearch_fulltext') - ); - } - - /** - * Test getIndexName() with any ndex - */ - public function testGetIndexName() - { - $this->assertEquals( - 'else_index_id', - $this->model->getIndexMapping('else_index_id') - ); - } - - /** - * Get elasticsearch client options - * - * @return array - */ - protected function getClientOptions() - { - return [ - 'hostname' => 'localhost', - 'port' => '9200', - 'timeout' => 15, - 'index' => 'magento2', - 'enableAuth' => 1, - 'username' => 'user', - 'password' => 'my-password', - ]; - } -} diff --git a/app/code/Magento/Elasticsearch7/Test/Unit/Model/DataProvider/Base/SuggestionsTest.php b/app/code/Magento/Elasticsearch7/Test/Unit/Model/DataProvider/Base/SuggestionsTest.php deleted file mode 100644 index 315e739f4c5..00000000000 --- a/app/code/Magento/Elasticsearch7/Test/Unit/Model/DataProvider/Base/SuggestionsTest.php +++ /dev/null @@ -1,298 +0,0 @@ -config = $this->getMockBuilder(Config::class) - ->disableOriginalConstructor() - ->onlyMethods(['isElasticsearchEnabled']) - ->getMock(); - - $this->queryResultFactory = $this->getMockBuilder(QueryResultFactory::class) - ->disableOriginalConstructor() - ->onlyMethods(['create']) - ->getMock(); - - $this->connectionManager = $this->getMockBuilder(ConnectionManager::class) - ->disableOriginalConstructor() - ->onlyMethods(['getConnection']) - ->getMock(); - - $this->scopeConfig = $this->getMockBuilder(ScopeConfigInterface::class) - ->disableOriginalConstructor() - ->getMockForAbstractClass(); - - $this->searchIndexNameResolver = $this - ->getMockBuilder(SearchIndexNameResolver::class) - ->disableOriginalConstructor() - ->onlyMethods(['getIndexName']) - ->getMock(); - - $this->storeManager = $this->getMockBuilder(StoreManager::class) - ->disableOriginalConstructor() - ->getMockForAbstractClass(); - - $this->fieldProvider = $this->getMockBuilder(FieldProviderInterface::class) - ->disableOriginalConstructor() - ->getMockForAbstractClass(); - - $this->logger = $this->getMockBuilder(LoggerInterface::class) - ->disableOriginalConstructor() - ->getMockForAbstractClass(); - - $this->client = $this->getMockBuilder(Elasticsearch::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->query = $this->getMockBuilder(QueryInterface::class) - ->disableOriginalConstructor() - ->getMockForAbstractClass(); - - $objectManager = new ObjectManagerHelper($this); - - $this->model = $objectManager->getObject( - Suggestions::class, - [ - 'queryResultFactory' => $this->queryResultFactory, - 'connectionManager' => $this->connectionManager, - 'scopeConfig' => $this->scopeConfig, - 'config' => $this->config, - 'searchIndexNameResolver' => $this->searchIndexNameResolver, - 'storeManager' => $this->storeManager, - 'fieldProvider' => $this->fieldProvider, - 'logger' => $this->logger, - ] - ); - } - - /** - * Test get items process with search suggestions disabled. - * @return void - */ - public function testGetItemsWithDisabledSearchSuggestion(): void - { - $this->scopeConfig->expects($this->once()) - ->method('isSetFlag') - ->willReturn(false); - - $this->scopeConfig->expects($this->never()) - ->method('getValue'); - - $this->config->expects($this->once()) - ->method('isElasticsearchEnabled') - ->willReturn(true); - - $this->logger->expects($this->never()) - ->method('critical'); - - $this->queryResultFactory->expects($this->never()) - ->method('create'); - - $this->assertEmpty($this->model->getItems($this->query)); - } - - /** - * Test get items process with search suggestions enabled. - * @return void - */ - public function testGetItemsWithEnabledSearchSuggestion(): void - { - $this->prepareSearchQuery(); - $this->client->expects($this->once()) - ->method('query') - ->willReturn([ - 'suggest' => [ - 'phrase_field' => [ - [ - 'options' => [ - 'suggestion' => [ - 'text' => 'query', - 'score' => 1, - 'freq' => 1, - ] - ] - ] - ], - ], - ]); - - $this->logger->expects($this->never()) - ->method('critical'); - - $query = $this->getMockBuilder(QueryResult::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->queryResultFactory->expects($this->once()) - ->method('create') - ->willReturn($query); - - $this->assertEquals([$query], $this->model->getItems($this->query)); - } - - /** - * Test get items process when throwing an exception. - * @return void - */ - public function testGetItemsException(): void - { - if (!class_exists(\Elasticsearch\ClientBuilder::class)) { /** @phpstan-ignore-line */ - $this->markTestSkipped('AC-6597: Skipped as Elasticsearch 8 is configured'); - } - - $this->prepareSearchQuery(); - $exception = new BadRequest400Exception(); - - $this->client->expects($this->once()) - ->method('query') - ->willThrowException($exception); - - $this->logger->expects($this->once()) - ->method('critical') - ->with($exception); - - $this->queryResultFactory->expects($this->never()) - ->method('create'); - - $this->assertEmpty($this->model->getItems($this->query)); - } - - /** - * Prepare Mocks for default get items process. - * @return void - */ - private function prepareSearchQuery(): void - { - $storeId = 1; - - $this->scopeConfig->expects($this->exactly(2)) - ->method('isSetFlag') - ->willReturn(true); - - $this->scopeConfig->expects($this->once()) - ->method('getValue') - ->willReturn(1); - - $this->config->expects($this->once()) - ->method('isElasticsearchEnabled') - ->willReturn(true); - - $store = $this->getMockBuilder(StoreInterface::class) - ->disableOriginalConstructor() - ->getMockForAbstractClass(); - - $store->expects($this->once()) - ->method('getId') - ->willReturn($storeId); - - $this->storeManager->expects($this->once()) - ->method('getStore') - ->willReturn($store); - - $this->searchIndexNameResolver->expects($this->once()) - ->method('getIndexName') - ->with($storeId, Config::ELASTICSEARCH_TYPE_DEFAULT) - ->willReturn('magento2_product_1'); - - $this->query->expects($this->once()) - ->method('getQueryText') - ->willReturn('query'); - - $this->fieldProvider->expects($this->once()) - ->method('getFields') - ->willReturn([]); - - $this->connectionManager->expects($this->once()) - ->method('getConnection') - ->willReturn($this->client); - } -} diff --git a/app/code/Magento/Elasticsearch7/Test/Unit/Model/SearchAdapter/Aggregation/IntervalTest.php b/app/code/Magento/Elasticsearch7/Test/Unit/Model/SearchAdapter/Aggregation/IntervalTest.php deleted file mode 100644 index 8c75a24ee5b..00000000000 --- a/app/code/Magento/Elasticsearch7/Test/Unit/Model/SearchAdapter/Aggregation/IntervalTest.php +++ /dev/null @@ -1,325 +0,0 @@ -connectionManager = $this->getMockBuilder(ConnectionManager::class) - ->onlyMethods(['getConnection']) - ->disableOriginalConstructor() - ->getMock(); - $this->fieldMapper = $this->getMockBuilder(FieldMapperInterface::class) - ->disableOriginalConstructor() - ->getMockForAbstractClass(); - $this->clientConfig = $this->getMockBuilder(Config::class) - ->addMethods(['getIndexName']) - ->onlyMethods([ - 'getEntityType', - ]) - ->disableOriginalConstructor() - ->getMock(); - $this->storeManager = $this->getMockBuilder(StoreManagerInterface::class) - ->disableOriginalConstructor() - ->getMockForAbstractClass(); - $this->customerSession = $this->getMockBuilder(CustomerSession::class) - ->onlyMethods(['getCustomerGroupId']) - ->disableOriginalConstructor() - ->getMock(); - $this->customerSession->expects($this->any()) - ->method('getCustomerGroupId') - ->willReturn(1); - $this->storeMock = $this->getMockBuilder(StoreInterface::class) - ->disableOriginalConstructor() - ->getMockForAbstractClass(); - $this->searchIndexNameResolver = $this - ->getMockBuilder(SearchIndexNameResolver::class) - ->disableOriginalConstructor() - ->getMock(); - $this->storeMock->expects($this->any()) - ->method('getWebsiteId') - ->willReturn(1); - $this->storeMock->expects($this->any()) - ->method('getId') - ->willReturn(1); - $this->clientConfig->expects($this->any()) - ->method('getIndexName') - ->willReturn('indexName'); - $this->clientConfig->expects($this->any()) - ->method('getEntityType') - ->willReturn('product'); - $this->clientMock = $this->getMockBuilder(ElasticsearchClient::class) - ->onlyMethods(['query']) - ->disableOriginalConstructor() - ->getMock(); - $this->connectionManager->expects($this->any()) - ->method('getConnection') - ->willReturn($this->clientMock); - - $objectManagerHelper = new ObjectManagerHelper($this); - $this->model = $objectManagerHelper->getObject( - Interval::class, - [ - 'connectionManager' => $this->connectionManager, - 'fieldMapper' => $this->fieldMapper, - 'clientConfig' => $this->clientConfig, - 'searchIndexNameResolver' => $this->searchIndexNameResolver, - 'fieldName' => 'price_0_1', - 'storeId' => 1, - 'entityIds' => [265, 313, 281], - ] - ); - } - - /** - * @dataProvider loadParamsProvider - * @param string $limit - * @param string $offset - * @param string $lower - * @param string $upper - * @param array $queryResult - * @param array $expected - * @return void - */ - public function testLoad( - string $limit, - string $offset, - string $lower, - string $upper, - array $queryResult, - array $expected - ): void { - $this->processQuery($queryResult); - - $this->assertEquals( - $expected, - $this->model->load($limit, $offset, $lower, $upper) - ); - } - - /** - * @dataProvider loadPrevParamsProvider - * @param string $data - * @param string $index - * @param string $lower - * @param array $queryResult - * @param array|bool $expected - * @return void - */ - public function testLoadPrev(string $data, string $index, string $lower, array $queryResult, $expected): void - { - $this->processQuery($queryResult); - - $this->assertEquals( - $expected, - $this->model->loadPrevious($data, $index, $lower) - ); - } - - /** - * @dataProvider loadNextParamsProvider - * @param string $data - * @param string $rightIndex - * @param string $upper - * @param array $queryResult - * @param array|bool $expected - * @return void - */ - public function testLoadNext(string $data, string $rightIndex, string $upper, array $queryResult, $expected): void - { - $this->processQuery($queryResult); - - $this->assertEquals( - $expected, - $this->model->loadNext($data, $rightIndex, $upper) - ); - } - - /** - * @param array $queryResult - * @return void - */ - private function processQuery(array $queryResult): void - { - $this->searchIndexNameResolver->expects($this->any()) - ->method('getIndexName') - ->willReturn('magento2_product_1'); - $this->clientConfig->expects($this->any()) - ->method('getEntityType') - ->willReturn('document'); - $this->clientMock->expects($this->any()) - ->method('query') - ->willReturn($queryResult); - } - - /** - * @return array - */ - public static function loadParamsProvider(): array - { - return [ - [ - 'limit' => '6', - 'offset' => '2', - 'lower' => '24', - 'upper' => '42', - 'queryResult' => [ - 'hits' => [ - 'hits' => [ - [ - 'fields' => [ - 'price_0_1' => [25], - ], - ], - ], - ], - ], - 'expected' => [25], - ], - ]; - } - - /** - * @return array - */ - public static function loadPrevParamsProvider(): array - { - return [ - [ - 'data' => '24', - 'index' => '1', - 'lower' => '24', - 'queryResult' => [ - 'hits' => [ - 'total'=> '1', - 'hits' => [ - [ - 'fields' => [ - 'price_0_1' => ['25'], - ], - ], - ], - ], - ], - 'expected' => ['25.0'], - ], - [ - 'data' => '24', - 'index' => '1', - 'lower' => '24', - 'queryResult' => [ - 'hits' => ['total'=> '0'], - ], - 'expected' => false, - ], - ]; - } - - /** - * @return array - */ - public static function loadNextParamsProvider(): array - { - return [ - [ - 'data' => '24', - 'rightIndex' => '2', - 'upper' => '42', - 'queryResult' => [ - 'hits' => [ - 'total'=> '1', - 'hits' => [ - [ - 'fields' => [ - 'price_0_1' => ['25'], - ], - ], - ], - ], - ], - 'expected' => ['25.0'], - ], - [ - 'data' => '24', - 'rightIndex' => '2', - 'upper' => '42', - 'queryResult' => [ - 'hits' => ['total'=> '0'], - ], - 'expected' => false, - ], - ]; - } -} diff --git a/app/code/Magento/Elasticsearch7/Test/Unit/SearchAdapter/AdapterTest.php b/app/code/Magento/Elasticsearch7/Test/Unit/SearchAdapter/AdapterTest.php deleted file mode 100644 index 1f9b143f3f1..00000000000 --- a/app/code/Magento/Elasticsearch7/Test/Unit/SearchAdapter/AdapterTest.php +++ /dev/null @@ -1,354 +0,0 @@ -connectionManagerMock = $this->createMock(ConnectionManager::class); - $this->mapperMock = $this->createMock(Mapper::class); - $this->responseFactoryMock = $this->createMock(ResponseFactory::class); - $this->aggregationBuilderMock = $this->createMock(AggregationBuilder::class); - $this->queryContainerFactoryMock = $this->createMock(QueryContainerFactory::class); - $this->loggerMock = $this->createMock(LoggerInterface::class); - $this->pageSizeProviderMock = $this->createMock(PageSizeProvider::class); - $this->adapter = new Adapter( - $this->connectionManagerMock, - $this->mapperMock, - $this->responseFactoryMock, - $this->aggregationBuilderMock, - $this->queryContainerFactoryMock, - $this->loggerMock, - $this->pageSizeProviderMock - ); - - $this->connectionMock = $this->createMock(ElasticsearchClient::class); - $this->connectionManagerMock->method('getConnection') - ->willReturn($this->connectionMock); - $this->pageSizeProviderMock->method('getMaxPageSize') - ->willReturn(10000); - } - - /** - * @dataProvider queryDataProvider - * @param int $from - * @param int $size - * @return void - */ - public function testQuery(int $from, int $size): void - { - $requestMock = $this->createMock(RequestInterface::class); - $requestMock->method('getFrom') - ->willReturn($from); - $requestMock->method('getSize') - ->willReturn($size); - - $query = [ - 'index' => 'magento_product', - 'body' => [ - 'from' => $from, - 'size' => $size, - 'query' => [], - ], - ]; - $this->mapperMock->expects($this->once()) - ->method('buildQuery') - ->with($requestMock) - ->willReturn($query); - - $response = [ - 'hits' => [ - 'total' => [ - 'value' => 2, - ], - 'hits' => [ - [ - 'fields' => ['_id' => ['111']], - ], - [ - 'fields' => ['_id' => ['222']], - ], - ], - ], - ]; - $this->connectionMock->expects($this->once()) - ->method('query') - ->with($query) - ->willReturn($response); - $this->connectionMock->expects($this->never()) - ->method('openPointInTime'); - $this->connectionMock->expects($this->never()) - ->method('closePointInTime'); - - $queryResponseMock = $this->mockQueryResponse($requestMock, $query, $response); - $queryResponse = $this->adapter->query($requestMock); - $this->assertEquals($queryResponseMock, $queryResponse); - } - - public function queryDataProvider(): array - { - return [ - [0, 2], - [0, 10000], - [9998, 2], - ]; - } - - /** - * @dataProvider queryExceedingPageSizeLimitDataProvider - * @param int $from - * @param int $size - * @return void - */ - public function testQueryExceedingPageSizeLimit(int $from, int $size): void - { - $requestMock = $this->createMock(RequestInterface::class); - $requestMock->method('getFrom')->willReturn($from); - $requestMock->method('getSize')->willReturn($size); - - $query = [ - 'index' => 'magento_product', - 'body' => [ - 'from' => $from, - 'size' => $size, - 'sort' => [ - [ '_score' => ['order' => 'asc']], - ], - 'query' => [], - ], - ]; - $this->mapperMock->expects($this->once())->method('buildQuery')->with($requestMock)->willReturn($query); - - $pit = ['id' => 'abc']; - $this->connectionMock->expects($this->once()) - ->method('openPointInTime') - ->with( - [ - 'index' => 'magento_product', - 'keep_alive' => '1m', - ] - ) - ->willReturn($pit); - $firstQuery = [ - 'body' => [ - 'from' => 0, - 'size' => $from, - 'sort' => [ - [ '_score' => ['order' => 'asc']], - ], - 'query' => [], - 'pit' => $pit, - ], - ]; - $finalQuery = [ - 'body' => [ - 'from' => 0, - 'size' => $size, - 'sort' => [ - [ '_score' => ['order' => 'asc']], - ], - 'query' => [], - 'pit' => $pit, - 'search_after' => [2.0], - ], - ]; - $firstResponse = [ - 'hits' => [ - 'total' => [ - 'value' => 2, - ], - 'hits' => [ - [ - 'fields' => ['_id' => ['111']], - 'sort' => [1.0], - ], - [ - 'fields' => ['_id' => ['222']], - 'sort' => [2.0], - ], - ], - ], - ]; - $finalResponse = [ - 'hits' => [ - 'total' => [ - 'value' => 2, - ], - 'hits' => [ - [ - 'fields' => ['_id' => ['333']], - 'sort' => [3.0], - ], - [ - 'fields' => ['_id' => ['444']], - 'sort' => [4.0], - ], - ], - ], - ]; - $this->connectionMock->expects($this->exactly(2)) - ->method('query') - ->willReturnCallback(fn ($query) => match ($query) { - $firstQuery => $firstResponse, - $finalQuery => $finalResponse, - }); - $this->connectionMock->expects($this->once())->method('closePointInTime')->with(['body' => $pit]); - - $queryResponseMock = $this->mockQueryResponse($requestMock, $finalQuery, $finalResponse); - $queryResponse = $this->adapter->query($requestMock); - $this->assertEquals($queryResponseMock, $queryResponse); - } - - public function queryExceedingPageSizeLimitDataProvider(): array - { - return [ - [10000, 2], - [9999, 2], - ]; - } - - /** - * @return void - */ - public function testQueryWithException(): void - { - $requestMock = $this->createMock(RequestInterface::class); - $requestMock->method('getFrom') - ->willReturn(0); - $requestMock->method('getSize') - ->willReturn(2); - - $query = [ - 'index' => 'magento_product', - 'body' => [ - 'from' => 0, - 'size' => 2, - 'query' => [], - ], - ]; - $this->mapperMock->expects($this->once()) - ->method('buildQuery') - ->with($requestMock) - ->willReturn($query); - - $exception = new \Exception('error'); - $this->connectionMock->expects($this->once()) - ->method('query') - ->with($query) - ->willThrowException($exception); - $this->loggerMock->expects($this->once()) - ->method('critical') - ->with($exception); - - $response = [ - 'hits' => ['hits' => []], - 'aggregations' => [ - 'price_bucket' => [], - 'category_bucket' => ['buckets' => []], - ], - ]; - $queryResponseMock = $this->mockQueryResponse($requestMock, $query, $response); - $queryResponse = $this->adapter->query($requestMock); - $this->assertEquals($queryResponseMock, $queryResponse); - } - - private function mockQueryResponse(MockObject $requestMock, array $query, array $rawResponse): MockObject - { - $queryContainerMock = $this->createMock(QueryContainer::class); - $this->queryContainerFactoryMock->expects($this->once()) - ->method('create') - ->with(['query' => $query]) - ->willReturn($queryContainerMock); - $this->aggregationBuilderMock->expects($this->once()) - ->method('setQuery') - ->with($queryContainerMock) - ->willReturnSelf(); - $aggregations = []; - $this->aggregationBuilderMock->expects($this->once()) - ->method('build') - ->with($requestMock, $rawResponse) - ->willReturn($aggregations); - $queryResponseMock = $this->createMock(QueryResponse::class); - $this->responseFactoryMock->expects($this->once()) - ->method('create') - ->with( - [ - 'documents' => $rawResponse['hits']['hits'], - 'aggregations' => $aggregations, - 'total' => count($rawResponse['hits']['hits']), - ] - ) - ->willReturn($queryResponseMock); - - return $queryResponseMock; - } -} diff --git a/app/code/Magento/Elasticsearch7/Test/Unit/Setup/InstallConfigTest.php b/app/code/Magento/Elasticsearch7/Test/Unit/Setup/InstallConfigTest.php deleted file mode 100644 index 1766416cfb2..00000000000 --- a/app/code/Magento/Elasticsearch7/Test/Unit/Setup/InstallConfigTest.php +++ /dev/null @@ -1,87 +0,0 @@ -configWriterMock = $this->getMockBuilder(WriterInterface::class)->getMockForAbstractClass(); - - $objectManager = new ObjectManager($this); - $this->installConfig = $objectManager->getObject( - InstallConfig::class, - [ - 'configWriter' => $this->configWriterMock, - 'searchConfigMapping' => [ - 'elasticsearch-host' => 'elasticsearch7_server_hostname', - 'elasticsearch-port' => 'elasticsearch7_server_port', - 'elasticsearch-timeout' => 'elasticsearch7_server_timeout', - 'elasticsearch-index-prefix' => 'elasticsearch7_index_prefix', - 'elasticsearch-enable-auth' => 'elasticsearch7_enable_auth', - 'elasticsearch-username' => 'elasticsearch7_username', - 'elasticsearch-password' => 'elasticsearch7_password' - ] - ] - ); - } - - /** - * @return void - */ - public function testConfigure(): void - { - $inputOptions = [ - 'search-engine' => 'elasticsearch7', - 'elasticsearch-host' => 'localhost', - 'elasticsearch-port' => '9200' - ]; - - $this->configWriterMock - ->method('save') - ->willReturnCallback(function ($arg1, $arg2) { - if ($arg1 == 'catalog/search/engine' && $arg2 == 'elasticsearch7') { - return null; - } elseif ($arg1 == 'catalog/search/elasticsearch7_server_hostname' && $arg2 == 'localhost') { - return null; - } elseif ($arg1 == 'catalog/search/elasticsearch7_server_port' && $arg2 == '9200') { - return null; - } - }); - - $this->installConfig->configure($inputOptions); - } - - /** - * @return void - */ - public function testConfigureWithEmptyInput(): void - { - $this->configWriterMock->expects($this->never())->method('save'); - $this->installConfig->configure([]); - } -} diff --git a/app/code/Magento/Elasticsearch7/Test/Unit/Setup/ValidatorTest.php b/app/code/Magento/Elasticsearch7/Test/Unit/Setup/ValidatorTest.php deleted file mode 100644 index cbd83d958f6..00000000000 --- a/app/code/Magento/Elasticsearch7/Test/Unit/Setup/ValidatorTest.php +++ /dev/null @@ -1,93 +0,0 @@ -clientResolverMock = $this->getMockBuilder(ClientResolver::class) - ->disableOriginalConstructor() - ->getMock(); - $this->elasticsearchClientMock = $this->getMockBuilder(Elasticsearch::class) - ->disableOriginalConstructor() - ->getMock(); - - $objectManager = new ObjectManager($this); - $this->validator = $objectManager->getObject( - Validator::class, - [ - 'clientResolver' => $this->clientResolverMock - ] - ); - } - - public function testValidate() - { - $this->clientResolverMock - ->expects($this->once()) - ->method('create') - ->willReturn($this->elasticsearchClientMock); - $this->elasticsearchClientMock->expects($this->once())->method('testConnection')->willReturn(true); - - $this->assertEquals([], $this->validator->validate()); - } - - public function testValidateFail() - { - $this->clientResolverMock - ->expects($this->once()) - ->method('create') - ->willReturn($this->elasticsearchClientMock); - $this->elasticsearchClientMock->expects($this->once())->method('testConnection')->willReturn(false); - - $expected = [ - 'Could not validate a connection to Elasticsearch.' - . ' Verify that the Elasticsearch host and port are configured correctly.' - ]; - $this->assertEquals($expected, $this->validator->validate()); - } - - public function testValidateFailException() - { - $this->clientResolverMock - ->expects($this->once()) - ->method('create') - ->willReturn($this->elasticsearchClientMock); - $exceptionMessage = 'Could not ping host.'; - $this->elasticsearchClientMock - ->expects($this->once()) - ->method('testConnection') - ->willThrowException(new \Exception($exceptionMessage)); - - $expected = ['Could not validate a connection to Elasticsearch. ' . $exceptionMessage]; - $this->assertEquals($expected, $this->validator->validate()); - } -} diff --git a/app/code/Magento/Elasticsearch7/etc/config.xml b/app/code/Magento/Elasticsearch7/etc/config.xml deleted file mode 100644 index 6f48d6490da..00000000000 --- a/app/code/Magento/Elasticsearch7/etc/config.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - elasticsearch7 - localhost - 9200 - magento2 - 0 - 15 - - - - - diff --git a/app/code/Magento/Elasticsearch8/Block/Adminhtml/System/Config/TestConnection.php b/app/code/Magento/Elasticsearch8/Block/Adminhtml/System/Config/TestConnection.php new file mode 100644 index 00000000000..311963e7929 --- /dev/null +++ b/app/code/Magento/Elasticsearch8/Block/Adminhtml/System/Config/TestConnection.php @@ -0,0 +1,35 @@ + 'catalog_search_engine', + 'hostname' => 'catalog_search_elasticsearch8_server_hostname', + 'port' => 'catalog_search_elasticsearch8_server_port', + 'index' => 'catalog_search_elasticsearch8_index_prefix', + 'enableAuth' => 'catalog_search_elasticsearch8_enable_auth', + 'username' => 'catalog_search_elasticsearch8_username', + 'password' => 'catalog_search_elasticsearch8_password', + 'timeout' => 'catalog_search_elasticsearch8_server_timeout', + ]; + + return array_merge(parent::_getFieldMapping(), $fields); + } +} diff --git a/app/code/Magento/Elasticsearch7/LICENSE.txt b/app/code/Magento/Elasticsearch8/LICENSE.txt similarity index 100% rename from app/code/Magento/Elasticsearch7/LICENSE.txt rename to app/code/Magento/Elasticsearch8/LICENSE.txt diff --git a/app/code/Magento/Elasticsearch7/LICENSE_AFL.txt b/app/code/Magento/Elasticsearch8/LICENSE_AFL.txt similarity index 100% rename from app/code/Magento/Elasticsearch7/LICENSE_AFL.txt rename to app/code/Magento/Elasticsearch8/LICENSE_AFL.txt diff --git a/app/code/Magento/Elasticsearch7/Model/Adapter/DynamicTemplates/IntegerMapper.php b/app/code/Magento/Elasticsearch8/Model/Adapter/DynamicTemplates/IntegerMapper.php similarity index 56% rename from app/code/Magento/Elasticsearch7/Model/Adapter/DynamicTemplates/IntegerMapper.php rename to app/code/Magento/Elasticsearch8/Model/Adapter/DynamicTemplates/IntegerMapper.php index 852ebc705c1..f156cd94475 100644 --- a/app/code/Magento/Elasticsearch7/Model/Adapter/DynamicTemplates/IntegerMapper.php +++ b/app/code/Magento/Elasticsearch8/Model/Adapter/DynamicTemplates/IntegerMapper.php @@ -1,25 +1,21 @@ $indexName, + 'body' => [], + 'refresh' => true, + ]; + + foreach ($documents as $id => $document) { + $bulkArray['body'][] = [ + $action => [ + '_id' => $id, + '_index' => $indexName + ] + ]; + + if ($action == self::BULK_ACTION_INDEX) { + $bulkArray['body'][] = $document; + } + } + + return $bulkArray; + } +} diff --git a/app/code/Magento/Elasticsearch7/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolver.php b/app/code/Magento/Elasticsearch8/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolver.php similarity index 80% rename from app/code/Magento/Elasticsearch7/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolver.php rename to app/code/Magento/Elasticsearch8/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolver.php index d51354a4fb7..3dd99346f7c 100644 --- a/app/code/Magento/Elasticsearch7/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolver.php +++ b/app/code/Magento/Elasticsearch8/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolver.php @@ -5,22 +5,22 @@ */ declare(strict_types=1); -namespace Magento\Elasticsearch7\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; +namespace Magento\Elasticsearch8\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface; /** - * Default name resolver for Elasticsearch 7 - * @deprecated 100.3.0 because of EOL for Elasticsearch7 - * @see this class will be responsible for ES7 only + * Default name resolver for Elasticsearch 8 + * @deprecated Elasticsearch8 is no longer supported by Adobe + * @see this class will be responsible for ES8 only */ class DefaultResolver implements ResolverInterface { /** * @var ResolverInterface */ - private $baseResolver; + private ResolverInterface $baseResolver; /** * DefaultResolver constructor. diff --git a/app/code/Magento/Elasticsearch7/Model/Client/Elasticsearch.php b/app/code/Magento/Elasticsearch8/Model/Client/Elasticsearch.php similarity index 57% rename from app/code/Magento/Elasticsearch7/Model/Client/Elasticsearch.php rename to app/code/Magento/Elasticsearch8/Model/Client/Elasticsearch.php index 387255d6cd5..159f6ca5412 100644 --- a/app/code/Magento/Elasticsearch7/Model/Client/Elasticsearch.php +++ b/app/code/Magento/Elasticsearch8/Model/Client/Elasticsearch.php @@ -1,46 +1,48 @@ client[getmypid()] = $elasticsearchClient; } $this->clientOptions = $options; @@ -81,48 +83,40 @@ public function __construct( } /** - * Execute suggest query for Elasticsearch 7 + * Get Elasticsearch 8 Client * - * @param array $query - * @return array - */ - public function suggest(array $query): array - { - return $this->getElasticsearchClient()->suggest($query); - } - - /** - * Get Elasticsearch 7 Client - * - * @return \Elasticsearch\Client + * @return Client|null */ - private function getElasticsearchClient(): \Elasticsearch\Client + private function getElasticsearchClient(): ?Client /** @phpstan-ignore-line */ { $pid = getmypid(); if (!isset($this->client[$pid])) { $config = $this->buildESConfig($this->clientOptions); - $this->client[$pid] = \Elasticsearch\ClientBuilder::fromConfig($config, true); + $this->client[$pid] = ClientBuilder::fromConfig($config, true); /** @phpstan-ignore-line */ } + return $this->client[$pid]; } /** - * Ping the Elasticsearch 7 client + * Ping the Elasticsearch 8 client * * @return bool */ public function ping(): bool { - if ($this->pingResult === null) { - $this->pingResult = $this->getElasticsearchClient() - ->ping(['client' => ['timeout' => $this->clientOptions['timeout']]]); + $elasticsearchClient = $this->getElasticsearchClient(); + if ($this->pingResult === false && $elasticsearchClient) { + $this->pingResult = $elasticsearchClient->ping( + ['client' => ['timeout' => $this->clientOptions['timeout']]] + )->asBool(); } return $this->pingResult; } /** - * Validate connection params for Elasticsearch 7 + * Validate connection params for Elasticsearch 8 * * @return bool */ @@ -132,7 +126,69 @@ public function testConnection(): bool } /** - * Build config for Elasticsearch 7 + * Add/update an Elasticsearch index settings. + * + * @param string $index + * @param array $settings + * @return void + */ + public function putIndexSettings(string $index, array $settings): void + { + $elasticsearchClient = $this->getElasticsearchClient(); + if ($elasticsearchClient) { + $elasticsearchClient->indices() + ->putSettings(['index' => $index, 'body' => $settings]); + } + } + + /** + * Updates alias. + * + * @param string $alias + * @param string $newIndex + * @param string $oldIndex + * @return void + */ + public function updateAlias(string $alias, string $newIndex, string $oldIndex = '') + { + $elasticsearchClient = $this->getElasticsearchClient(); + if ($elasticsearchClient === null) { + return; + } + + $params = ['body' => ['actions' => []]]; + if ($newIndex) { + $params['body']['actions'][] = ['add' => ['alias' => $alias, 'index' => $newIndex]]; + } + + if ($oldIndex) { + $params['body']['actions'][] = ['remove' => ['alias' => $alias, 'index' => $oldIndex]]; + } + + $elasticsearchClient->indices()->updateAliases($params); + } + + /** + * Checks whether Elasticsearch 8 index exists + * + * @param string $index + * @return bool + */ + public function indexExists(string $index): bool + { + $indexExists = false; + $elasticsearchClient = $this->getElasticsearchClient(); + if ($elasticsearchClient) { + $indexExists = $elasticsearchClient->indices() + ->exists(['index' => $index]) + ->asBool(); + } + + return $indexExists; + } + + /** + * Build config for Elasticsearch 8 * * @param array $options * @return array @@ -165,179 +221,153 @@ private function buildESConfig(array $options = []): array } /** - * Performs bulk query over Elasticsearch 7 index - * - * @param array $query - * @return array - */ - public function bulkQuery(array $query) - { - return $this->getElasticsearchClient()->bulk($query); - } - - /** - * Creates an Elasticsearch 7 index. + * Exists alias. * + * @param string $alias * @param string $index - * @param array $settings - * @return void + * @return bool */ - public function createIndex(string $index, array $settings) + public function existsAlias(string $alias, string $index = ''): bool { - $this->getElasticsearchClient()->indices()->create( - [ - 'index' => $index, - 'body' => $settings, - ] - ); + $existAlias = false; + $elasticsearchClient = $this->getElasticsearchClient(); + if ($elasticsearchClient) { + $params = ['name' => $alias]; + if ($index) { + $params['index'] = $index; + } + + $existAlias = $elasticsearchClient->indices()->existsAlias($params)->asBool(); + } + + return $existAlias; } /** - * Add/update an Elasticsearch index settings. + * Performs bulk query over Elasticsearch 8 index * - * @param string $index - * @param array $settings - * @return void + * @param array $query + * @return \Elastic\Elasticsearch\Response\Elasticsearch|\Http\Promise\Promise */ - public function putIndexSettings(string $index, array $settings): void + public function bulkQuery(array $query) { - $this->getElasticsearchClient()->indices()->putSettings( - [ - 'index' => $index, - 'body' => $settings, - ] - ); + return $this->getElasticsearchClient()->bulk($query); } /** - * Delete an Elasticsearch 7 index. + * Creates an Elasticsearch 8 index. * * @param string $index + * @param array $settings * @return void */ - public function deleteIndex(string $index) + public function createIndex(string $index, array $settings): void { - $this->getElasticsearchClient()->indices()->delete(['index' => $index]); + $elasticsearchClient = $this->getElasticsearchClient(); + if ($elasticsearchClient) { + $elasticsearchClient->indices() + ->create([ + 'index' => $index, + 'body' => $settings, + ]); + } } /** - * Check if index is empty. + * Get alias. * - * @param string $index - * @return bool + * @param string $alias + * @return array */ - public function isEmptyIndex(string $index): bool + public function getAlias(string $alias): array { - $stats = $this->getElasticsearchClient()->indices()->stats(['index' => $index, 'metric' => 'docs']); - if ($stats['indices'][$index]['primaries']['docs']['count'] === 0) { - return true; + $elasticsearchClient = $this->getElasticsearchClient(); + if ($elasticsearchClient === null) { + return []; } - return false; + return $elasticsearchClient->indices() + ->getAlias(['name' => $alias]) + ->asArray(); } /** - * Updates alias. + * Add mapping to Elasticsearch 8 index * - * @param string $alias - * @param string $newIndex - * @param string $oldIndex + * @param array $fields + * @param string $index + * @param string $entityType * @return void + * @SuppressWarnings("unused") */ - public function updateAlias(string $alias, string $newIndex, string $oldIndex = '') + public function addFieldsMapping(array $fields, string $index, string $entityType) { + $elasticsearchClient = $this->getElasticsearchClient(); + if ($elasticsearchClient === null) { + return; + } + $params = [ + 'index' => $index, 'body' => [ - 'actions' => [], + 'properties' => [], + 'dynamic_templates' => $this->dynamicTemplatesProvider->getTemplates(), ], ]; - if ($oldIndex) { - $params['body']['actions'][] = ['remove' => ['alias' => $alias, 'index' => $oldIndex]]; - } - if ($newIndex) { - $params['body']['actions'][] = ['add' => ['alias' => $alias, 'index' => $newIndex]]; + + foreach ($this->applyFieldsMappingPreprocessors($fields) as $field => $fieldInfo) { + $params['body']['properties'][$field] = $fieldInfo; } - $this->getElasticsearchClient()->indices()->updateAliases($params); + $elasticsearchClient->indices()->putMapping($params); } /** - * Checks whether Elasticsearch 7 index exists + * Delete an Elasticsearch 8 index. * * @param string $index - * @return bool + * @return void */ - public function indexExists(string $index): bool + public function deleteIndex(string $index) { - return $this->getElasticsearchClient()->indices()->exists(['index' => $index]); + $elasticsearchClient = $this->getElasticsearchClient(); + if ($elasticsearchClient) { + $elasticsearchClient->indices() + ->delete(['index' => $index]); + } } /** - * Exists alias. + * Check if index is empty. * - * @param string $alias * @param string $index * @return bool */ - public function existsAlias(string $alias, string $index = ''): bool + public function isEmptyIndex(string $index): bool { - $params = ['name' => $alias]; - if ($index) { - $params['index'] = $index; + $elasticsearchClient = $this->getElasticsearchClient(); + if ($elasticsearchClient === null) { + return false; } - return $this->getElasticsearchClient()->indices()->existsAlias($params); - } - - /** - * Get alias. - * - * @param string $alias - * @return array - */ - public function getAlias(string $alias): array - { - return $this->getElasticsearchClient()->indices()->getAlias(['name' => $alias]); - } - - /** - * Add mapping to Elasticsearch 7 index - * - * @param array $fields - * @param string $index - * @param string $entityType - * @return void - */ - public function addFieldsMapping(array $fields, string $index, string $entityType) - { - $params = [ - 'index' => $index, - 'type' => $entityType, - 'include_type_name' => true, - 'body' => [ - $entityType => [ - 'properties' => [], - 'dynamic_templates' => $this->dynamicTemplatesProvider->getTemplates(), - ], - ], - ]; - - foreach ($this->applyFieldsMappingPreprocessors($fields) as $field => $fieldInfo) { - $params['body'][$entityType]['properties'][$field] = $fieldInfo; + $stats = $this->getElasticsearchClient()->indices()->stats(['index' => $index, 'metric' => 'docs']); + if ($stats['indices'][$index]['primaries']['docs']['count'] === 0) { + return true; } - $this->getElasticsearchClient()->indices()->putMapping($params); + return false; } /** * Execute search by $query * * @param array $query - * @return array */ public function query(array $query): array { - return $this->getElasticsearchClient()->search($query); + $elasticsearchClient = $this->getElasticsearchClient(); + + return $elasticsearchClient === null ? [] : $elasticsearchClient->search($query)->asArray(); } /** @@ -348,24 +378,9 @@ public function query(array $query): array */ public function getMapping(array $params): array { - return $this->getElasticsearchClient()->indices()->getMapping($params); - } + $elasticsearchClient = $this->getElasticsearchClient(); - /** - * Delete mapping in Elasticsearch 7 index - * - * @param string $index - * @param string $entityType - * @return void - */ - public function deleteMapping(string $index, string $entityType) - { - $this->getElasticsearchClient()->indices()->deleteMapping( - [ - 'index' => $index, - 'type' => $entityType, - ] - ); + return $elasticsearchClient === null ? [] : $elasticsearchClient->indices()->getMapping($params)->asArray(); } /** @@ -379,28 +394,7 @@ private function applyFieldsMappingPreprocessors(array $properties): array foreach ($this->fieldsMappingPreprocessors as $preprocessor) { $properties = $preprocessor->process($properties); } - return $properties; - } - - /** - * Open point in time - * - * @param array $params - * @return array - */ - public function openPointInTime(array $params = []): array - { - return $this->getElasticsearchClient()->openPointInTime($params); - } - /** - * Close point in time - * - * @param array $params - * @return array - */ - public function closePointInTime(array $params = []): array - { - return $this->getElasticsearchClient()->closePointInTime($params); + return $properties; } } diff --git a/app/code/Magento/Elasticsearch8/README.md b/app/code/Magento/Elasticsearch8/README.md new file mode 100644 index 00000000000..d60dc9ebbaf --- /dev/null +++ b/app/code/Magento/Elasticsearch8/README.md @@ -0,0 +1,26 @@ +# Magento_Elasticsearch8 module + +Magento_Elasticsearch8 module allows using ElasticSearch engine 8.x version for the product searching capabilities. + +The module implements Magento_Search library interfaces. + +## Structure + +`SearchAdapter/` - the directory that contains solutions for adapting ElasticSearch query searching. + +For information about a typical file structure of a module in Magento 2, see [Module file structure](https://devdocs.magento.com/guides/v2.4/extension-dev-guide/build/module-file-structure.html#module-file-structure). + +## Additional information + +By default`indices.id_field_data` is disallowed in Elasticsearch8 hence it needs to enabled it from `elasticsearch.yml` +by adding the following configuration +`indices: +id_field_data: +enabled: true` + +More information about ElasticSearch are at articles: + +- [Configuring Catalog Search](https://experienceleague.adobe.com/docs/commerce-admin/catalog/catalog/search/search-configuration.html). +- [Installation Guide/Elasticsearch](https://experienceleague.adobe.com/docs/commerce-operations/installation-guide/prerequisites/search-engine/overview.html). +- [Configure and maintain Elasticsearch](https://experienceleague.adobe.com/docs/commerce-operations/configuration-guide/search/overview-search.html). +- Magento Commerce Cloud - [set up Elasticsearch service](https://devdocs.magento.com/cloud/project/services-elastic.html). diff --git a/app/code/Magento/Elasticsearch7/SearchAdapter/Adapter.php b/app/code/Magento/Elasticsearch8/SearchAdapter/Adapter.php similarity index 52% rename from app/code/Magento/Elasticsearch7/SearchAdapter/Adapter.php rename to app/code/Magento/Elasticsearch8/SearchAdapter/Adapter.php index 08fd835b287..013db89fed7 100644 --- a/app/code/Magento/Elasticsearch7/SearchAdapter/Adapter.php +++ b/app/code/Magento/Elasticsearch8/SearchAdapter/Adapter.php @@ -5,14 +5,12 @@ */ declare(strict_types=1); -namespace Magento\Elasticsearch7\SearchAdapter; +namespace Magento\Elasticsearch8\SearchAdapter; -use Magento\Elasticsearch7\Model\Client\Elasticsearch as ElasticsearchClient; use Magento\Elasticsearch\SearchAdapter\Aggregation\Builder as AggregationBuilder; use Magento\Elasticsearch\SearchAdapter\ConnectionManager; use Magento\Elasticsearch\SearchAdapter\QueryContainerFactory; use Magento\Elasticsearch\SearchAdapter\ResponseFactory; -use Magento\Search\Model\Search\PageSizeProvider; use Magento\Framework\Search\AdapterInterface; use Magento\Framework\Search\RequestInterface; use Magento\Framework\Search\Response\QueryResponse; @@ -20,63 +18,57 @@ /** * Elasticsearch Search Adapter - * @deprecated 100.3.0 because of EOL for Elasticsearch7 - * @see this class will be responsible for ES7 only + * @deprecated Elasticsearch8 is no longer supported by Adobe + * @see this class will be responsible for ES8 only */ class Adapter implements AdapterInterface { /** + * Mapper instance + * * @var Mapper */ - private $mapper; + private Mapper $mapper; /** * @var ResponseFactory */ - private $responseFactory; + private ResponseFactory $responseFactory; /** * @var ConnectionManager */ - private $connectionManager; + private ConnectionManager $connectionManager; /** * @var AggregationBuilder */ - private $aggregationBuilder; + private AggregationBuilder $aggregationBuilder; /** * @var QueryContainerFactory */ - private $queryContainerFactory; + private QueryContainerFactory $queryContainerFactory; /** * Empty response from Elasticsearch * * @var array */ - private static $emptyRawResponse = [ + private static array $emptyRawResponse = [ "hits" => [ - "hits" => [] - ], + "hits" => [] + ], "aggregations" => [ - "price_bucket" => [], - "category_bucket" => [ - "buckets" => [] - - ] - ] + "price_bucket" => [], + "category_bucket" => ["buckets" => []], + ] ]; /** * @var LoggerInterface */ - private $logger; - - /** - * @var PageSizeProvider - */ - private $pageSizeProvider; + private LoggerInterface $logger; /** * @param ConnectionManager $connectionManager @@ -85,7 +77,6 @@ class Adapter implements AdapterInterface * @param AggregationBuilder $aggregationBuilder * @param QueryContainerFactory $queryContainerFactory * @param LoggerInterface $logger - * @param PageSizeProvider $pageSizeProvider */ public function __construct( ConnectionManager $connectionManager, @@ -93,8 +84,7 @@ public function __construct( ResponseFactory $responseFactory, AggregationBuilder $aggregationBuilder, QueryContainerFactory $queryContainerFactory, - LoggerInterface $logger, - PageSizeProvider $pageSizeProvider + LoggerInterface $logger ) { $this->connectionManager = $connectionManager; $this->mapper = $mapper; @@ -102,7 +92,6 @@ public function __construct( $this->aggregationBuilder = $aggregationBuilder; $this->queryContainerFactory = $queryContainerFactory; $this->logger = $logger; - $this->pageSizeProvider = $pageSizeProvider; } /** @@ -113,56 +102,26 @@ public function __construct( */ public function query(RequestInterface $request) : QueryResponse { - /** @var ElasticsearchClient $client */ $client = $this->connectionManager->getConnection(); - $query = $this->mapper->buildQuery($request); - try { - $maxPageSize = $this->pageSizeProvider->getMaxPageSize(); - if ($request->getFrom() + $request->getSize() > $maxPageSize) { - $pit = $client->openPointInTime( - [ - 'index' => $query['index'], - 'keep_alive' => '1m', - ] - ); - $query['body']['pit'] = $pit; - unset($query['index']); - - $query['body']['from'] = 0; - $processed = 0; - while ($processed < $request->getFrom()) { - $query['body']['size'] = min($request->getFrom() - $processed, $maxPageSize); - $processed += $query['body']['size']; - $rawResponse = $client->query($query); - $lastHit = end($rawResponse['hits']['hits']); - $query['body']['search_after'] = $lastHit['sort']; - } - $query['body']['size'] = $request->getSize(); - } + $aggregationBuilder = $this->aggregationBuilder; + $aggregationBuilder->setQuery($this->queryContainerFactory->create(['query' => $query])); + try { $rawResponse = $client->query($query); } catch (\Exception $e) { $this->logger->critical($e); // return empty search result in case an exception is thrown from Elasticsearch $rawResponse = self::$emptyRawResponse; - } finally { - if (isset($pit)) { - $client->closePointInTime(['body' => $pit]); - } } $rawDocuments = $rawResponse['hits']['hits'] ?? []; - $this->aggregationBuilder->setQuery($this->queryContainerFactory->create(['query' => $query])); - $aggregations = $this->aggregationBuilder->build($request, $rawResponse); - $queryResponse = $this->responseFactory->create( + return $this->responseFactory->create( [ 'documents' => $rawDocuments, - 'aggregations' => $aggregations, + 'aggregations' => $aggregationBuilder->build($request, $rawResponse), 'total' => $rawResponse['hits']['total']['value'] ?? 0 ] ); - - return $queryResponse; } } diff --git a/app/code/Magento/Elasticsearch7/SearchAdapter/Mapper.php b/app/code/Magento/Elasticsearch8/SearchAdapter/Mapper.php similarity index 58% rename from app/code/Magento/Elasticsearch7/SearchAdapter/Mapper.php rename to app/code/Magento/Elasticsearch8/SearchAdapter/Mapper.php index 67552e6b76b..a9fdf389a2b 100644 --- a/app/code/Magento/Elasticsearch7/SearchAdapter/Mapper.php +++ b/app/code/Magento/Elasticsearch8/SearchAdapter/Mapper.php @@ -6,27 +6,28 @@ declare(strict_types=1); -namespace Magento\Elasticsearch7\SearchAdapter; +namespace Magento\Elasticsearch8\SearchAdapter; use Magento\Framework\Search\RequestInterface; +use Magento\Elasticsearch\Elasticsearch5\SearchAdapter\Mapper as ElasticsearchMapper; /** - * Elasticsearch7 mapper class - * @deprecated 100.3.0 because of EOL for Elasticsearch7 - * @see this class will be responsible for ES7 only + * Elasticsearch8 mapper class + * @deprecated Elasticsearch8 is no longer supported by Adobe + * @see this class will be responsible for ES8 only */ class Mapper { /** - * @var \Magento\Elasticsearch\ElasticAdapter\SearchAdapter\Mapper + * @var ElasticsearchMapper */ - private $mapper; + private ElasticsearchMapper $mapper; /** * Mapper constructor. - * @param \Magento\Elasticsearch\ElasticAdapter\SearchAdapter\Mapper $mapper + * @param ElasticsearchMapper $mapper */ - public function __construct(\Magento\Elasticsearch\ElasticAdapter\SearchAdapter\Mapper $mapper) + public function __construct(ElasticsearchMapper $mapper) { $this->mapper = $mapper; } diff --git a/app/code/Magento/Elasticsearch7/Test/Mftf/Test/StorefrontQuickSearchUsingElasticSearchByProductSkuTest.xml b/app/code/Magento/Elasticsearch8/Test/Mftf/Test/StorefrontQuickSearchUsingElasticSearch8ByProductSkuTest.xml similarity index 75% rename from app/code/Magento/Elasticsearch7/Test/Mftf/Test/StorefrontQuickSearchUsingElasticSearchByProductSkuTest.xml rename to app/code/Magento/Elasticsearch8/Test/Mftf/Test/StorefrontQuickSearchUsingElasticSearch8ByProductSkuTest.xml index f2f8e37063d..cf733bd22f8 100644 --- a/app/code/Magento/Elasticsearch7/Test/Mftf/Test/StorefrontQuickSearchUsingElasticSearchByProductSkuTest.xml +++ b/app/code/Magento/Elasticsearch8/Test/Mftf/Test/StorefrontQuickSearchUsingElasticSearch8ByProductSkuTest.xml @@ -8,44 +8,41 @@ - + - + - - <description value="Check that AND query is performed when searching using ElasticSearch 7"/> + <title value="Check that AND query is performed when searching using ElasticSearch 8"/> + <description value="Check that AND query is performed when searching using ElasticSearch 8"/> <severity value="CRITICAL"/> - <testCaseId value="MC-31114"/> - <useCaseId value="MC-29788"/> + <testCaseId value="AC-6597"/> + <useCaseId value="AC-6665"/> <group value="SearchEngine"/> <group value="pr_exclude"/> </annotations> <before> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="setSearchEngine"/> <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> <actionGroup ref="DeleteAllProductsUsingProductGridActionGroup" stepKey="deleteAllProducts"/> - - <createData entity="VirtualProduct" stepKey="createFirtsSimpleProduct"/> + <createData entity="VirtualProduct" stepKey="createVirtualProduct"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="createFirtsSimpleProduct"/> <createData entity="SimpleProductWithCustomSku24MB06" stepKey="createSecondSimpleProduct"/> <createData entity="SimpleProductWithCustomSku24MB04" stepKey="createThirdSimpleProduct"/> <createData entity="SimpleProductWithCustomSku24MB02" stepKey="createFourthSimpleProduct"/> <createData entity="SimpleProductWithCustomSku24MB01" stepKey="createFifthSimpleProduct"/> - <actionGroup ref="CliCacheCleanActionGroup" stepKey="cleanCache"> - <argument name="tags" value=""/> - </actionGroup> - <actionGroup ref="CliIndexerReindexActionGroup" stepKey="reindex"> - <argument name="indices" value=""/> + <argument name="tags" value="config full_page"/> </actionGroup> + <magentoCron groups="index" stepKey="reindex"/> </before> <after> - <deleteData createDataKey="createFirtsSimpleProduct" stepKey="deleteProductOne"/> - + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="deleteProductOne"/> <actionGroup ref="DeleteAllProductsUsingProductGridActionGroup" stepKey="deleteAllProductsAfterTest"/> <actionGroup ref="AdminLogoutActionGroup" stepKey="logoutFromAdminPanel"/> </after> <actionGroup ref="StorefrontOpenHomePageActionGroup" stepKey="openStoreFrontHomePage"/> <actionGroup ref="StorefrontCheckQuickSearchStringActionGroup" stepKey="quickSearchByProductSku"> - <argument name="phrase" value="24 MB0"/> + <argument name="phrase" value="24 MB04"/> </actionGroup> <see userInput="4" selector="{{StorefrontCatalogSearchMainSection.productCount}}" stepKey="assertSearchResultCount"/> diff --git a/app/code/Magento/Elasticsearch7/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolverTest.php b/app/code/Magento/Elasticsearch8/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolverTest.php similarity index 95% rename from app/code/Magento/Elasticsearch7/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolverTest.php rename to app/code/Magento/Elasticsearch8/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolverTest.php index 1625d634c6f..30c93cd7125 100644 --- a/app/code/Magento/Elasticsearch7/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolverTest.php +++ b/app/code/Magento/Elasticsearch8/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolverTest.php @@ -5,7 +5,7 @@ */ declare(strict_types=1); -namespace Magento\Elasticsearch7\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; +namespace Magento\Elasticsearch8\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\DefaultResolver @@ -14,7 +14,7 @@ as FieldTypeConverterInterface; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ResolverInterface as FieldTypeResolver; -use Magento\Elasticsearch7\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\DefaultResolver; +use Magento\Elasticsearch8\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\DefaultResolver; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; use PHPUnit\Framework\TestCase; @@ -46,14 +46,14 @@ class DefaultResolverTest extends TestCase protected function setUp(): void { $objectManager = new ObjectManagerHelper($this); - $this->fieldTypeResolver = $this->getMockBuilder(FieldTypeResolver::class) - ->disableOriginalConstructor() - ->onlyMethods(['getFieldType']) - ->getMockForAbstractClass(); $this->fieldTypeConverter = $this->getMockBuilder(FieldTypeConverterInterface::class) ->disableOriginalConstructor() ->onlyMethods(['convert']) ->getMockForAbstractClass(); + $this->fieldTypeResolver = $this->getMockBuilder(FieldTypeResolver::class) + ->disableOriginalConstructor() + ->onlyMethods(['getFieldType']) + ->getMockForAbstractClass(); $baseResolver = $objectManager->getObject( BaseDefaultResolver::class, @@ -84,19 +84,19 @@ public function testGetFieldName( $context, $expected ) { - $this->fieldTypeConverter->expects($this->any()) - ->method('convert') - ->willReturn('string'); $attributeMock = $this->getMockBuilder(AttributeAdapter::class) ->disableOriginalConstructor() ->onlyMethods(['getAttributeCode', 'getFrontendInput', 'isSortable']) ->getMock(); - $attributeMock->expects($this->any()) - ->method('getAttributeCode') - ->willReturn($attributeCode); + $this->fieldTypeConverter->expects($this->any()) + ->method('convert') + ->willReturn('string'); $attributeMock->expects($this->any()) ->method('getFrontendInput') ->willReturn($frontendInput); + $attributeMock->expects($this->any()) + ->method('getAttributeCode') + ->willReturn($attributeCode); $attributeMock->expects($this->any()) ->method('isSortable') ->willReturn($isSortable); @@ -113,7 +113,7 @@ public function testGetFieldName( /** * @return array */ - public static function getFieldNameProvider() + public static function getFieldNameProvider(): array { return [ ['', 'code', '', false, [], 'code'], @@ -121,8 +121,8 @@ public static function getFieldNameProvider() ['string', '*', '', false, ['type' => 'default'], '_search'], ['', 'code', '', false, ['type' => 'default'], 'code'], ['', 'code', 'select', false, ['type' => 'default'], 'code'], - ['', 'code', 'boolean', false, ['type' => 'default'], 'code'], ['', 'code', '', true, ['type' => 'sort'], 'sort_code'], + ['', 'code', 'boolean', false, ['type' => 'default'], 'code'], ]; } } diff --git a/app/code/Magento/Elasticsearch7/Test/Unit/Model/Client/ElasticsearchTest.php b/app/code/Magento/Elasticsearch8/Test/Unit/Model/Client/ElasticsearchTest.php similarity index 60% rename from app/code/Magento/Elasticsearch7/Test/Unit/Model/Client/ElasticsearchTest.php rename to app/code/Magento/Elasticsearch8/Test/Unit/Model/Client/ElasticsearchTest.php index f361da11537..95df0b57524 100644 --- a/app/code/Magento/Elasticsearch7/Test/Unit/Model/Client/ElasticsearchTest.php +++ b/app/code/Magento/Elasticsearch8/Test/Unit/Model/Client/ElasticsearchTest.php @@ -1,28 +1,31 @@ <?php /** - * Copyright 2015 Adobe - * All Rights Reserved. + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. */ + declare(strict_types=1); -namespace Magento\Elasticsearch7\Test\Unit\Model\Client; +namespace Magento\Elasticsearch8\Test\Unit\Model\Client; -use Elasticsearch\Client; -use Elasticsearch\Namespaces\IndicesNamespace; +use DG\BypassFinals; +use Elastic\Elasticsearch\Client; +use Elastic\Elasticsearch\Endpoints\Indices; +use Elastic\Elasticsearch\Response\Elasticsearch as ElasticsearchResponse; use Magento\Elasticsearch\Model\Adapter\FieldMapper\AddDefaultSearchField; -use Magento\Elasticsearch7\Model\Adapter\DynamicTemplates\IntegerMapper; -use Magento\Elasticsearch7\Model\Adapter\DynamicTemplates\PositionMapper; -use Magento\Elasticsearch7\Model\Adapter\DynamicTemplates\PriceMapper; -use Magento\Elasticsearch7\Model\Adapter\DynamicTemplates\StringMapper; -use Magento\Elasticsearch7\Model\Adapter\DynamicTemplatesProvider; -use Magento\Elasticsearch7\Model\Client\Elasticsearch; +use Magento\Elasticsearch8\Model\Adapter\DynamicTemplates\IntegerMapper; +use Magento\Elasticsearch8\Model\Adapter\DynamicTemplates\PositionMapper; +use Magento\Elasticsearch8\Model\Adapter\DynamicTemplates\PriceMapper; +use Magento\Elasticsearch8\Model\Adapter\DynamicTemplates\StringMapper; +use Magento\Elasticsearch8\Model\Adapter\DynamicTemplatesProvider; +use Magento\Elasticsearch8\Model\Client\Elasticsearch; use Magento\Framework\Exception\LocalizedException; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; /** - * Class ElasticsearchTest to test Elasticsearch 7 + * Class ElasticsearchTest to test Elasticsearch 8 * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ @@ -39,7 +42,7 @@ class ElasticsearchTest extends TestCase private $elasticsearchClientMock; /** - * @var IndicesNamespace|MockObject + * @var Indices|MockObject */ private $indicesMock; @@ -48,6 +51,9 @@ class ElasticsearchTest extends TestCase */ private $objectManager; + /** @var ElasticsearchResponse|MockObject */ + private $elasticsearchResponse; + /** * Setup * @@ -55,8 +61,8 @@ class ElasticsearchTest extends TestCase */ protected function setUp(): void { - $this->elasticsearchClientMock = $this->getMockBuilder(Client::class) - ->addMethods(['suggest']) + BypassFinals::enable(); + $this->elasticsearchClientMock = $this->getMockBuilder(Client::class) /** @phpstan-ignore-line */ ->onlyMethods( [ 'indices', @@ -65,14 +71,11 @@ protected function setUp(): void 'search', 'scroll', 'info', - 'openPointInTime', - 'closePointInTime', ] ) ->disableOriginalConstructor() ->getMock(); - $this->indicesMock = $this->getMockBuilder(IndicesNamespace::class) - ->addMethods(['deleteMapping']) + $this->indicesMock = $this->getMockBuilder(Indices::class) /** @phpstan-ignore-line */ ->onlyMethods( [ 'exists', @@ -87,17 +90,21 @@ protected function setUp(): void 'getAlias', ] ) + ->addMethods(['deleteMapping']) ->disableOriginalConstructor() ->getMock(); + $this->elasticsearchResponse = $this->getMockBuilder(ElasticsearchResponse::class) /** @phpstan-ignore-line */ + ->onlyMethods([ + 'asBool', + 'asArray', + ]) + ->getMock(); $this->elasticsearchClientMock->expects($this->any()) ->method('indices') ->willReturn($this->indicesMock); $this->elasticsearchClientMock->expects($this->any()) ->method('ping') - ->willReturn(true); - $this->elasticsearchClientMock->expects($this->any()) - ->method('info') - ->willReturn(['version' => ['number' => '7.0.0']]); + ->willReturn($this->elasticsearchResponse); $this->objectManager = new ObjectManagerHelper($this); $dynamicTemplatesProvider = new DynamicTemplatesProvider( @@ -119,6 +126,11 @@ protected function setUp(): void ); } + /** + * Test configurations with exception + * + * @return void + */ public function testConstructorOptionsException() { $this->expectException('Magento\Framework\Exception\LocalizedException'); @@ -154,17 +166,10 @@ public function testConstructorWithOptions() * @throws \ReflectionException * @dataProvider getOptionsDataProvider */ - public function testBuildConfig(array $options, $expectedResult): void + public function testBuildConfig(array $options, string $expectedResult): void { - $objects = [ - [ - DynamicTemplatesProvider::class, - $this->createMock(DynamicTemplatesProvider::class) - ] - ]; - $this->objectManager->prepareObjectManager($objects); $buildConfig = new Elasticsearch($options); - $config = $this->getPrivateMethod(Elasticsearch::class, 'buildESConfig'); + $config = $this->getPrivateMethod(); $result = $config->invoke($buildConfig, $options); $this->assertEquals($expectedResult, $result['hosts'][0]); } @@ -172,15 +177,12 @@ public function testBuildConfig(array $options, $expectedResult): void /** * Return private method for elastic search class. * - * @param $className - * @param $methodName * @return \ReflectionMethod - * @throws \ReflectionException */ - private function getPrivateMethod($className, $methodName) + private function getPrivateMethod(): \ReflectionMethod { - $reflector = new \ReflectionClass($className); - $method = $reflector->getMethod($methodName); + $reflector = new \ReflectionClass(Elasticsearch::class); + $method = $reflector->getMethod('buildESConfig'); $method->setAccessible(true); return $method; @@ -189,28 +191,28 @@ private function getPrivateMethod($className, $methodName) /** * Get options data provider. */ - public static function getOptionsDataProvider() + public function getOptionsDataProvider(): array { return [ [ - 'options' => [ + 'without_protocol' => [ 'hostname' => 'localhost', 'port' => '9200', 'timeout' => 15, 'index' => 'magento2', 'enableAuth' => 0, ], - 'expectedResult' => 'http://localhost:9200', + 'expected_result' => 'http://localhost:9200', ], [ - 'options' => [ + 'with_protocol' => [ 'hostname' => 'https://localhost', 'port' => '9200', 'timeout' => 15, 'index' => 'magento2', 'enableAuth' => 0, ], - 'expectedResult' => 'https://localhost:9200', + 'expected_result' => 'https://localhost:9200', ], ]; } @@ -220,16 +222,38 @@ public static function getOptionsDataProvider() */ public function testPing() { - $this->elasticsearchClientMock->expects($this->once())->method('ping')->willReturn(true); + $this->elasticsearchResponse->expects($this->once()) + ->method('asBool') + ->willReturn(true); $this->assertTrue($this->model->ping()); } + /** + * Get elasticsearch client options + * + * @return array + */ + protected function getOptions(): array + { + return [ + 'hostname' => 'localhost', + 'port' => '9200', + 'timeout' => 15, + 'index' => 'magento2', + 'enableAuth' => 1, + 'username' => 'user', + 'password' => 'passwd', + ]; + } + /** * Test validation of connection parameters */ public function testTestConnection() { - $this->elasticsearchClientMock->expects($this->once())->method('ping')->willReturn(true); + $this->elasticsearchResponse->expects($this->once()) + ->method('asBool') + ->willReturn(true); $this->assertTrue($this->model->testConnection()); } @@ -238,8 +262,10 @@ public function testTestConnection() */ public function testTestConnectionFalse() { - $this->elasticsearchClientMock->expects($this->once())->method('ping')->willReturn(false); - $this->assertTrue($this->model->testConnection()); + $this->elasticsearchResponse->expects($this->once()) + ->method('asBool') + ->willReturn(false); + $this->assertFalse($this->model->testConnection()); } /** @@ -247,6 +273,9 @@ public function testTestConnectionFalse() */ public function testTestConnectionPing() { + $this->elasticsearchResponse->expects($this->once()) + ->method('asBool') + ->willReturn(true); $this->model = $this->objectManager->getObject( Elasticsearch::class, [ @@ -259,20 +288,31 @@ public function testTestConnectionPing() $this->assertTrue($this->model->testConnection()); } + /** + * @return array + */ + private function getEmptyIndexOption(): array + { + return [ + 'hostname' => 'localhost', + 'port' => '9200', + 'index' => '', + 'timeout' => 15, + 'enableAuth' => 1, + 'username' => 'user', + 'password' => 'passwd', + ]; + } + /** * Test bulkQuery() method */ public function testBulkQuery() { - $result = [ - 'errors' => false, - 'items' => [], - ]; $this->elasticsearchClientMock->expects($this->once()) ->method('bulk') - ->with([]) - ->willReturn($result); - $this->assertEquals($result, $this->model->bulkQuery([])); + ->with([]); + $this->model->bulkQuery([]); } /** @@ -307,7 +347,7 @@ public function testDeleteIndex() */ public function testIsEmptyIndex() { - $indexName = 'magento2_index'; + $indexName = 'magento2_test_index'; $stats['indices'][$indexName]['primaries']['docs']['count'] = 0; $this->indicesMock->expects($this->once()) @@ -322,7 +362,7 @@ public function testIsEmptyIndex() */ public function testIsEmptyIndexFalse() { - $indexName = 'magento2_index'; + $indexName = 'magento2_test_index'; $stats['indices'][$indexName]['primaries']['docs']['count'] = 1; $this->indicesMock->expects($this->once()) @@ -357,8 +397,8 @@ public function testUpdateAliasRemoveOldIndex() $newIndex = 'index1'; $oldIndex = 'indexOld'; - $params['body']['actions'][] = ['remove' => ['alias' => $alias, 'index' => $oldIndex]]; $params['body']['actions'][] = ['add' => ['alias' => $alias, 'index' => $newIndex]]; + $params['body']['actions'][] = ['remove' => ['alias' => $alias, 'index' => $oldIndex]]; $this->indicesMock->expects($this->once()) ->method('updateAliases') @@ -371,10 +411,13 @@ public function testUpdateAliasRemoveOldIndex() */ public function testIndexExists() { + $this->elasticsearchResponse->expects($this->once()) + ->method('asBool') + ->willReturn(true); $this->indicesMock->expects($this->once()) ->method('exists') ->with(['index' => 'indexName']) - ->willReturn(true); + ->willReturn($this->elasticsearchResponse); $this->model->indexExists('indexName'); } @@ -383,12 +426,15 @@ public function testIndexExists() */ public function testExistsAlias() { + $this->elasticsearchResponse->expects($this->once()) + ->method('asBool') + ->willReturn(true); $alias = 'alias1'; $params = ['name' => $alias]; $this->indicesMock->expects($this->once()) ->method('existsAlias') ->with($params) - ->willReturn(true); + ->willReturn($this->elasticsearchResponse); $this->assertTrue($this->model->existsAlias($alias)); } @@ -397,13 +443,16 @@ public function testExistsAlias() */ public function testExistsAliasWithIndex() { + $this->elasticsearchResponse->expects($this->once()) + ->method('asBool') + ->willReturn(true); $alias = 'alias1'; $index = 'index1'; $params = ['name' => $alias, 'index' => $index]; $this->indicesMock->expects($this->once()) ->method('existsAlias') ->with($params) - ->willReturn(true); + ->willReturn($this->elasticsearchResponse); $this->assertTrue($this->model->existsAlias($alias, $index)); } @@ -412,12 +461,15 @@ public function testExistsAliasWithIndex() */ public function testGetAlias() { + $this->elasticsearchResponse->expects($this->once()) + ->method('asArray') + ->willReturn([]); $alias = 'alias1'; $params = ['name' => $alias]; $this->indicesMock->expects($this->once()) ->method('getAlias') ->with($params) - ->willReturn([]); + ->willReturn($this->elasticsearchResponse); $this->assertEquals([], $this->model->getAlias($alias)); } @@ -449,56 +501,52 @@ public function testAddFieldsMapping() ->with( [ 'index' => 'indexName', - 'type' => 'product', - 'include_type_name' => true, 'body' => [ - 'product' => [ - 'properties' => [ - '_search' => [ - 'type' => 'text', - ], - 'name' => [ - 'type' => 'text', - ], + 'properties' => [ + '_search' => [ + 'type' => 'text', ], - 'dynamic_templates' => [ - [ - 'price_mapping' => [ - 'match' => 'price_*', - 'match_mapping_type' => 'string', - 'mapping' => [ - 'type' => 'double', - 'store' => true, - ], + 'name' => [ + 'type' => 'text', + ], + ], + 'dynamic_templates' => [ + [ + 'price_mapping' => [ + 'match' => 'price_*', + 'match_mapping_type' => 'string', + 'mapping' => [ + 'type' => 'double', + 'store' => true, ], ], - [ - 'position_mapping' => [ - 'match' => 'position_*', - 'match_mapping_type' => 'string', - 'mapping' => [ - 'type' => 'integer', - 'index' => true, - ], + ], + [ + 'position_mapping' => [ + 'match' => 'position_*', + 'match_mapping_type' => 'string', + 'mapping' => [ + 'type' => 'integer', + 'index' => true, ], ], - [ - 'string_mapping' => [ - 'match' => '*', - 'match_mapping_type' => 'string', - 'mapping' => [ - 'type' => 'text', - 'index' => true, - 'copy_to' => '_search', - ], + ], + [ + 'string_mapping' => [ + 'match' => '*', + 'match_mapping_type' => 'string', + 'mapping' => [ + 'type' => 'text', + 'index' => true, + 'copy_to' => '_search', ], ], - [ - 'integer_mapping' => [ - 'match_mapping_type' => 'long', - 'mapping' => [ - 'type' => 'integer', - ], + ], + [ + 'integer_mapping' => [ + 'match_mapping_type' => 'long', + 'mapping' => [ + 'type' => 'integer', ], ], ], @@ -528,56 +576,52 @@ public function testAddFieldsMappingFailure() ->with( [ 'index' => 'indexName', - 'type' => 'product', - 'include_type_name' => true, 'body' => [ - 'product' => [ - 'properties' => [ - '_search' => [ - 'type' => 'text', - ], - 'name' => [ - 'type' => 'text', - ], + 'properties' => [ + '_search' => [ + 'type' => 'text', ], - 'dynamic_templates' => [ - [ - 'price_mapping' => [ - 'match' => 'price_*', - 'match_mapping_type' => 'string', - 'mapping' => [ - 'type' => 'double', - 'store' => true, - ], + 'name' => [ + 'type' => 'text', + ], + ], + 'dynamic_templates' => [ + [ + 'price_mapping' => [ + 'match' => 'price_*', + 'match_mapping_type' => 'string', + 'mapping' => [ + 'type' => 'double', + 'store' => true, ], ], - [ - 'position_mapping' => [ - 'match' => 'position_*', - 'match_mapping_type' => 'string', - 'mapping' => [ - 'type' => 'integer', - 'index' => true, - ], + ], + [ + 'position_mapping' => [ + 'match' => 'position_*', + 'match_mapping_type' => 'string', + 'mapping' => [ + 'type' => 'integer', + 'index' => true, ], ], - [ - 'string_mapping' => [ - 'match' => '*', - 'match_mapping_type' => 'string', - 'mapping' => [ - 'type' => 'text', - 'index' => true, - 'copy_to' => '_search', - ], + ], + [ + 'string_mapping' => [ + 'match' => '*', + 'match_mapping_type' => 'string', + 'mapping' => [ + 'type' => 'text', + 'index' => true, + 'copy_to' => '_search', ], ], - [ - 'integer_mapping' => [ - 'match_mapping_type' => 'long', - 'mapping' => [ - 'type' => 'integer', - ], + ], + [ + 'integer_mapping' => [ + 'match_mapping_type' => 'long', + 'mapping' => [ + 'type' => 'integer', ], ], ], @@ -597,46 +641,6 @@ public function testAddFieldsMappingFailure() ); } - /** - * Test deleteMapping() method - */ - public function testDeleteMapping() - { - $this->indicesMock->expects($this->once()) - ->method('deleteMapping') - ->with( - [ - 'index' => 'indexName', - 'type' => 'product', - ] - ); - $this->model->deleteMapping( - 'indexName', - 'product' - ); - } - - /** - * Test deleteMapping() method - */ - public function testDeleteMappingFailure() - { - $this->expectException('Exception'); - $this->indicesMock->expects($this->once()) - ->method('deleteMapping') - ->with( - [ - 'index' => 'indexName', - 'type' => 'product', - ] - ) - ->willThrowException(new \Exception('Something went wrong')); - $this->model->deleteMapping( - 'indexName', - 'product' - ); - } - /** * Test get Elasticsearch mapping process. * @@ -644,11 +648,14 @@ public function testDeleteMappingFailure() */ public function testGetMapping(): void { + $this->elasticsearchResponse->expects($this->once()) + ->method('asArray') + ->willReturn([]); $params = ['index' => 'indexName']; $this->indicesMock->expects($this->once()) ->method('getMapping') ->with($params) - ->willReturn([]); + ->willReturn($this->elasticsearchResponse); $this->model->getMapping($params); } @@ -660,80 +667,14 @@ public function testGetMapping(): void */ public function testQuery() { + $this->elasticsearchResponse->expects($this->once()) + ->method('asArray') + ->willReturn([]); $query = ['test phrase query']; $this->elasticsearchClientMock->expects($this->once()) ->method('search') ->with($query) - ->willReturn([]); + ->willReturn($this->elasticsearchResponse); $this->assertEquals([], $this->model->query($query)); } - - /** - * Test suggest() method - * - * @return void - */ - public function testSuggest() - { - $query = ['query']; - $this->elasticsearchClientMock->expects($this->once()) - ->method('suggest') - ->willReturn([]); - $this->assertEquals([], $this->model->suggest($query)); - } - - /** - * Get elasticsearch client options - * - * @return array - */ - protected function getOptions() - { - return [ - 'hostname' => 'localhost', - 'port' => '9200', - 'timeout' => 15, - 'index' => 'magento2', - 'enableAuth' => 1, - 'username' => 'user', - 'password' => 'passwd', - ]; - } - - /** - * @return array - */ - private function getEmptyIndexOption() - { - return [ - 'hostname' => 'localhost', - 'port' => '9200', - 'index' => '', - 'timeout' => 15, - 'enableAuth' => 1, - 'username' => 'user', - 'password' => 'passwd', - ]; - } - - public function testOpenPointInTime(): void - { - $params = ['keep_alive' => '1m']; - $pit = ['id' => 'abc']; - $this->elasticsearchClientMock->expects($this->once()) - ->method('openPointInTime') - ->with($params) - ->willReturn($pit); - $this->assertEquals($pit, $this->model->openPointInTime($params)); - } - - public function testClosePointInTime(): void - { - $params = ['body' => ['id' => 'abc']]; - $this->elasticsearchClientMock->expects($this->once()) - ->method('closePointInTime') - ->with($params) - ->willReturn([]); - $this->model->closePointInTime($params); - } } diff --git a/app/code/Magento/Elasticsearch7/composer.json b/app/code/Magento/Elasticsearch8/composer.json similarity index 68% rename from app/code/Magento/Elasticsearch7/composer.json rename to app/code/Magento/Elasticsearch8/composer.json index e823afc586e..4d0a45f98ec 100644 --- a/app/code/Magento/Elasticsearch7/composer.json +++ b/app/code/Magento/Elasticsearch8/composer.json @@ -1,18 +1,21 @@ { - "name": "magento/module-elasticsearch-7", + "name": "magento/module-elasticsearch-8", "description": "N/A", "require": { "php": "~8.2.0||~8.3.0||~8.4.0", "magento/framework": "*", "magento/module-elasticsearch": "*", - "magento/elasticsearch": "^1.0.0", "magento/module-advanced-search": "*", "magento/module-catalog-search": "*", - "magento/module-search": "*" + "magento/module-search": "*", + "elasticsearch/elasticsearch": "^8.15" }, "suggest": { "magento/module-config": "*" }, + "replace": { + "magento/module-elasticsearch-7": "*" + }, "type": "magento2-module", "license": [ "OSL-3.0", @@ -23,7 +26,7 @@ "registration.php" ], "psr-4": { - "Magento\\Elasticsearch7\\": "" + "Magento\\Elasticsearch8\\": "" } } } diff --git a/app/code/Magento/Elasticsearch7/etc/adminhtml/system.xml b/app/code/Magento/Elasticsearch8/etc/adminhtml/system.xml similarity index 65% rename from app/code/Magento/Elasticsearch7/etc/adminhtml/system.xml rename to app/code/Magento/Elasticsearch8/etc/adminhtml/system.xml index a8f4ecccdea..cc51355cd10 100644 --- a/app/code/Magento/Elasticsearch7/etc/adminhtml/system.xml +++ b/app/code/Magento/Elasticsearch8/etc/adminhtml/system.xml @@ -10,81 +10,81 @@ <system> <section id="catalog"> <group id="search"> - <!-- Elasticsearch 7 --> - <field id="elasticsearch7_server_hostname" translate="label" type="text" sortOrder="61" + <!-- Elasticsearch 8 --> + <field id="elasticsearch8_server_hostname" translate="label" type="text" sortOrder="61" showInDefault="1" showInWebsite="0" showInStore="0"> <label>Elasticsearch Server Hostname</label> <depends> - <field id="engine">elasticsearch7</field> + <field id="engine">elasticsearch8</field> </depends> </field> - <field id="elasticsearch7_server_port" translate="label" type="text" sortOrder="62" showInDefault="1" + <field id="elasticsearch8_server_port" translate="label" type="text" sortOrder="62" showInDefault="1" showInWebsite="0" showInStore="0"> <label>Elasticsearch Server Port</label> <depends> - <field id="engine">elasticsearch7</field> + <field id="engine">elasticsearch8</field> </depends> </field> - <field id="elasticsearch7_index_prefix" translate="label" type="text" sortOrder="63" showInDefault="1" + <field id="elasticsearch8_index_prefix" translate="label" type="text" sortOrder="63" showInDefault="1" showInWebsite="0" showInStore="0"> <label>Elasticsearch Index Prefix</label> <depends> - <field id="engine">elasticsearch7</field> + <field id="engine">elasticsearch8</field> </depends> </field> - <field id="elasticsearch7_enable_auth" translate="label" type="select" sortOrder="64" showInDefault="1" + <field id="elasticsearch8_enable_auth" translate="label" type="select" sortOrder="64" showInDefault="1" showInWebsite="0" showInStore="0"> <label>Enable Elasticsearch HTTP Auth</label> <source_model>Magento\Config\Model\Config\Source\Yesno</source_model> <depends> - <field id="engine">elasticsearch7</field> + <field id="engine">elasticsearch8</field> </depends> </field> - <field id="elasticsearch7_username" translate="label" type="text" sortOrder="65" showInDefault="1" + <field id="elasticsearch8_username" translate="label" type="text" sortOrder="65" showInDefault="1" showInWebsite="0" showInStore="0"> <label>Elasticsearch HTTP Username</label> <depends> - <field id="engine">elasticsearch7</field> - <field id="elasticsearch7_enable_auth">1</field> + <field id="engine">elasticsearch8</field> + <field id="elasticsearch8_enable_auth">1</field> </depends> </field> - <field id="elasticsearch7_password" translate="label" type="text" sortOrder="66" showInDefault="1" + <field id="elasticsearch8_password" translate="label" type="text" sortOrder="66" showInDefault="1" showInWebsite="0" showInStore="0"> <label>Elasticsearch HTTP Password</label> <depends> - <field id="engine">elasticsearch7</field> - <field id="elasticsearch7_enable_auth">1</field> + <field id="engine">elasticsearch8</field> + <field id="elasticsearch8_enable_auth">1</field> </depends> </field> - <field id="elasticsearch7_server_timeout" translate="label" type="text" sortOrder="67" showInDefault="1" + <field id="elasticsearch8_server_timeout" translate="label" type="text" sortOrder="67" showInDefault="1" showInWebsite="0" showInStore="0"> <label>Elasticsearch Server Timeout</label> <depends> - <field id="engine">elasticsearch7</field> + <field id="engine">elasticsearch8</field> </depends> </field> - <field id="elasticsearch7_test_connect_wizard" translate="button_label" sortOrder="68" showInDefault="1" + <field id="elasticsearch8_test_connect_wizard" translate="button_label" sortOrder="68" showInDefault="1" showInWebsite="0" showInStore="0"> <label/> <button_label>Test Connection</button_label> - <frontend_model>Magento\Elasticsearch7\Block\Adminhtml\System\Config\TestConnection</frontend_model> + <frontend_model>Magento\Elasticsearch8\Block\Adminhtml\System\Config\TestConnection</frontend_model> <depends> - <field id="engine">elasticsearch7</field> + <field id="engine">elasticsearch8</field> </depends> </field> - <field id="elasticsearch7_minimum_should_match" translate="label" type="text" sortOrder="93" showInDefault="1"> + <field id="elasticsearch8_minimum_should_match" translate="label" type="text" sortOrder="93" showInDefault="1"> <label>Minimum Terms to Match</label> <depends> - <field id="engine">elasticsearch7</field> + <field id="engine">elasticsearch8</field> </depends> - <comment><![CDATA[<a href="https://experienceleague.adobe.com/docs/commerce-admin/catalog/catalog/search/search-configuration.html">Learn more</a> about valid syntax.]]></comment> + <comment><![CDATA[<a href="https://docs.magento.com/user-guide/catalog/search-elasticsearch.html">Learn more</a> about valid syntax.]]></comment> <backend_model>Magento\Elasticsearch\Model\Config\Backend\MinimumShouldMatch</backend_model> </field> </group> diff --git a/app/code/Magento/Elasticsearch8/etc/config.xml b/app/code/Magento/Elasticsearch8/etc/config.xml new file mode 100644 index 00000000000..727af7d024f --- /dev/null +++ b/app/code/Magento/Elasticsearch8/etc/config.xml @@ -0,0 +1,22 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd"> + <default> + <catalog> + <search> + <engine>elasticsearch8</engine> + <elasticsearch8_server_hostname>localhost</elasticsearch8_server_hostname> + <elasticsearch8_server_port>9200</elasticsearch8_server_port> + <elasticsearch8_index_prefix>magento2</elasticsearch8_index_prefix> + <elasticsearch8_enable_auth>0</elasticsearch8_enable_auth> + <elasticsearch8_server_timeout>15</elasticsearch8_server_timeout> + <elasticsearch8_minimum_should_match/> + </search> + </catalog> + </default> +</config> diff --git a/app/code/Magento/Elasticsearch7/etc/di.xml b/app/code/Magento/Elasticsearch8/etc/di.xml similarity index 68% rename from app/code/Magento/Elasticsearch7/etc/di.xml rename to app/code/Magento/Elasticsearch8/etc/di.xml index d762aebf13d..694b7c658a9 100644 --- a/app/code/Magento/Elasticsearch7/etc/di.xml +++ b/app/code/Magento/Elasticsearch8/etc/di.xml @@ -6,10 +6,27 @@ */ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> + <preference for="Magento\Elasticsearch\Model\Adapter\Elasticsearch" type="Magento\Elasticsearch8\Model\Adapter\Elasticsearch"/> <type name="Magento\Elasticsearch\Model\Config"> <arguments> <argument name="engineList" xsi:type="array"> - <item name="elasticsearch7" xsi:type="string">elasticsearch7</item> + <item name="elasticsearch8" xsi:type="string">elasticsearch8</item> + </argument> + </arguments> + </type> + + <type name="Magento\Elasticsearch\Model\Adapter\Elasticsearch"> + <arguments> + <argument name="responseErrorExceptionList" xsi:type="array"> + <item name="clientResponseException" xsi:type="string">Elastic\Elasticsearch\Exception\ClientResponseException</item> + </argument> + </arguments> + </type> + + <type name="Magento\Elasticsearch\Model\DataProvider\Base\Suggestions"> + <arguments> + <argument name="responseErrorExceptionList" xsi:type="array"> + <item name="clientResponseException" xsi:type="string">Elastic\Elasticsearch\Exception\ClientResponseException</item> </argument> </arguments> </type> @@ -17,7 +34,7 @@ <type name="Magento\Search\Model\Adminhtml\System\Config\Source\Engine"> <arguments> <argument name="engines" xsi:type="array"> - <item sortOrder="30" name="elasticsearch7" xsi:type="string">Elasticsearch 7 (Deprecated)</item> + <item sortOrder="30" name="elasticsearch8" xsi:type="string">Elasticsearch 8 (Deprecated)</item> </argument> </arguments> </type> @@ -25,14 +42,14 @@ <type name="Magento\Elasticsearch\Elasticsearch5\Model\Adapter\BatchDataMapper\CategoryFieldsProviderProxy"> <arguments> <argument name="categoryFieldsProviders" xsi:type="array"> - <item name="elasticsearch7" xsi:type="object">Magento\Elasticsearch\Elasticsearch5\Model\Adapter\BatchDataMapper\CategoryFieldsProvider</item> + <item name="elasticsearch8" xsi:type="object">Magento\Elasticsearch\Elasticsearch5\Model\Adapter\BatchDataMapper\CategoryFieldsProvider</item> </argument> </arguments> </type> <type name="Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\ProductFieldMapperProxy"> <arguments> <argument name="productFieldMappers" xsi:type="array"> - <item name="elasticsearch7" xsi:type="object">Magento\Elasticsearch7\Model\Adapter\FieldMapper\ProductFieldMapper</item> + <item name="elasticsearch8" xsi:type="object">Magento\Elasticsearch8\Model\Adapter\FieldMapper\ProductFieldMapper</item> </argument> </arguments> </type> @@ -40,10 +57,10 @@ <type name="Magento\AdvancedSearch\Model\Client\ClientResolver"> <arguments> <argument name="clientFactories" xsi:type="array"> - <item name="elasticsearch7" xsi:type="string">\Magento\Elasticsearch7\Model\Client\ElasticsearchFactory</item> + <item name="elasticsearch8" xsi:type="string">\Magento\Elasticsearch8\Model\Client\ElasticsearchFactory</item> </argument> <argument name="clientOptions" xsi:type="array"> - <item name="elasticsearch7" xsi:type="string">\Magento\Elasticsearch\Model\Config</item> + <item name="elasticsearch8" xsi:type="string">\Magento\Elasticsearch\Model\Config</item> </argument> </arguments> </type> @@ -51,7 +68,7 @@ <type name="Magento\CatalogSearch\Model\Indexer\IndexerHandlerFactory"> <arguments> <argument name="handlers" xsi:type="array"> - <item name="elasticsearch7" xsi:type="string">Magento\Elasticsearch\Model\Indexer\IndexerHandler</item> + <item name="elasticsearch8" xsi:type="string">Magento\Elasticsearch\Model\Indexer\IndexerHandler</item> </argument> </arguments> </type> @@ -59,7 +76,7 @@ <type name="Magento\CatalogSearch\Model\Indexer\IndexStructureFactory"> <arguments> <argument name="structures" xsi:type="array"> - <item name="elasticsearch7" xsi:type="string">Magento\Elasticsearch\Model\Indexer\IndexStructure</item> + <item name="elasticsearch8" xsi:type="string">Magento\Elasticsearch\Model\Indexer\IndexStructure</item> </argument> </arguments> </type> @@ -67,7 +84,7 @@ <type name="Magento\CatalogSearch\Model\ResourceModel\EngineProvider"> <arguments> <argument name="engines" xsi:type="array"> - <item name="elasticsearch7" xsi:type="string">Magento\Elasticsearch\Model\ResourceModel\Engine</item> + <item name="elasticsearch8" xsi:type="string">Magento\Elasticsearch\Model\ResourceModel\Engine</item> </argument> </arguments> </type> @@ -75,7 +92,7 @@ <type name="Magento\Search\Model\AdapterFactory"> <arguments> <argument name="adapters" xsi:type="array"> - <item name="elasticsearch7" xsi:type="string">\Magento\Elasticsearch7\SearchAdapter\Adapter</item> + <item name="elasticsearch8" xsi:type="string">\Magento\Elasticsearch8\SearchAdapter\Adapter</item> </argument> </arguments> </type> @@ -83,22 +100,22 @@ <type name="Magento\Search\Model\EngineResolver"> <arguments> <argument name="engines" xsi:type="array"> - <item name="elasticsearch7" xsi:type="string">elasticsearch7</item> + <item name="elasticsearch8" xsi:type="string">elasticsearch8</item> </argument> - <argument name="defaultEngine" xsi:type="string">elasticsearch7</argument> + <argument name="defaultEngine" xsi:type="string">elasticsearch8</argument> </arguments> </type> - <virtualType name="Magento\Elasticsearch7\Model\Client\ElasticsearchFactory" type="Magento\AdvancedSearch\Model\Client\ClientFactory"> + <virtualType name="Magento\Elasticsearch8\Model\Client\ElasticsearchFactory" type="Magento\AdvancedSearch\Model\Client\ClientFactory"> <arguments> - <argument name="clientClass" xsi:type="string">Magento\Elasticsearch7\Model\Client\Elasticsearch</argument> + <argument name="clientClass" xsi:type="string">Magento\Elasticsearch8\Model\Client\Elasticsearch</argument> </arguments> </virtualType> <type name="Magento\Elasticsearch\Elasticsearch5\Model\Client\ClientFactoryProxy"> <arguments> <argument name="clientFactories" xsi:type="array"> - <item name="elasticsearch7" xsi:type="object">Magento\Elasticsearch7\Model\Client\ElasticsearchFactory</item> + <item name="elasticsearch8" xsi:type="object">Magento\Elasticsearch8\Model\Client\ElasticsearchFactory</item> </argument> </arguments> </type> @@ -106,7 +123,7 @@ <type name="Magento\Framework\Search\Dynamic\IntervalFactory"> <arguments> <argument name="intervals" xsi:type="array"> - <item name="elasticsearch7" xsi:type="string">Magento\Elasticsearch\Elasticsearch5\SearchAdapter\Aggregation\Interval</item> + <item name="elasticsearch8" xsi:type="string">Magento\Elasticsearch\Elasticsearch5\SearchAdapter\Aggregation\Interval</item> </argument> </arguments> </type> @@ -114,12 +131,12 @@ <type name="Magento\Framework\Search\Dynamic\DataProviderFactory"> <arguments> <argument name="dataProviders" xsi:type="array"> - <item name="elasticsearch7" xsi:type="string">Magento\Elasticsearch\SearchAdapter\Dynamic\DataProvider</item> + <item name="elasticsearch8" xsi:type="string">Magento\Elasticsearch\SearchAdapter\Dynamic\DataProvider</item> </argument> </arguments> </type> - <virtualType name="Magento\Elasticsearch7\Model\DataProvider\Suggestions" type="Magento\Elasticsearch\Model\DataProvider\Base\Suggestions"> + <virtualType name="Magento\Elasticsearch8\Model\DataProvider\Suggestions" type="Magento\Elasticsearch\Model\DataProvider\Base\Suggestions"> <arguments> <argument name="fieldProvider" xsi:type="object">elasticsearch5FieldProvider</argument> </arguments> @@ -127,11 +144,11 @@ <type name="Magento\AdvancedSearch\Model\SuggestedQueries"> <arguments> <argument name="data" xsi:type="array"> - <item name="elasticsearch7" xsi:type="string">Magento\Elasticsearch7\Model\DataProvider\Suggestions</item> + <item name="elasticsearch8" xsi:type="string">Magento\Elasticsearch8\Model\DataProvider\Suggestions</item> </argument> </arguments> </type> - <virtualType name="\Magento\Elasticsearch7\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\CompositeResolver" type="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\CompositeResolver"> + <virtualType name="\Magento\Elasticsearch8\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\CompositeResolver" type="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\CompositeResolver"> <arguments> <argument name="items" xsi:type="array"> <item name="notEav" xsi:type="object" sortOrder="10">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\NotEavAttribute</item> @@ -139,27 +156,27 @@ <item name="price" xsi:type="object" sortOrder="30">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\Price</item> <item name="categoryName" xsi:type="object" sortOrder="40">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\CategoryName</item> <item name="position" xsi:type="object" sortOrder="50">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\Position</item> - <item name="default" xsi:type="object" sortOrder="100">Magento\Elasticsearch7\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\DefaultResolver</item> + <item name="default" xsi:type="object" sortOrder="100">Magento\Elasticsearch8\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\DefaultResolver</item> </argument> </arguments> </virtualType> - <type name="Magento\Elasticsearch7\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\DefaultResolver"> + <type name="Magento\Elasticsearch8\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\DefaultResolver"> <arguments> <argument name="baseResolver" xsi:type="object">Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\DefaultResolver</argument> </arguments> </type> - <virtualType name="Magento\Elasticsearch7\Model\Adapter\FieldMapper\ProductFieldMapper" + <virtualType name="Magento\Elasticsearch8\Model\Adapter\FieldMapper\ProductFieldMapper" type="Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\ProductFieldMapper"> <arguments> <argument name="fieldProvider" xsi:type="object">elasticsearch5FieldProvider</argument> - <argument name="fieldNameResolver" xsi:type="object">\Magento\Elasticsearch7\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\CompositeResolver</argument> + <argument name="fieldNameResolver" xsi:type="object">\Magento\Elasticsearch8\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\CompositeResolver</argument> </arguments> </virtualType> <type name="Magento\Search\Model\Search\PageSizeProvider"> <arguments> <argument name="pageSizeBySearchEngine" xsi:type="array"> - <item name="elasticsearch7" xsi:type="number">10000</item> + <item name="elasticsearch8" xsi:type="number">10000</item> </argument> </arguments> </type> @@ -167,7 +184,7 @@ <virtualType name="elasticsearchLayerCategoryItemCollectionProvider" type="Magento\Elasticsearch\Model\Layer\Category\ItemCollectionProvider"> <arguments> <argument name="factories" xsi:type="array"> - <item name="elasticsearch7" xsi:type="object">elasticsearchCategoryCollectionFactory</item> + <item name="elasticsearch8" xsi:type="object">elasticsearchCategoryCollectionFactory</item> </argument> </arguments> </virtualType> @@ -175,7 +192,7 @@ <type name="Magento\CatalogSearch\Model\Search\ItemCollectionProvider"> <arguments> <argument name="factories" xsi:type="array"> - <item name="elasticsearch7" xsi:type="object">elasticsearchAdvancedCollectionFactory</item> + <item name="elasticsearch8" xsi:type="object">elasticsearchAdvancedCollectionFactory</item> <item name="default" xsi:type="object">elasticsearchAdvancedCollectionFactory</item> </argument> </arguments> @@ -184,7 +201,7 @@ <type name="Magento\CatalogSearch\Model\Advanced\ProductCollectionPrepareStrategyProvider"> <arguments> <argument name="strategies" xsi:type="array"> - <item name="elasticsearch7" xsi:type="object">Magento\Elasticsearch\Model\Advanced\ProductCollectionPrepareStrategy</item> + <item name="elasticsearch8" xsi:type="object">Magento\Elasticsearch\Model\Advanced\ProductCollectionPrepareStrategy</item> </argument> </arguments> </type> @@ -192,7 +209,7 @@ <virtualType name="elasticsearchLayerSearchItemCollectionProvider" type="Magento\Elasticsearch\Model\Layer\Search\ItemCollectionProvider"> <arguments> <argument name="factories" xsi:type="array"> - <item name="elasticsearch7" xsi:type="object">elasticsearchFulltextSearchCollectionFactory</item> + <item name="elasticsearch8" xsi:type="object">elasticsearchFulltextSearchCollectionFactory</item> </argument> </arguments> </virtualType> @@ -200,64 +217,64 @@ <type name="Magento\Config\Model\Config\TypePool"> <arguments> <argument name="sensitive" xsi:type="array"> - <item name="catalog/search/elasticsearch7_password" xsi:type="string">1</item> - <item name="catalog/search/elasticsearch7_server_hostname" xsi:type="string">1</item> - <item name="catalog/search/elasticsearch7_username" xsi:type="string">1</item> + <item name="catalog/search/elasticsearch8_password" xsi:type="string">1</item> + <item name="catalog/search/elasticsearch8_server_hostname" xsi:type="string">1</item> + <item name="catalog/search/elasticsearch8_username" xsi:type="string">1</item> </argument> <argument name="environment" xsi:type="array"> - <item name="catalog/search/elasticsearch7_enable_auth" xsi:type="string">1</item> - <item name="catalog/search/elasticsearch7_index_prefix" xsi:type="string">1</item> - <item name="catalog/search/elasticsearch7_password" xsi:type="string">1</item> - <item name="catalog/search/elasticsearch7_server_hostname" xsi:type="string">1</item> - <item name="catalog/search/elasticsearch7_server_port" xsi:type="string">1</item> - <item name="catalog/search/elasticsearch7_username" xsi:type="string">1</item> - <item name="catalog/search/elasticsearch7_server_timeout" xsi:type="string">1</item> + <item name="catalog/search/elasticsearch8_enable_auth" xsi:type="string">1</item> + <item name="catalog/search/elasticsearch8_index_prefix" xsi:type="string">1</item> + <item name="catalog/search/elasticsearch8_password" xsi:type="string">1</item> + <item name="catalog/search/elasticsearch8_server_hostname" xsi:type="string">1</item> + <item name="catalog/search/elasticsearch8_server_port" xsi:type="string">1</item> + <item name="catalog/search/elasticsearch8_username" xsi:type="string">1</item> + <item name="catalog/search/elasticsearch8_server_timeout" xsi:type="string">1</item> </argument> </arguments> </type> - <type name="Magento\Elasticsearch7\Model\Client\Elasticsearch"> + <type name="Magento\Elasticsearch8\Model\Client\Elasticsearch"> <arguments> <argument name="fieldsMappingPreprocessors" xsi:type="array"> - <item name="elasticsearch7_copy_searchable_fields_to_search_field" xsi:type="object">Magento\Elasticsearch\Model\Adapter\FieldMapper\CopySearchableFieldsToSearchField</item> - <item name="elasticsearch7_add_default_search_field" xsi:type="object">Magento\Elasticsearch\Model\Adapter\FieldMapper\AddDefaultSearchField</item> + <item name="elasticsearch8_copy_searchable_fields_to_search_field" xsi:type="object">Magento\Elasticsearch\Model\Adapter\FieldMapper\CopySearchableFieldsToSearchField</item> + <item name="elasticsearch8_add_default_search_field" xsi:type="object">Magento\Elasticsearch\Model\Adapter\FieldMapper\AddDefaultSearchField</item> </argument> </arguments> </type> - <virtualType name="Magento\Elasticsearch7\Setup\InstallConfig" type="Magento\Search\Setup\InstallConfig"> + <virtualType name="Magento\Elasticsearch8\Setup\InstallConfig" type="Magento\Search\Setup\InstallConfig"> <arguments> <argument name="searchConfigMapping" xsi:type="array"> - <item name="elasticsearch-host" xsi:type="string">elasticsearch7_server_hostname</item> - <item name="elasticsearch-port" xsi:type="string">elasticsearch7_server_port</item> - <item name="elasticsearch-timeout" xsi:type="string">elasticsearch7_server_timeout</item> - <item name="elasticsearch-index-prefix" xsi:type="string">elasticsearch7_index_prefix</item> - <item name="elasticsearch-enable-auth" xsi:type="string">elasticsearch7_enable_auth</item> - <item name="elasticsearch-username" xsi:type="string">elasticsearch7_username</item> - <item name="elasticsearch-password" xsi:type="string">elasticsearch7_password</item> + <item name="elasticsearch-host" xsi:type="string">elasticsearch8_server_hostname</item> + <item name="elasticsearch-port" xsi:type="string">elasticsearch8_server_port</item> + <item name="elasticsearch-timeout" xsi:type="string">elasticsearch8_server_timeout</item> + <item name="elasticsearch-index-prefix" xsi:type="string">elasticsearch8_index_prefix</item> + <item name="elasticsearch-enable-auth" xsi:type="string">elasticsearch8_enable_auth</item> + <item name="elasticsearch-username" xsi:type="string">elasticsearch8_username</item> + <item name="elasticsearch-password" xsi:type="string">elasticsearch8_password</item> </argument> </arguments> </virtualType> <type name="Magento\Search\Setup\CompositeInstallConfig"> <arguments> <argument name="installConfigList" xsi:type="array"> - <item name="elasticsearch7" xsi:type="object">Magento\Elasticsearch7\Setup\InstallConfig</item> + <item name="elasticsearch8" xsi:type="object">Magento\Elasticsearch8\Setup\InstallConfig</item> </argument> </arguments> </type> <type name="Magento\Search\Model\SearchEngine\Validator"> <arguments> <argument name="engineValidators" xsi:type="array"> - <item name="elasticsearch7" xsi:type="object">Magento\Elasticsearch\Setup\Validator</item> + <item name="elasticsearch8" xsi:type="object">Magento\Elasticsearch\Setup\Validator</item> </argument> </arguments> </type> - <type name="Magento\Elasticsearch7\Model\Adapter\DynamicTemplatesProvider"> + <type name="Magento\Elasticsearch8\Model\Adapter\DynamicTemplatesProvider"> <arguments> <argument name="mappers" xsi:type="array"> - <item name="price_mapping" xsi:type="object">Magento\Elasticsearch7\Model\Adapter\DynamicTemplates\PriceMapper</item> - <item name="position_mapping" xsi:type="object">Magento\Elasticsearch7\Model\Adapter\DynamicTemplates\PositionMapper</item> - <item name="string_mapping" xsi:type="object">Magento\Elasticsearch7\Model\Adapter\DynamicTemplates\StringMapper</item> - <item name="integer_mapping" xsi:type="object">Magento\Elasticsearch7\Model\Adapter\DynamicTemplates\IntegerMapper</item> + <item name="price_mapping" xsi:type="object">Magento\Elasticsearch8\Model\Adapter\DynamicTemplates\PriceMapper</item> + <item name="position_mapping" xsi:type="object">Magento\Elasticsearch8\Model\Adapter\DynamicTemplates\PositionMapper</item> + <item name="string_mapping" xsi:type="object">Magento\Elasticsearch8\Model\Adapter\DynamicTemplates\StringMapper</item> + <item name="integer_mapping" xsi:type="object">Magento\Elasticsearch8\Model\Adapter\DynamicTemplates\IntegerMapper</item> </argument> </arguments> </type> diff --git a/app/code/Magento/Elasticsearch7/etc/module.xml b/app/code/Magento/Elasticsearch8/etc/module.xml similarity index 91% rename from app/code/Magento/Elasticsearch7/etc/module.xml rename to app/code/Magento/Elasticsearch8/etc/module.xml index 93dd7a2e49c..32ea0b381b7 100644 --- a/app/code/Magento/Elasticsearch7/etc/module.xml +++ b/app/code/Magento/Elasticsearch8/etc/module.xml @@ -6,7 +6,7 @@ */ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> - <module name="Magento_Elasticsearch7"> + <module name="Magento_Elasticsearch8"> <sequence> <module name="Magento_AdvancedSearch"/> <module name="Magento_Elasticsearch"/> diff --git a/app/code/Magento/Elasticsearch7/etc/search_engine.xml b/app/code/Magento/Elasticsearch8/etc/search_engine.xml similarity index 90% rename from app/code/Magento/Elasticsearch7/etc/search_engine.xml rename to app/code/Magento/Elasticsearch8/etc/search_engine.xml index 9633d186691..28e4074bfc8 100644 --- a/app/code/Magento/Elasticsearch7/etc/search_engine.xml +++ b/app/code/Magento/Elasticsearch8/etc/search_engine.xml @@ -6,7 +6,7 @@ */ --> <engines xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Search/etc/search_engine.xsd"> - <engine name="elasticsearch7"> + <engine name="elasticsearch8"> <feature name="synonyms" support="true" /> </engine> </engines> diff --git a/app/code/Magento/Elasticsearch7/registration.php b/app/code/Magento/Elasticsearch8/registration.php similarity index 89% rename from app/code/Magento/Elasticsearch7/registration.php rename to app/code/Magento/Elasticsearch8/registration.php index 63e13cfbed8..bfe52f2f4ce 100644 --- a/app/code/Magento/Elasticsearch7/registration.php +++ b/app/code/Magento/Elasticsearch8/registration.php @@ -7,6 +7,6 @@ \Magento\Framework\Component\ComponentRegistrar::register( \Magento\Framework\Component\ComponentRegistrar::MODULE, - 'Magento_Elasticsearch7', + 'Magento_Elasticsearch8', __DIR__ ); diff --git a/composer.json b/composer.json index ba7661fd817..d13c5f3da9d 100644 --- a/composer.json +++ b/composer.json @@ -47,10 +47,9 @@ "colinmollenhour/credis": "^1.15", "colinmollenhour/php-redis-session-abstract": "^2.0", "composer/composer": "^2.0, !=2.2.16", - "magento/elasticsearch": "^1.0.0", + "elasticsearch/elasticsearch": "^8.15", "duosecurity/duo_api_php": "^1.1", "duosecurity/duo_universal_php": "^1.0", - "elasticsearch/elasticsearch": "^7.17 || ^8.15", "ezyang/htmlpurifier": "^4.17", "guzzlehttp/guzzle": "^7.5", "laminas/laminas-captcha": "^2.18", diff --git a/composer.lock b/composer.lock index beb32e9d712..1ecb6d20e08 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "70a2b64cfd2aae73628f56ca984e0d23", + "content-hash": "865481b08740a0da1ef9c8dd862108b1", "packages": [ { "name": "aws/aws-crt-php", @@ -62,16 +62,16 @@ }, { "name": "aws/aws-sdk-php", - "version": "3.336.13", + "version": "3.338.2", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "dcb43c029ca74c52fa03a739341cc77086296a83" + "reference": "7a52364e053d74363f9976dfb4473bace5b7790e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/dcb43c029ca74c52fa03a739341cc77086296a83", - "reference": "dcb43c029ca74c52fa03a739341cc77086296a83", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/7a52364e053d74363f9976dfb4473bace5b7790e", + "reference": "7a52364e053d74363f9976dfb4473bace5b7790e", "shasum": "" }, "require": { @@ -79,31 +79,31 @@ "ext-json": "*", "ext-pcre": "*", "ext-simplexml": "*", - "guzzlehttp/guzzle": "^6.5.8 || ^7.4.5", - "guzzlehttp/promises": "^1.4.0 || ^2.0", - "guzzlehttp/psr7": "^1.9.1 || ^2.4.5", - "mtdowling/jmespath.php": "^2.6", - "php": ">=7.2.5", - "psr/http-message": "^1.0 || ^2.0" + "guzzlehttp/guzzle": "^7.4.5", + "guzzlehttp/promises": "^2.0", + "guzzlehttp/psr7": "^2.4.5", + "mtdowling/jmespath.php": "^2.8.0", + "php": ">=8.1", + "psr/http-message": "^2.0" }, "require-dev": { "andrewsville/php-token-reflection": "^1.4", "aws/aws-php-sns-message-validator": "~1.0", "behat/behat": "~3.0", - "composer/composer": "^1.10.22", + "composer/composer": "^2.7.8", "dms/phpunit-arraysubset-asserts": "^0.4.0", "doctrine/cache": "~1.4", "ext-dom": "*", "ext-openssl": "*", "ext-pcntl": "*", "ext-sockets": "*", - "nette/neon": "^2.3", "paragonie/random_compat": ">= 2", "phpunit/phpunit": "^5.6.3 || ^8.5 || ^9.5", - "psr/cache": "^1.0 || ^2.0 || ^3.0", - "psr/simple-cache": "^1.0 || ^2.0 || ^3.0", - "sebastian/comparator": "^1.2.3 || ^4.0", - "yoast/phpunit-polyfills": "^1.0" + "psr/cache": "^2.0 || ^3.0", + "psr/simple-cache": "^2.0 || ^3.0", + "sebastian/comparator": "^1.2.3 || ^4.0 || ^5.0", + "symfony/filesystem": "^v6.4.0 || ^v7.1.0", + "yoast/phpunit-polyfills": "^2.0" }, "suggest": { "aws/aws-php-sns-message-validator": "To validate incoming SNS notifications", @@ -152,11 +152,11 @@ "sdk" ], "support": { - "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80", + "forum": "https://github.com/aws/aws-sdk-php/discussions", "issues": "https://github.com/aws/aws-sdk-php/issues", - "source": "https://github.com/aws/aws-sdk-php/tree/3.336.13" + "source": "https://github.com/aws/aws-sdk-php/tree/3.338.2" }, - "time": "2025-01-10T19:04:25+00:00" + "time": "2025-01-24T19:09:22+00:00" }, { "name": "brick/math", @@ -596,16 +596,16 @@ }, { "name": "composer/composer", - "version": "2.8.4", + "version": "2.8.5", "source": { "type": "git", "url": "https://github.com/composer/composer.git", - "reference": "112e37d1dca22b3fdb81cf3524ab4994f47fdb8c" + "reference": "ae208dc1e182bd45d99fcecb956501da212454a1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/composer/zipball/112e37d1dca22b3fdb81cf3524ab4994f47fdb8c", - "reference": "112e37d1dca22b3fdb81cf3524ab4994f47fdb8c", + "url": "https://api.github.com/repos/composer/composer/zipball/ae208dc1e182bd45d99fcecb956501da212454a1", + "reference": "ae208dc1e182bd45d99fcecb956501da212454a1", "shasum": "" }, "require": { @@ -690,7 +690,7 @@ "irc": "ircs://irc.libera.chat:6697/composer", "issues": "https://github.com/composer/composer/issues", "security": "https://github.com/composer/composer/security/policy", - "source": "https://github.com/composer/composer/tree/2.8.4" + "source": "https://github.com/composer/composer/tree/2.8.5" }, "funding": [ { @@ -706,7 +706,7 @@ "type": "tidelift" } ], - "time": "2024-12-11T10:57:47+00:00" + "time": "2025-01-21T14:23:40+00:00" }, { "name": "composer/metadata-minifier", @@ -1161,6 +1161,122 @@ }, "time": "2023-01-13T18:47:58+00:00" }, + { + "name": "elastic/transport", + "version": "v8.10.0", + "source": { + "type": "git", + "url": "https://github.com/elastic/elastic-transport-php.git", + "reference": "8be37d679637545e50b1cea9f8ee903888783021" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/elastic/elastic-transport-php/zipball/8be37d679637545e50b1cea9f8ee903888783021", + "reference": "8be37d679637545e50b1cea9f8ee903888783021", + "shasum": "" + }, + "require": { + "composer-runtime-api": "^2.0", + "open-telemetry/api": "^1.0", + "php": "^7.4 || ^8.0", + "php-http/discovery": "^1.14", + "php-http/httplug": "^2.3", + "psr/http-client": "^1.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.0 || ^2.0", + "psr/log": "^1 || ^2 || ^3" + }, + "require-dev": { + "nyholm/psr7": "^1.5", + "open-telemetry/sdk": "^1.0", + "php-http/mock-client": "^1.5", + "phpstan/phpstan": "^1.4", + "phpunit/phpunit": "^9.5", + "symfony/http-client": "^5.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Elastic\\Transport\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "HTTP transport PHP library for Elastic products", + "keywords": [ + "PSR_17", + "elastic", + "http", + "psr-18", + "psr-7", + "transport" + ], + "support": { + "issues": "https://github.com/elastic/elastic-transport-php/issues", + "source": "https://github.com/elastic/elastic-transport-php/tree/v8.10.0" + }, + "time": "2024-08-14T08:55:07+00:00" + }, + { + "name": "elasticsearch/elasticsearch", + "version": "v8.17.0", + "source": { + "type": "git", + "url": "https://github.com/elastic/elasticsearch-php.git", + "reference": "6cd0fe6a95fdb7198a2795624927b094813b3d8b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/elastic/elasticsearch-php/zipball/6cd0fe6a95fdb7198a2795624927b094813b3d8b", + "reference": "6cd0fe6a95fdb7198a2795624927b094813b3d8b", + "shasum": "" + }, + "require": { + "elastic/transport": "^8.10", + "guzzlehttp/guzzle": "^7.0", + "php": "^7.4 || ^8.0", + "psr/http-client": "^1.0", + "psr/http-message": "^1.1 || ^2.0", + "psr/log": "^1|^2|^3" + }, + "require-dev": { + "ext-yaml": "*", + "ext-zip": "*", + "mockery/mockery": "^1.5", + "nyholm/psr7": "^1.5", + "php-http/message-factory": "^1.0", + "php-http/mock-client": "^1.5", + "phpstan/phpstan": "^1.4", + "phpunit/phpunit": "^9.5", + "psr/http-factory": "^1.0", + "symfony/finder": "~4.0", + "symfony/http-client": "^5.0|^6.0|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Elastic\\Elasticsearch\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHP Client for Elasticsearch", + "keywords": [ + "client", + "elastic", + "elasticsearch", + "search" + ], + "support": { + "issues": "https://github.com/elastic/elasticsearch-php/issues", + "source": "https://github.com/elastic/elasticsearch-php/tree/v8.17.0" + }, + "time": "2024-12-18T11:00:27+00:00" + }, { "name": "ezimuel/guzzlestreams", "version": "3.1.0", @@ -1277,16 +1393,16 @@ }, { "name": "firebase/php-jwt", - "version": "v6.10.2", + "version": "v6.11.0", "source": { "type": "git", "url": "https://github.com/firebase/php-jwt.git", - "reference": "30c19ed0f3264cb660ea496895cfb6ef7ee3653b" + "reference": "8f718f4dfc9c5d5f0c994cdfd103921b43592712" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/firebase/php-jwt/zipball/30c19ed0f3264cb660ea496895cfb6ef7ee3653b", - "reference": "30c19ed0f3264cb660ea496895cfb6ef7ee3653b", + "url": "https://api.github.com/repos/firebase/php-jwt/zipball/8f718f4dfc9c5d5f0c994cdfd103921b43592712", + "reference": "8f718f4dfc9c5d5f0c994cdfd103921b43592712", "shasum": "" }, "require": { @@ -1334,9 +1450,9 @@ ], "support": { "issues": "https://github.com/firebase/php-jwt/issues", - "source": "https://github.com/firebase/php-jwt/tree/v6.10.2" + "source": "https://github.com/firebase/php-jwt/tree/v6.11.0" }, - "time": "2024-11-24T11:22:49+00:00" + "time": "2025-01-23T05:11:06+00:00" }, { "name": "guzzlehttp/guzzle", @@ -3059,16 +3175,16 @@ }, { "name": "laminas/laminas-session", - "version": "2.22.1", + "version": "2.23.0", "source": { "type": "git", "url": "https://github.com/laminas/laminas-session.git", - "reference": "0c2b84c26abca83dfc2cb41f114edb12ad06d111" + "reference": "799aeb8c9fc42763966d9d18789f88e96280f7b4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-session/zipball/0c2b84c26abca83dfc2cb41f114edb12ad06d111", - "reference": "0c2b84c26abca83dfc2cb41f114edb12ad06d111", + "url": "https://api.github.com/repos/laminas/laminas-session/zipball/799aeb8c9fc42763966d9d18789f88e96280f7b4", + "reference": "799aeb8c9fc42763966d9d18789f88e96280f7b4", "shasum": "" }, "require": { @@ -3138,7 +3254,7 @@ "type": "community_bridge" } ], - "time": "2024-12-19T10:45:50+00:00" + "time": "2025-01-23T20:54:08+00:00" }, { "name": "laminas/laminas-soap", @@ -3926,64 +4042,6 @@ ], "description": "Validating packages through a composer plugin" }, - { - "name": "magento/elasticsearch", - "version": "1.0.0-beta106", - "dist": { - "type": "zip", - "url": "https://repo.magento.com/archives/magento/elasticsearch/magento-elasticsearch-1.0.0.0-beta106.zip", - "shasum": "e37af28b840c683beee6d1e2157278980086e286" - }, - "require": { - "ext-json": ">=1.3.7", - "ezimuel/ringphp": "^1.1.2", - "php": "^7.3 || ^8.0", - "psr/log": "^1|^2|^3" - }, - "replace": { - "elasticsearch/elasticsearch": "^7.17" - }, - "require-dev": { - "ext-yaml": "*", - "ext-zip": "*", - "mockery/mockery": "^1.2", - "phpstan/phpstan": "^1.10", - "phpunit/phpunit": "^9.3", - "squizlabs/php_codesniffer": "^3.4", - "symfony/finder": "~4.0" - }, - "suggest": { - "ext-curl": "*", - "monolog/monolog": "Allows for client-level logging and tracing" - }, - "type": "library", - "autoload": { - "files": [ - "src/autoload.php" - ], - "psr-4": { - "Elasticsearch\\": "src/Elasticsearch/" - } - }, - "license": [ - "Apache-2.0", - "LGPL-2.1-only" - ], - "authors": [ - { - "name": "Zachary Tong" - }, - { - "name": "Enrico Zimuel" - } - ], - "description": "PHP Client for Elasticsearch", - "keywords": [ - "client", - "elasticsearch", - "search" - ] - }, { "name": "magento/laminas-crypt", "version": "1.0.0-beta106", @@ -5049,6 +5107,135 @@ }, "time": "2024-12-30T11:07:19+00:00" }, + { + "name": "open-telemetry/api", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/opentelemetry-php/api.git", + "reference": "351a30baa79699de3de3a814c8ccc7b52ccdfb1d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/opentelemetry-php/api/zipball/351a30baa79699de3de3a814c8ccc7b52ccdfb1d", + "reference": "351a30baa79699de3de3a814c8ccc7b52ccdfb1d", + "shasum": "" + }, + "require": { + "open-telemetry/context": "^1.0", + "php": "^8.1", + "psr/log": "^1.1|^2.0|^3.0", + "symfony/polyfill-php82": "^1.26" + }, + "conflict": { + "open-telemetry/sdk": "<=1.0.8" + }, + "type": "library", + "extra": { + "spi": { + "OpenTelemetry\\API\\Instrumentation\\AutoInstrumentation\\HookManagerInterface": [ + "OpenTelemetry\\API\\Instrumentation\\AutoInstrumentation\\ExtensionHookManager" + ] + }, + "branch-alias": { + "dev-main": "1.1.x-dev" + } + }, + "autoload": { + "files": [ + "Trace/functions.php" + ], + "psr-4": { + "OpenTelemetry\\API\\": "." + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "opentelemetry-php contributors", + "homepage": "https://github.com/open-telemetry/opentelemetry-php/graphs/contributors" + } + ], + "description": "API for OpenTelemetry PHP.", + "keywords": [ + "Metrics", + "api", + "apm", + "logging", + "opentelemetry", + "otel", + "tracing" + ], + "support": { + "chat": "https://app.slack.com/client/T08PSQ7BQ/C01NFPCV44V", + "docs": "https://opentelemetry.io/docs/php", + "issues": "https://github.com/open-telemetry/opentelemetry-php/issues", + "source": "https://github.com/open-telemetry/opentelemetry-php" + }, + "time": "2025-01-08T23:50:34+00:00" + }, + { + "name": "open-telemetry/context", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/opentelemetry-php/context.git", + "reference": "0cba875ea1953435f78aec7f1d75afa87bdbf7f3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/opentelemetry-php/context/zipball/0cba875ea1953435f78aec7f1d75afa87bdbf7f3", + "reference": "0cba875ea1953435f78aec7f1d75afa87bdbf7f3", + "shasum": "" + }, + "require": { + "php": "^8.1", + "symfony/polyfill-php82": "^1.26" + }, + "suggest": { + "ext-ffi": "To allow context switching in Fibers" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.0.x-dev" + } + }, + "autoload": { + "files": [ + "fiber/initialize_fiber_handler.php" + ], + "psr-4": { + "OpenTelemetry\\Context\\": "." + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "opentelemetry-php contributors", + "homepage": "https://github.com/open-telemetry/opentelemetry-php/graphs/contributors" + } + ], + "description": "Context implementation for OpenTelemetry PHP.", + "keywords": [ + "Context", + "opentelemetry", + "otel" + ], + "support": { + "chat": "https://app.slack.com/client/T08PSQ7BQ/C01NFPCV44V", + "docs": "https://opentelemetry.io/docs/php", + "issues": "https://github.com/open-telemetry/opentelemetry-php/issues", + "source": "https://github.com/open-telemetry/opentelemetry-php" + }, + "time": "2024-08-21T00:29:20+00:00" + }, { "name": "opensearch-project/opensearch-php", "version": "2.3.1", @@ -5488,6 +5675,194 @@ }, "time": "2024-11-21T09:21:41+00:00" }, + { + "name": "php-http/discovery", + "version": "1.20.0", + "source": { + "type": "git", + "url": "https://github.com/php-http/discovery.git", + "reference": "82fe4c73ef3363caed49ff8dd1539ba06044910d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/discovery/zipball/82fe4c73ef3363caed49ff8dd1539ba06044910d", + "reference": "82fe4c73ef3363caed49ff8dd1539ba06044910d", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0|^2.0", + "php": "^7.1 || ^8.0" + }, + "conflict": { + "nyholm/psr7": "<1.0", + "zendframework/zend-diactoros": "*" + }, + "provide": { + "php-http/async-client-implementation": "*", + "php-http/client-implementation": "*", + "psr/http-client-implementation": "*", + "psr/http-factory-implementation": "*", + "psr/http-message-implementation": "*" + }, + "require-dev": { + "composer/composer": "^1.0.2|^2.0", + "graham-campbell/phpspec-skip-example-extension": "^5.0", + "php-http/httplug": "^1.0 || ^2.0", + "php-http/message-factory": "^1.0", + "phpspec/phpspec": "^5.1 || ^6.1 || ^7.3", + "sebastian/comparator": "^3.0.5 || ^4.0.8", + "symfony/phpunit-bridge": "^6.4.4 || ^7.0.1" + }, + "type": "composer-plugin", + "extra": { + "class": "Http\\Discovery\\Composer\\Plugin", + "plugin-optional": true + }, + "autoload": { + "psr-4": { + "Http\\Discovery\\": "src/" + }, + "exclude-from-classmap": [ + "src/Composer/Plugin.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + } + ], + "description": "Finds and installs PSR-7, PSR-17, PSR-18 and HTTPlug implementations", + "homepage": "http://php-http.org", + "keywords": [ + "adapter", + "client", + "discovery", + "factory", + "http", + "message", + "psr17", + "psr7" + ], + "support": { + "issues": "https://github.com/php-http/discovery/issues", + "source": "https://github.com/php-http/discovery/tree/1.20.0" + }, + "time": "2024-10-02T11:20:13+00:00" + }, + { + "name": "php-http/httplug", + "version": "2.4.1", + "source": { + "type": "git", + "url": "https://github.com/php-http/httplug.git", + "reference": "5cad731844891a4c282f3f3e1b582c46839d22f4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/httplug/zipball/5cad731844891a4c282f3f3e1b582c46839d22f4", + "reference": "5cad731844891a4c282f3f3e1b582c46839d22f4", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0", + "php-http/promise": "^1.1", + "psr/http-client": "^1.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "require-dev": { + "friends-of-phpspec/phpspec-code-coverage": "^4.1 || ^5.0 || ^6.0", + "phpspec/phpspec": "^5.1 || ^6.0 || ^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Http\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eric GELOEN", + "email": "geloen.eric@gmail.com" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://sagikazarmark.hu" + } + ], + "description": "HTTPlug, the HTTP client abstraction for PHP", + "homepage": "http://httplug.io", + "keywords": [ + "client", + "http" + ], + "support": { + "issues": "https://github.com/php-http/httplug/issues", + "source": "https://github.com/php-http/httplug/tree/2.4.1" + }, + "time": "2024-09-23T11:39:58+00:00" + }, + { + "name": "php-http/promise", + "version": "1.3.1", + "source": { + "type": "git", + "url": "https://github.com/php-http/promise.git", + "reference": "fc85b1fba37c169a69a07ef0d5a8075770cc1f83" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/promise/zipball/fc85b1fba37c169a69a07ef0d5a8075770cc1f83", + "reference": "fc85b1fba37c169a69a07ef0d5a8075770cc1f83", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "friends-of-phpspec/phpspec-code-coverage": "^4.3.2 || ^6.3", + "phpspec/phpspec": "^5.1.2 || ^6.2 || ^7.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Http\\Promise\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Joel Wurtz", + "email": "joel.wurtz@gmail.com" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + } + ], + "description": "Promise used for asynchronous HTTP requests", + "homepage": "http://httplug.io", + "keywords": [ + "promise" + ], + "support": { + "issues": "https://github.com/php-http/promise/issues", + "source": "https://github.com/php-http/promise/tree/1.3.1" + }, + "time": "2024-03-15T13:55:21+00:00" + }, { "name": "phpseclib/mcrypt_compat", "version": "2.0.6", @@ -8615,6 +8990,82 @@ ], "time": "2024-09-09T11:45:10+00:00" }, + { + "name": "symfony/polyfill-php82", + "version": "v1.31.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php82.git", + "reference": "5d2ed36f7734637dacc025f179698031951b1692" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php82/zipball/5d2ed36f7734637dacc025f179698031951b1692", + "reference": "5d2ed36f7734637dacc025f179698031951b1692", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php82\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.2+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php82/tree/v1.31.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, { "name": "symfony/polyfill-php83", "version": "v1.31.0", @@ -10495,16 +10946,16 @@ }, { "name": "dg/bypass-finals", - "version": "v1.8.0", + "version": "v1.9.0", "source": { "type": "git", "url": "https://github.com/dg/bypass-finals.git", - "reference": "86b00f0d900c7e15d3341e687e0df89e8c2d4632" + "reference": "920a7da2f3c1422fd83f9ec4df007af53dc4018b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/dg/bypass-finals/zipball/86b00f0d900c7e15d3341e687e0df89e8c2d4632", - "reference": "86b00f0d900c7e15d3341e687e0df89e8c2d4632", + "url": "https://api.github.com/repos/dg/bypass-finals/zipball/920a7da2f3c1422fd83f9ec4df007af53dc4018b", + "reference": "920a7da2f3c1422fd83f9ec4df007af53dc4018b", "shasum": "" }, "require": { @@ -10542,9 +10993,9 @@ ], "support": { "issues": "https://github.com/dg/bypass-finals/issues", - "source": "https://github.com/dg/bypass-finals/tree/v1.8.0" + "source": "https://github.com/dg/bypass-finals/tree/v1.9.0" }, - "time": "2024-07-02T22:24:43+00:00" + "time": "2025-01-16T00:46:05+00:00" }, { "name": "doctrine/annotations", @@ -10809,16 +11260,16 @@ }, { "name": "friendsofphp/php-cs-fixer", - "version": "v3.68.0", + "version": "v3.68.1", "source": { "type": "git", "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", - "reference": "73f78d8b2b34a0dd65fedb434a602ee4c2c8ad4c" + "reference": "b9db2b2ea3cdba7201067acee46f984ef2397cff" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/73f78d8b2b34a0dd65fedb434a602ee4c2c8ad4c", - "reference": "73f78d8b2b34a0dd65fedb434a602ee4c2c8ad4c", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/b9db2b2ea3cdba7201067acee46f984ef2397cff", + "reference": "b9db2b2ea3cdba7201067acee46f984ef2397cff", "shasum": "" }, "require": { @@ -10900,7 +11351,7 @@ ], "support": { "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", - "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.68.0" + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.68.1" }, "funding": [ { @@ -10908,7 +11359,7 @@ "type": "github" } ], - "time": "2025-01-13T17:01:01+00:00" + "time": "2025-01-17T09:20:36+00:00" }, { "name": "laminas/laminas-diactoros", @@ -11871,16 +12322,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.12.15", + "version": "1.12.16", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "c91d4e8bc056f46cf653656e6f71004b254574d1" + "reference": "e0bb5cb78545aae631220735aa706eac633a6be9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/c91d4e8bc056f46cf653656e6f71004b254574d1", - "reference": "c91d4e8bc056f46cf653656e6f71004b254574d1", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/e0bb5cb78545aae631220735aa706eac633a6be9", + "reference": "e0bb5cb78545aae631220735aa706eac633a6be9", "shasum": "" }, "require": { @@ -11925,7 +12376,7 @@ "type": "github" } ], - "time": "2025-01-05T16:40:22+00:00" + "time": "2025-01-21T14:50:05+00:00" }, { "name": "phpunit/php-code-coverage", @@ -13940,16 +14391,16 @@ }, { "name": "squizlabs/php_codesniffer", - "version": "3.11.2", + "version": "3.11.3", "source": { "type": "git", "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git", - "reference": "1368f4a58c3c52114b86b1abe8f4098869cb0079" + "reference": "ba05f990e79cbe69b9f35c8c1ac8dca7eecc3a10" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/1368f4a58c3c52114b86b1abe8f4098869cb0079", - "reference": "1368f4a58c3c52114b86b1abe8f4098869cb0079", + "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/ba05f990e79cbe69b9f35c8c1ac8dca7eecc3a10", + "reference": "ba05f990e79cbe69b9f35c8c1ac8dca7eecc3a10", "shasum": "" }, "require": { @@ -14014,9 +14465,13 @@ { "url": "https://opencollective.com/php_codesniffer", "type": "open_collective" + }, + { + "url": "https://thanks.dev/phpcsstandards", + "type": "thanks_dev" } ], - "time": "2024-12-11T16:04:26+00:00" + "time": "2025-01-23T17:04:15+00:00" }, { "name": "symfony/dotenv", From 2bf62d8b43fbf903d09371ed17ee3a48aaf4135d Mon Sep 17 00:00:00 2001 From: Rajesh Kumar <glo71317@adobe.com> Date: Mon, 27 Jan 2025 19:51:11 +0530 Subject: [PATCH 02/30] AC-13818::Make ES8 to be default for 2.4.8 instead of ES7 --- app/code/Magento/Elasticsearch/composer.json | 2 +- .../System/Config/TestConnection.php | 4 +- .../DynamicTemplates/IntegerMapper.php | 4 +- .../DynamicTemplates/MapperInterface.php | 4 +- .../DynamicTemplates/PositionMapper.php | 4 +- .../Adapter/DynamicTemplates/PriceMapper.php | 4 +- .../Adapter/DynamicTemplates/StringMapper.php | 4 +- .../Adapter/DynamicTemplatesProvider.php | 4 +- .../Model/Adapter/Elasticsearch.php | 4 +- .../FieldName/Resolver/DefaultResolver.php | 4 +- .../Model/Client/Elasticsearch.php | 5 +- .../Elasticsearch8/SearchAdapter/Adapter.php | 4 +- .../Elasticsearch8/SearchAdapter/Mapper.php | 5 +- ...rchUsingElasticSearch8ByProductSkuTest.xml | 6 +-- .../Resolver/DefaultResolverTest.php | 4 +- .../Unit/Model/Client/ElasticsearchTest.php | 6 +-- .../Elasticsearch8/etc/adminhtml/system.xml | 4 +- .../Magento/Elasticsearch8/etc/config.xml | 4 +- app/code/Magento/Elasticsearch8/etc/di.xml | 4 +- .../Magento/Elasticsearch8/etc/module.xml | 4 +- .../Elasticsearch8/etc/search_engine.xml | 4 +- .../Magento/Elasticsearch8/registration.php | 4 +- composer.json | 2 +- composer.lock | 2 +- .../_files/state-filter-list.php | 2 +- .../SearchAdapter/ConnectionManagerTest.php | 53 ------------------- .../allowed_dependencies/ce.php | 2 +- .../Test/Legacy/_files/obsolete_classes.php | 9 ++-- 28 files changed, 56 insertions(+), 106 deletions(-) delete mode 100644 dev/tests/integration/testsuite/Magento/Elasticsearch7/SearchAdapter/ConnectionManagerTest.php diff --git a/app/code/Magento/Elasticsearch/composer.json b/app/code/Magento/Elasticsearch/composer.json index 26f357d7608..2b9b6fa2569 100644 --- a/app/code/Magento/Elasticsearch/composer.json +++ b/app/code/Magento/Elasticsearch/composer.json @@ -12,7 +12,7 @@ "magento/module-store": "*", "magento/module-catalog-inventory": "*", "magento/framework": "*", - "elasticsearch/elasticsearch": "^8.15" + "magento/elasticsearch": "^1.0.0" }, "suggest": { "magento/module-config": "*" diff --git a/app/code/Magento/Elasticsearch8/Block/Adminhtml/System/Config/TestConnection.php b/app/code/Magento/Elasticsearch8/Block/Adminhtml/System/Config/TestConnection.php index 311963e7929..f14c7b907ee 100644 --- a/app/code/Magento/Elasticsearch8/Block/Adminhtml/System/Config/TestConnection.php +++ b/app/code/Magento/Elasticsearch8/Block/Adminhtml/System/Config/TestConnection.php @@ -1,7 +1,7 @@ <?php /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. + * Copyright 2025 Adobe + * All Rights Reserved. */ declare(strict_types=1); diff --git a/app/code/Magento/Elasticsearch8/Model/Adapter/DynamicTemplates/IntegerMapper.php b/app/code/Magento/Elasticsearch8/Model/Adapter/DynamicTemplates/IntegerMapper.php index f156cd94475..b6575bded35 100644 --- a/app/code/Magento/Elasticsearch8/Model/Adapter/DynamicTemplates/IntegerMapper.php +++ b/app/code/Magento/Elasticsearch8/Model/Adapter/DynamicTemplates/IntegerMapper.php @@ -1,7 +1,7 @@ <?php /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. + * Copyright 2025 Adobe + * All Rights Reserved. */ declare(strict_types=1); diff --git a/app/code/Magento/Elasticsearch8/Model/Adapter/DynamicTemplates/MapperInterface.php b/app/code/Magento/Elasticsearch8/Model/Adapter/DynamicTemplates/MapperInterface.php index 3ac67f69b8a..83dc744db5b 100644 --- a/app/code/Magento/Elasticsearch8/Model/Adapter/DynamicTemplates/MapperInterface.php +++ b/app/code/Magento/Elasticsearch8/Model/Adapter/DynamicTemplates/MapperInterface.php @@ -1,7 +1,7 @@ <?php /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. + * Copyright 2025 Adobe + * All Rights Reserved. */ declare(strict_types=1); diff --git a/app/code/Magento/Elasticsearch8/Model/Adapter/DynamicTemplates/PositionMapper.php b/app/code/Magento/Elasticsearch8/Model/Adapter/DynamicTemplates/PositionMapper.php index e90e1065ba6..834b830d0fb 100644 --- a/app/code/Magento/Elasticsearch8/Model/Adapter/DynamicTemplates/PositionMapper.php +++ b/app/code/Magento/Elasticsearch8/Model/Adapter/DynamicTemplates/PositionMapper.php @@ -1,7 +1,7 @@ <?php /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. + * Copyright 2025 Adobe + * All Rights Reserved. */ declare(strict_types=1); diff --git a/app/code/Magento/Elasticsearch8/Model/Adapter/DynamicTemplates/PriceMapper.php b/app/code/Magento/Elasticsearch8/Model/Adapter/DynamicTemplates/PriceMapper.php index a0ccec213c6..ef91f1e26a5 100644 --- a/app/code/Magento/Elasticsearch8/Model/Adapter/DynamicTemplates/PriceMapper.php +++ b/app/code/Magento/Elasticsearch8/Model/Adapter/DynamicTemplates/PriceMapper.php @@ -1,7 +1,7 @@ <?php /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. + * Copyright 2025 Adobe + * All Rights Reserved. */ declare(strict_types=1); diff --git a/app/code/Magento/Elasticsearch8/Model/Adapter/DynamicTemplates/StringMapper.php b/app/code/Magento/Elasticsearch8/Model/Adapter/DynamicTemplates/StringMapper.php index 19b87012b23..dcb799f96a2 100644 --- a/app/code/Magento/Elasticsearch8/Model/Adapter/DynamicTemplates/StringMapper.php +++ b/app/code/Magento/Elasticsearch8/Model/Adapter/DynamicTemplates/StringMapper.php @@ -1,7 +1,7 @@ <?php /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. + * Copyright 2025 Adobe + * All Rights Reserved. */ declare(strict_types=1); diff --git a/app/code/Magento/Elasticsearch8/Model/Adapter/DynamicTemplatesProvider.php b/app/code/Magento/Elasticsearch8/Model/Adapter/DynamicTemplatesProvider.php index fec21e4fed8..31beab8ebb1 100644 --- a/app/code/Magento/Elasticsearch8/Model/Adapter/DynamicTemplatesProvider.php +++ b/app/code/Magento/Elasticsearch8/Model/Adapter/DynamicTemplatesProvider.php @@ -1,7 +1,7 @@ <?php /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. + * Copyright 2025 Adobe + * All Rights Reserved. */ declare(strict_types=1); diff --git a/app/code/Magento/Elasticsearch8/Model/Adapter/Elasticsearch.php b/app/code/Magento/Elasticsearch8/Model/Adapter/Elasticsearch.php index b3554196569..d1757ce9cb6 100644 --- a/app/code/Magento/Elasticsearch8/Model/Adapter/Elasticsearch.php +++ b/app/code/Magento/Elasticsearch8/Model/Adapter/Elasticsearch.php @@ -1,7 +1,7 @@ <?php /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. + * Copyright 2025 Adobe + * All Rights Reserved. */ declare(strict_types=1); diff --git a/app/code/Magento/Elasticsearch8/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolver.php b/app/code/Magento/Elasticsearch8/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolver.php index 3dd99346f7c..f8a66e5a1e8 100644 --- a/app/code/Magento/Elasticsearch8/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolver.php +++ b/app/code/Magento/Elasticsearch8/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolver.php @@ -1,7 +1,7 @@ <?php /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. + * Copyright 2025 Adobe + * All Rights Reserved. */ declare(strict_types=1); diff --git a/app/code/Magento/Elasticsearch8/Model/Client/Elasticsearch.php b/app/code/Magento/Elasticsearch8/Model/Client/Elasticsearch.php index 159f6ca5412..8e8492cd217 100644 --- a/app/code/Magento/Elasticsearch8/Model/Client/Elasticsearch.php +++ b/app/code/Magento/Elasticsearch8/Model/Client/Elasticsearch.php @@ -1,7 +1,7 @@ <?php /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. + * Copyright 2025 Adobe + * All Rights Reserved. */ declare(strict_types=1); @@ -78,6 +78,7 @@ public function __construct( } $this->clientOptions = $options; $this->fieldsMappingPreprocessors = $fieldsMappingPreprocessors; + // phpstan:ignore "File has calls static method. (phpStaticMethodCalls)" $this->dynamicTemplatesProvider = $dynamicTemplatesProvider ?: ObjectManager::getInstance() ->get(DynamicTemplatesProvider::class); } diff --git a/app/code/Magento/Elasticsearch8/SearchAdapter/Adapter.php b/app/code/Magento/Elasticsearch8/SearchAdapter/Adapter.php index 013db89fed7..528de9804c4 100644 --- a/app/code/Magento/Elasticsearch8/SearchAdapter/Adapter.php +++ b/app/code/Magento/Elasticsearch8/SearchAdapter/Adapter.php @@ -1,7 +1,7 @@ <?php /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. + * Copyright 2025 Adobe + * All Rights Reserved. */ declare(strict_types=1); diff --git a/app/code/Magento/Elasticsearch8/SearchAdapter/Mapper.php b/app/code/Magento/Elasticsearch8/SearchAdapter/Mapper.php index a9fdf389a2b..51cfc024c37 100644 --- a/app/code/Magento/Elasticsearch8/SearchAdapter/Mapper.php +++ b/app/code/Magento/Elasticsearch8/SearchAdapter/Mapper.php @@ -1,9 +1,8 @@ <?php /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. + * Copyright 2025 Adobe + * All Rights Reserved. */ - declare(strict_types=1); namespace Magento\Elasticsearch8\SearchAdapter; diff --git a/app/code/Magento/Elasticsearch8/Test/Mftf/Test/StorefrontQuickSearchUsingElasticSearch8ByProductSkuTest.xml b/app/code/Magento/Elasticsearch8/Test/Mftf/Test/StorefrontQuickSearchUsingElasticSearch8ByProductSkuTest.xml index cf733bd22f8..9eaae765be0 100644 --- a/app/code/Magento/Elasticsearch8/Test/Mftf/Test/StorefrontQuickSearchUsingElasticSearch8ByProductSkuTest.xml +++ b/app/code/Magento/Elasticsearch8/Test/Mftf/Test/StorefrontQuickSearchUsingElasticSearch8ByProductSkuTest.xml @@ -1,9 +1,9 @@ <?xml version="1.0" encoding="UTF-8"?> <!-- /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ + * Copyright 2025 Adobe + * All Rights Reserved. + */ --> <tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" diff --git a/app/code/Magento/Elasticsearch8/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolverTest.php b/app/code/Magento/Elasticsearch8/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolverTest.php index 30c93cd7125..67fe4db5a46 100644 --- a/app/code/Magento/Elasticsearch8/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolverTest.php +++ b/app/code/Magento/Elasticsearch8/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolverTest.php @@ -1,7 +1,7 @@ <?php /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. + * Copyright 2025 Adobe + * All Rights Reserved. */ declare(strict_types=1); diff --git a/app/code/Magento/Elasticsearch8/Test/Unit/Model/Client/ElasticsearchTest.php b/app/code/Magento/Elasticsearch8/Test/Unit/Model/Client/ElasticsearchTest.php index 95df0b57524..f266911a4b2 100644 --- a/app/code/Magento/Elasticsearch8/Test/Unit/Model/Client/ElasticsearchTest.php +++ b/app/code/Magento/Elasticsearch8/Test/Unit/Model/Client/ElasticsearchTest.php @@ -1,9 +1,8 @@ <?php /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. + * Copyright 2025 Adobe + * All Rights Reserved. */ - declare(strict_types=1); namespace Magento\Elasticsearch8\Test\Unit\Model\Client; @@ -61,6 +60,7 @@ class ElasticsearchTest extends TestCase */ protected function setUp(): void { + // phpstan:ignore "File has calls static method. (phpStaticMethodCalls)" BypassFinals::enable(); $this->elasticsearchClientMock = $this->getMockBuilder(Client::class) /** @phpstan-ignore-line */ ->onlyMethods( diff --git a/app/code/Magento/Elasticsearch8/etc/adminhtml/system.xml b/app/code/Magento/Elasticsearch8/etc/adminhtml/system.xml index cc51355cd10..2fb1f4f94e7 100644 --- a/app/code/Magento/Elasticsearch8/etc/adminhtml/system.xml +++ b/app/code/Magento/Elasticsearch8/etc/adminhtml/system.xml @@ -1,8 +1,8 @@ <?xml version="1.0"?> <!-- /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. + * Copyright 2025 Adobe + * All Rights Reserved. */ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" diff --git a/app/code/Magento/Elasticsearch8/etc/config.xml b/app/code/Magento/Elasticsearch8/etc/config.xml index 727af7d024f..81b83e6dd31 100644 --- a/app/code/Magento/Elasticsearch8/etc/config.xml +++ b/app/code/Magento/Elasticsearch8/etc/config.xml @@ -1,8 +1,8 @@ <?xml version="1.0"?> <!-- /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. + * Copyright 2025 Adobe + * All Rights Reserved. */ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd"> diff --git a/app/code/Magento/Elasticsearch8/etc/di.xml b/app/code/Magento/Elasticsearch8/etc/di.xml index 694b7c658a9..42c8289c314 100644 --- a/app/code/Magento/Elasticsearch8/etc/di.xml +++ b/app/code/Magento/Elasticsearch8/etc/di.xml @@ -1,8 +1,8 @@ <?xml version="1.0"?> <!-- /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. + * Copyright 2025 Adobe + * All Rights Reserved. */ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> diff --git a/app/code/Magento/Elasticsearch8/etc/module.xml b/app/code/Magento/Elasticsearch8/etc/module.xml index 32ea0b381b7..0158dd2bff0 100644 --- a/app/code/Magento/Elasticsearch8/etc/module.xml +++ b/app/code/Magento/Elasticsearch8/etc/module.xml @@ -1,8 +1,8 @@ <?xml version="1.0"?> <!-- /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. + * Copyright 2025 Adobe + * All Rights Reserved. */ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> diff --git a/app/code/Magento/Elasticsearch8/etc/search_engine.xml b/app/code/Magento/Elasticsearch8/etc/search_engine.xml index 28e4074bfc8..71fa1c3adf3 100644 --- a/app/code/Magento/Elasticsearch8/etc/search_engine.xml +++ b/app/code/Magento/Elasticsearch8/etc/search_engine.xml @@ -1,8 +1,8 @@ <?xml version="1.0"?> <!-- /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. + * Copyright 2025 Adobe + * All Rights Reserved. */ --> <engines xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Search/etc/search_engine.xsd"> diff --git a/app/code/Magento/Elasticsearch8/registration.php b/app/code/Magento/Elasticsearch8/registration.php index bfe52f2f4ce..86322f0c0bf 100644 --- a/app/code/Magento/Elasticsearch8/registration.php +++ b/app/code/Magento/Elasticsearch8/registration.php @@ -1,7 +1,7 @@ <?php /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. + * Copyright 2025 Adobe + * All Rights Reserved. */ declare(strict_types=1); diff --git a/composer.json b/composer.json index d13c5f3da9d..0ed58afe311 100644 --- a/composer.json +++ b/composer.json @@ -181,7 +181,7 @@ "magento/module-eav": "*", "magento/module-open-search": "*", "magento/module-elasticsearch": "*", - "magento/module-elasticsearch-7": "*", + "magento/module-elasticsearch-8": "*", "magento/module-email": "*", "magento/module-encryption-key": "*", "magento/module-fedex": "*", diff --git a/composer.lock b/composer.lock index 1ecb6d20e08..e81691a0bb6 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "865481b08740a0da1ef9c8dd862108b1", + "content-hash": "4d21655c4853f2c9d7569fab31210516", "packages": [ { "name": "aws/aws-crt-php", diff --git a/dev/tests/integration/framework/Magento/TestFramework/ApplicationStateComparator/_files/state-filter-list.php b/dev/tests/integration/framework/Magento/TestFramework/ApplicationStateComparator/_files/state-filter-list.php index 549575f85d6..c22f4864b44 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/ApplicationStateComparator/_files/state-filter-list.php +++ b/dev/tests/integration/framework/Magento/TestFramework/ApplicationStateComparator/_files/state-filter-list.php @@ -112,7 +112,7 @@ // TODO: Do we need resetState for the connection? Magento\Elasticsearch\SearchAdapter\ConnectionManager::class => ['client' => null], // TODO: Do we need resetState for the connection? - Magento\Elasticsearch7\Model\Client\Elasticsearch::class => ['client' => null], + Magento\Elasticsearch8\Model\Client\Elasticsearch::class => ['client' => null], // TODO: Do we need resetState for the connection? Magento\Webapi\Model\Authorization\TokenUserContext::class => ['request' => null], Magento\Framework\Json\Helper\Data::class => ['_request' => null], diff --git a/dev/tests/integration/testsuite/Magento/Elasticsearch7/SearchAdapter/ConnectionManagerTest.php b/dev/tests/integration/testsuite/Magento/Elasticsearch7/SearchAdapter/ConnectionManagerTest.php deleted file mode 100644 index 9222a3149c3..00000000000 --- a/dev/tests/integration/testsuite/Magento/Elasticsearch7/SearchAdapter/ConnectionManagerTest.php +++ /dev/null @@ -1,53 +0,0 @@ -<?php -/** - * Copyright 2022 Adobe - * All Rights Reserved. - */ -declare(strict_types=1); - -namespace Magento\Elasticsearch7\SearchAdapter; - -use Magento\Elasticsearch\SearchAdapter\ConnectionManager; -use Magento\Elasticsearch7\Model\Client\Elasticsearch; -use Magento\TestFramework\Helper\Bootstrap; -use PHPUnit\Framework\TestCase; - -class ConnectionManagerTest extends TestCase -{ - /** - * @var \Magento\Framework\ObjectManagerInterface - */ - private $objectManager; - - /** - * @var \Magento\Elasticsearch\SearchAdapter\ConnectionManager - */ - private $connectionManager; - - /** - * @inheritDoc - */ - protected function setUp(): void - { - $this->objectManager = Bootstrap::getObjectManager(); - - // phpstan:ignore "Class Magento\Elasticsearch\SearchAdapter\ConnectionManager not found." - $this->connectionManager = $this->objectManager->create(ConnectionManager::class); - } - - /** - * Test if 'elasticsearch7' search engine returned by connection manager. - * - * @magentoAppIsolation enabled - * @magentoConfigFixture default/catalog/search/engine elasticsearch7 - */ - public function testCorrectElasticsearchClientEs7() - { - if (!class_exists(\Elasticsearch\ClientBuilder::class)) { /** @phpstan-ignore-line */ - $this->markTestSkipped('AC-6597: Skipped as Elasticsearch 8 is configured'); - } - - $connection = $this->connectionManager->getConnection(); - $this->assertInstanceOf(Elasticsearch::class, $connection); - } -} diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/_files/extension_dependencies_test/allowed_dependencies/ce.php b/dev/tests/static/testsuite/Magento/Test/Integrity/_files/extension_dependencies_test/allowed_dependencies/ce.php index b4506499d00..5e50d629abe 100644 --- a/dev/tests/static/testsuite/Magento/Test/Integrity/_files/extension_dependencies_test/allowed_dependencies/ce.php +++ b/dev/tests/static/testsuite/Magento/Test/Integrity/_files/extension_dependencies_test/allowed_dependencies/ce.php @@ -7,7 +7,7 @@ return [ 'Magento\Elasticsearch' => [ - 'Magento\Elasticsearch7', + 'Magento\Elasticsearch8', 'Magento\OpenSearch' ] ]; diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php index 4ad7b3797ac..e7e4a3e4905 100644 --- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php +++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php @@ -4331,15 +4331,18 @@ ], [ 'Magento\Elasticsearch6\Block\Adminhtml\System\Config\TestConnection', - 'Magento\Elasticsearch7\Block\Adminhtml\System\Config\TestConnection' + 'Magento\Elasticsearch7\Block\Adminhtml\System\Config\TestConnection', + 'Magento\Elasticsearch8\Block\Adminhtml\System\Config\TestConnection' ], [ 'Magento\Elasticsearch6\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\DefaultResolver', - 'Magento\Elasticsearch7\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\DefaultResolver' + 'Magento\Elasticsearch7\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\DefaultResolver', + 'Magento\Elasticsearch8\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\DefaultResolver' ], [ 'Magento\Elasticsearch6\Model\Client\Elasticsearch', - 'Magento\Elasticsearch7\Model\Client\Elasticsearch' + 'Magento\Elasticsearch7\Model\Client\Elasticsearch', + 'Magento\Elasticsearch8\Model\Client\Elasticsearch' ], ['Magento\Elasticsearch\Test\Unit\Model\DataProvider\Base\SuggestionsTest'], ['Magento\Elasticsearch6\Test\Unit\Model\Client\ElasticsearchTest'], From 24b4587678fd5eaaab66ae3aaedd82b3f84bf539 Mon Sep 17 00:00:00 2001 From: Rajesh Kumar <glo71317@adobe.com> Date: Tue, 28 Jan 2025 14:14:38 +0530 Subject: [PATCH 03/30] AC-13818::Make ES8 to be default for 2.4.8 instead of ES7 --- .../Magento/Elasticsearch8/Model/Client/Elasticsearch.php | 3 +-- .../Test/Unit/Model/Client/ElasticsearchTest.php | 3 +-- .../dependency_test/whitelist/redundant_dependencies_ce.php | 6 ------ .../extension_dependencies_test/allowed_dependencies/ce.php | 4 ++-- 4 files changed, 4 insertions(+), 12 deletions(-) diff --git a/app/code/Magento/Elasticsearch8/Model/Client/Elasticsearch.php b/app/code/Magento/Elasticsearch8/Model/Client/Elasticsearch.php index 8e8492cd217..970860ffd61 100644 --- a/app/code/Magento/Elasticsearch8/Model/Client/Elasticsearch.php +++ b/app/code/Magento/Elasticsearch8/Model/Client/Elasticsearch.php @@ -78,9 +78,8 @@ public function __construct( } $this->clientOptions = $options; $this->fieldsMappingPreprocessors = $fieldsMappingPreprocessors; - // phpstan:ignore "File has calls static method. (phpStaticMethodCalls)" $this->dynamicTemplatesProvider = $dynamicTemplatesProvider ?: ObjectManager::getInstance() - ->get(DynamicTemplatesProvider::class); + ->get(DynamicTemplatesProvider::class); /** @phpstan-ignore-line */ } /** diff --git a/app/code/Magento/Elasticsearch8/Test/Unit/Model/Client/ElasticsearchTest.php b/app/code/Magento/Elasticsearch8/Test/Unit/Model/Client/ElasticsearchTest.php index f266911a4b2..aa4daf7b984 100644 --- a/app/code/Magento/Elasticsearch8/Test/Unit/Model/Client/ElasticsearchTest.php +++ b/app/code/Magento/Elasticsearch8/Test/Unit/Model/Client/ElasticsearchTest.php @@ -60,8 +60,7 @@ class ElasticsearchTest extends TestCase */ protected function setUp(): void { - // phpstan:ignore "File has calls static method. (phpStaticMethodCalls)" - BypassFinals::enable(); + BypassFinals::enable(); /** @phpstan-ignore-line */ $this->elasticsearchClientMock = $this->getMockBuilder(Client::class) /** @phpstan-ignore-line */ ->onlyMethods( [ diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/_files/dependency_test/whitelist/redundant_dependencies_ce.php b/dev/tests/static/testsuite/Magento/Test/Integrity/_files/dependency_test/whitelist/redundant_dependencies_ce.php index 42056d3bb20..009dc16df46 100644 --- a/dev/tests/static/testsuite/Magento/Test/Integrity/_files/dependency_test/whitelist/redundant_dependencies_ce.php +++ b/dev/tests/static/testsuite/Magento/Test/Integrity/_files/dependency_test/whitelist/redundant_dependencies_ce.php @@ -6,12 +6,6 @@ declare(strict_types=1); return [ - 'Magento\Elasticsearch' => [ - 'magento/elasticsearch' => 'magento/elasticsearch', - ], - 'Magento\Elasticsearch7' => [ - 'magento/elasticsearch' => 'magento/elasticsearch', - ], 'Magento\Captcha' => [ 'magento/laminas-db' => 'magento/laminas-db', ] diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/_files/extension_dependencies_test/allowed_dependencies/ce.php b/dev/tests/static/testsuite/Magento/Test/Integrity/_files/extension_dependencies_test/allowed_dependencies/ce.php index 5e50d629abe..84e8af7ee10 100644 --- a/dev/tests/static/testsuite/Magento/Test/Integrity/_files/extension_dependencies_test/allowed_dependencies/ce.php +++ b/dev/tests/static/testsuite/Magento/Test/Integrity/_files/extension_dependencies_test/allowed_dependencies/ce.php @@ -1,7 +1,7 @@ <?php /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. + * Copyright 2022 Adobe + * All Rights Reserved. */ declare(strict_types=1); From 04b9d679ea13d0acd4f52ea372cfab5a5c910d0a Mon Sep 17 00:00:00 2001 From: Rajesh Kumar <glo71317@adobe.com> Date: Mon, 3 Feb 2025 15:35:12 +0530 Subject: [PATCH 04/30] AC-13818::Make ES8 to be default for 2.4.8 instead of ES7 --- app/code/Magento/Elasticsearch/composer.json | 2 +- app/code/Magento/Elasticsearch8/Model/Client/Elasticsearch.php | 1 + .../Elasticsearch8/Test/Unit/Model/Client/ElasticsearchTest.php | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Elasticsearch/composer.json b/app/code/Magento/Elasticsearch/composer.json index 2b9b6fa2569..26f357d7608 100644 --- a/app/code/Magento/Elasticsearch/composer.json +++ b/app/code/Magento/Elasticsearch/composer.json @@ -12,7 +12,7 @@ "magento/module-store": "*", "magento/module-catalog-inventory": "*", "magento/framework": "*", - "magento/elasticsearch": "^1.0.0" + "elasticsearch/elasticsearch": "^8.15" }, "suggest": { "magento/module-config": "*" diff --git a/app/code/Magento/Elasticsearch8/Model/Client/Elasticsearch.php b/app/code/Magento/Elasticsearch8/Model/Client/Elasticsearch.php index 970860ffd61..24a7cc79bce 100644 --- a/app/code/Magento/Elasticsearch8/Model/Client/Elasticsearch.php +++ b/app/code/Magento/Elasticsearch8/Model/Client/Elasticsearch.php @@ -19,6 +19,7 @@ * Elasticsearch client * @deprecated Elasticsearch8 is no longer supported by Adobe * @see this class will be responsible for ES8 only + * phpstan:ignore "File has calls static method. (phpStaticMethodCalls)" */ class Elasticsearch implements ClientInterface { diff --git a/app/code/Magento/Elasticsearch8/Test/Unit/Model/Client/ElasticsearchTest.php b/app/code/Magento/Elasticsearch8/Test/Unit/Model/Client/ElasticsearchTest.php index aa4daf7b984..a5d388edebe 100644 --- a/app/code/Magento/Elasticsearch8/Test/Unit/Model/Client/ElasticsearchTest.php +++ b/app/code/Magento/Elasticsearch8/Test/Unit/Model/Client/ElasticsearchTest.php @@ -27,6 +27,7 @@ * Class ElasticsearchTest to test Elasticsearch 8 * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * phpstan:ignore "File has calls static method. (phpStaticMethodCalls)" */ class ElasticsearchTest extends TestCase { From bea3a94ebaeed70c67cbb8c562ff161fc77f66e0 Mon Sep 17 00:00:00 2001 From: Rajesh Kumar <glo71317@adobe.com> Date: Mon, 3 Feb 2025 17:44:32 +0530 Subject: [PATCH 05/30] AC-13818::Make ES8 to be default for 2.4.8 instead of ES7 --- .../Model/Client/Elasticsearch.php | 3 +- .../Unit/Model/Client/ElasticsearchTest.php | 60 +++++++++---------- 2 files changed, 31 insertions(+), 32 deletions(-) diff --git a/app/code/Magento/Elasticsearch8/Model/Client/Elasticsearch.php b/app/code/Magento/Elasticsearch8/Model/Client/Elasticsearch.php index 24a7cc79bce..ed47ffaf2d9 100644 --- a/app/code/Magento/Elasticsearch8/Model/Client/Elasticsearch.php +++ b/app/code/Magento/Elasticsearch8/Model/Client/Elasticsearch.php @@ -19,7 +19,6 @@ * Elasticsearch client * @deprecated Elasticsearch8 is no longer supported by Adobe * @see this class will be responsible for ES8 only - * phpstan:ignore "File has calls static method. (phpStaticMethodCalls)" */ class Elasticsearch implements ClientInterface { @@ -80,7 +79,7 @@ public function __construct( $this->clientOptions = $options; $this->fieldsMappingPreprocessors = $fieldsMappingPreprocessors; $this->dynamicTemplatesProvider = $dynamicTemplatesProvider ?: ObjectManager::getInstance() - ->get(DynamicTemplatesProvider::class); /** @phpstan-ignore-line */ + ->get(DynamicTemplatesProvider::class); } /** diff --git a/app/code/Magento/Elasticsearch8/Test/Unit/Model/Client/ElasticsearchTest.php b/app/code/Magento/Elasticsearch8/Test/Unit/Model/Client/ElasticsearchTest.php index a5d388edebe..853ca85a243 100644 --- a/app/code/Magento/Elasticsearch8/Test/Unit/Model/Client/ElasticsearchTest.php +++ b/app/code/Magento/Elasticsearch8/Test/Unit/Model/Client/ElasticsearchTest.php @@ -3,6 +3,7 @@ * Copyright 2025 Adobe * All Rights Reserved. */ + declare(strict_types=1); namespace Magento\Elasticsearch8\Test\Unit\Model\Client; @@ -27,7 +28,6 @@ * Class ElasticsearchTest to test Elasticsearch 8 * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) - * phpstan:ignore "File has calls static method. (phpStaticMethodCalls)" */ class ElasticsearchTest extends TestCase { @@ -61,43 +61,43 @@ class ElasticsearchTest extends TestCase */ protected function setUp(): void { - BypassFinals::enable(); /** @phpstan-ignore-line */ + BypassFinals::enable(); $this->elasticsearchClientMock = $this->getMockBuilder(Client::class) /** @phpstan-ignore-line */ - ->onlyMethods( - [ - 'indices', - 'ping', - 'bulk', - 'search', - 'scroll', - 'info', - ] - ) + ->onlyMethods( + [ + 'indices', + 'ping', + 'bulk', + 'search', + 'scroll', + 'info', + ] + ) ->disableOriginalConstructor() ->getMock(); $this->indicesMock = $this->getMockBuilder(Indices::class) /** @phpstan-ignore-line */ - ->onlyMethods( - [ - 'exists', - 'getSettings', - 'create', - 'delete', - 'putMapping', - 'getMapping', - 'stats', - 'updateAliases', - 'existsAlias', - 'getAlias', - ] - ) + ->onlyMethods( + [ + 'exists', + 'getSettings', + 'create', + 'delete', + 'putMapping', + 'getMapping', + 'stats', + 'updateAliases', + 'existsAlias', + 'getAlias', + ] + ) ->addMethods(['deleteMapping']) ->disableOriginalConstructor() ->getMock(); $this->elasticsearchResponse = $this->getMockBuilder(ElasticsearchResponse::class) /** @phpstan-ignore-line */ - ->onlyMethods([ - 'asBool', - 'asArray', - ]) + ->onlyMethods([ + 'asBool', + 'asArray', + ]) ->getMock(); $this->elasticsearchClientMock->expects($this->any()) ->method('indices') From fef856a63a05e33d33f18a3cc0a67f33709c99d9 Mon Sep 17 00:00:00 2001 From: Rajesh Kumar <glo71317@adobe.com> Date: Tue, 4 Feb 2025 17:12:49 +0530 Subject: [PATCH 06/30] AC-13818::Make ES8 to be default for 2.4.8 instead of ES7 --- app/code/Magento/Elasticsearch8/etc/di.xml | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/app/code/Magento/Elasticsearch8/etc/di.xml b/app/code/Magento/Elasticsearch8/etc/di.xml index 42c8289c314..2a22f6f4657 100644 --- a/app/code/Magento/Elasticsearch8/etc/di.xml +++ b/app/code/Magento/Elasticsearch8/etc/di.xml @@ -6,7 +6,6 @@ */ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> - <preference for="Magento\Elasticsearch\Model\Adapter\Elasticsearch" type="Magento\Elasticsearch8\Model\Adapter\Elasticsearch"/> <type name="Magento\Elasticsearch\Model\Config"> <arguments> <argument name="engineList" xsi:type="array"> @@ -15,22 +14,6 @@ </arguments> </type> - <type name="Magento\Elasticsearch\Model\Adapter\Elasticsearch"> - <arguments> - <argument name="responseErrorExceptionList" xsi:type="array"> - <item name="clientResponseException" xsi:type="string">Elastic\Elasticsearch\Exception\ClientResponseException</item> - </argument> - </arguments> - </type> - - <type name="Magento\Elasticsearch\Model\DataProvider\Base\Suggestions"> - <arguments> - <argument name="responseErrorExceptionList" xsi:type="array"> - <item name="clientResponseException" xsi:type="string">Elastic\Elasticsearch\Exception\ClientResponseException</item> - </argument> - </arguments> - </type> - <type name="Magento\Search\Model\Adminhtml\System\Config\Source\Engine"> <arguments> <argument name="engines" xsi:type="array"> From c0ecda4bc4a05906a225bd28d420849fd5e26dc3 Mon Sep 17 00:00:00 2001 From: Rajesh Kumar <glo71317@adobe.com> Date: Wed, 5 Feb 2025 15:15:02 +0530 Subject: [PATCH 07/30] AC-13818::Make ES8 to be default for 2.4.8 instead of ES7 --- app/code/Magento/Elasticsearch8/composer.json | 3 --- app/code/Magento/OpenSearch/composer.json | 8 +------- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/app/code/Magento/Elasticsearch8/composer.json b/app/code/Magento/Elasticsearch8/composer.json index 4d0a45f98ec..bf95e56564e 100644 --- a/app/code/Magento/Elasticsearch8/composer.json +++ b/app/code/Magento/Elasticsearch8/composer.json @@ -13,9 +13,6 @@ "suggest": { "magento/module-config": "*" }, - "replace": { - "magento/module-elasticsearch-7": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", diff --git a/app/code/Magento/OpenSearch/composer.json b/app/code/Magento/OpenSearch/composer.json index 5ca8928f7c0..39b5645c1d0 100644 --- a/app/code/Magento/OpenSearch/composer.json +++ b/app/code/Magento/OpenSearch/composer.json @@ -1,12 +1,6 @@ { "name": "magento/module-open-search", "description": "N/A", - "repositories": [ - { - "type": "vcs", - "url": "git@github.com:djadobe16/opensearch-php.git" - } - ], "require": { "php": "~8.2.0||~8.3.0||~8.4.0", "magento/framework": "*", @@ -15,7 +9,7 @@ "magento/module-elasticsearch": "*", "magento/module-search": "*", "magento/module-config": "*", - "opensearch-project/opensearch-php": "dev-php84-support" + "opensearch-project/opensearch-php": "^2.3" }, "type": "magento2-module", "license": [ From e4287c3f6b93260d2ef5d4ddb69d65b2d949f1da Mon Sep 17 00:00:00 2001 From: Rajesh Kumar <glo71317@adobe.com> Date: Fri, 7 Feb 2025 13:26:00 +0530 Subject: [PATCH 08/30] AC-13818::Make ES8 to be default for 2.4.8 instead of ES7 --- app/code/Magento/AdvancedSearch/README.md | 2 +- .../view/adminhtml/web/js/search-engine-comment.js | 2 +- .../ChooseElasticSearchAsSearchEngineActionGroup.xml | 4 ++-- .../Model/SearchEngineVersionReader.php | 2 +- .../Magento/Elasticsearch/Controller/QuickSearchTest.php | 1 - .../Elasticsearch/Model/Indexer/IndexHandlerTest.php | 2 +- .../Elasticsearch/Model/Indexer/ReindexAllTest.php | 2 +- .../Magento/Elasticsearch/SearchAdapter/AdapterTest.php | 2 +- .../extension_conflicts/ce.php | 1 - .../Magento/Test/Legacy/_files/obsolete_classes.php | 8 -------- phpserver/README.md | 2 +- setup/src/Magento/Setup/Model/SearchConfigOptionsList.php | 5 ++--- .../Setup/Test/Unit/Model/SearchConfigOptionsListTest.php | 7 +++---- .../Magento/Setup/Test/Unit/Model/SearchConfigTest.php | 4 ++-- 14 files changed, 16 insertions(+), 28 deletions(-) diff --git a/app/code/Magento/AdvancedSearch/README.md b/app/code/Magento/AdvancedSearch/README.md index bfb217b97cb..d73a8c211d6 100644 --- a/app/code/Magento/AdvancedSearch/README.md +++ b/app/code/Magento/AdvancedSearch/README.md @@ -7,7 +7,7 @@ The Magento_AdvancedSearch module introduces advanced search functionality and p Before disabling or uninstalling this module, note that the following modules depends on this module: - Magento_Elasticsearch -- Magento_Elasticsearch7 +- Magento_Elasticsearch8 For information about module installation in Magento 2, see [Enable or disable modules](https://experienceleague.adobe.com/docs/commerce-operations/installation-guide/tutorials/manage-modules.html). diff --git a/app/code/Magento/CatalogSearch/view/adminhtml/web/js/search-engine-comment.js b/app/code/Magento/CatalogSearch/view/adminhtml/web/js/search-engine-comment.js index ec02bb0eb79..859649a8ecc 100644 --- a/app/code/Magento/CatalogSearch/view/adminhtml/web/js/search-engine-comment.js +++ b/app/code/Magento/CatalogSearch/view/adminhtml/web/js/search-engine-comment.js @@ -17,7 +17,7 @@ require([ 'It is recommended to use OpenSearch as a search engine instead.'), updateCommentText = () => { const engineValue = engineField.val(), - newCommentText = ['elasticsearch7', 'elasticsearch8'].includes(engineValue) ? + newCommentText = ['elasticsearch8'].includes(engineValue) ? unsupportedText : defaultText; if (commentContainer.text() !== newCommentText) { diff --git a/app/code/Magento/Config/Test/Mftf/ActionGroup/ChooseElasticSearchAsSearchEngineActionGroup.xml b/app/code/Magento/Config/Test/Mftf/ActionGroup/ChooseElasticSearchAsSearchEngineActionGroup.xml index 1b5549b7fb0..7347b474bca 100644 --- a/app/code/Magento/Config/Test/Mftf/ActionGroup/ChooseElasticSearchAsSearchEngineActionGroup.xml +++ b/app/code/Magento/Config/Test/Mftf/ActionGroup/ChooseElasticSearchAsSearchEngineActionGroup.xml @@ -10,7 +10,7 @@ xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> <actionGroup name="ChooseElasticSearchAsSearchEngineActionGroup"> <annotations> - <description>Goes to the 'Configuration' page for 'Catalog'. Sets the 'Search Engine' to 'elasticsearch7'. Clicks on the Save button. PLEASE NOTE: The value is Hardcoded.</description> + <description>Goes to the 'Configuration' page for 'Catalog'. Sets the 'Search Engine' to 'elasticsearch8'. Clicks on the Save button. PLEASE NOTE: The value is Hardcoded.</description> </annotations> <amOnPage url="{{AdminCatalogSearchConfigurationPage.url}}" stepKey="configureSearchEngine"/> @@ -19,7 +19,7 @@ <conditionalClick selector="{{AdminCatalogSearchConfigurationSection.catalogSearchTab}}" dependentSelector="{{AdminCatalogSearchConfigurationSection.checkIfCatalogSearchTabExpand}}" visible="true" stepKey="expandCatalogSearchTab"/> <waitForElementVisible selector="{{AdminCatalogSearchConfigurationSection.searchEngine}}" stepKey="waitForDropdownToBeVisible"/> <uncheckOption selector="{{AdminCatalogSearchConfigurationSection.searchEngineDefaultSystemValue}}" stepKey="uncheckUseSystemValue"/> - <selectOption selector="{{AdminCatalogSearchConfigurationSection.searchEngine}}" userInput="Elasticsearch 7" stepKey="chooseES5"/> + <selectOption selector="{{AdminCatalogSearchConfigurationSection.searchEngine}}" userInput="Elasticsearch 8" stepKey="chooseES5"/> <!--<scrollTo selector="{{AdminCatalogSearchConfigurationSection.catalogSearchTab}}" stepKey="scrollToCatalogSearchTab2"/>--> <!--<click selector="{{AdminCatalogSearchConfigurationSection.catalogSearchTab}}" stepKey="collapseCatalogSearchTab"/>--> <click selector="{{ContentManagementSection.Save}}" stepKey="saveConfiguration"/> diff --git a/dev/tests/integration/_files/Magento/TestModuleCatalogSearch/Model/SearchEngineVersionReader.php b/dev/tests/integration/_files/Magento/TestModuleCatalogSearch/Model/SearchEngineVersionReader.php index b565caae4e3..5b3bf26a306 100644 --- a/dev/tests/integration/_files/Magento/TestModuleCatalogSearch/Model/SearchEngineVersionReader.php +++ b/dev/tests/integration/_files/Magento/TestModuleCatalogSearch/Model/SearchEngineVersionReader.php @@ -24,7 +24,7 @@ class SearchEngineVersionReader private $versionInfo; /** - * Returns full search engine version e.g. 'elasticsearch7' + * Returns full search engine version e.g. 'elasticsearch8' * * @return string */ diff --git a/dev/tests/integration/testsuite/Magento/Elasticsearch/Controller/QuickSearchTest.php b/dev/tests/integration/testsuite/Magento/Elasticsearch/Controller/QuickSearchTest.php index 90e06e577f8..775877b6647 100644 --- a/dev/tests/integration/testsuite/Magento/Elasticsearch/Controller/QuickSearchTest.php +++ b/dev/tests/integration/testsuite/Magento/Elasticsearch/Controller/QuickSearchTest.php @@ -47,7 +47,6 @@ public function testQuickSearchWithImprovedPriceRangeCalculation() * * @magentoAppArea frontend * @magentoDbIsolation disabled - * @magentoConfigFixture current_store catalog/search/elasticsearch7_minimum_should_match 100% * @magentoConfigFixture current_store catalog/search/elasticsearch8_minimum_should_match 100% * @magentoConfigFixture current_store catalog/search/opensearch_minimum_should_match 100% * @magentoDataFixture Magento/Elasticsearch/_files/products_for_search.php diff --git a/dev/tests/integration/testsuite/Magento/Elasticsearch/Model/Indexer/IndexHandlerTest.php b/dev/tests/integration/testsuite/Magento/Elasticsearch/Model/Indexer/IndexHandlerTest.php index 25e36bdfc8c..9ac265fa858 100644 --- a/dev/tests/integration/testsuite/Magento/Elasticsearch/Model/Indexer/IndexHandlerTest.php +++ b/dev/tests/integration/testsuite/Magento/Elasticsearch/Model/Indexer/IndexHandlerTest.php @@ -24,7 +24,7 @@ /** * Important: Please make sure that each integration test file works with unique search index. In order to * achieve this, use @magentoConfigFixture to pass unique value for index_prefix for every test - * method. E.g. '@magentoConfigFixture current_store catalog/search/elasticsearch7_index_prefix indexerhandlertest' + * method. E.g. '@magentoConfigFixture current_store catalog/search/elasticsearch8_index_prefix indexerhandlertest' * * @magentoDbIsolation disabled * @magentoDataFixture Magento/Elasticsearch/_files/indexer.php diff --git a/dev/tests/integration/testsuite/Magento/Elasticsearch/Model/Indexer/ReindexAllTest.php b/dev/tests/integration/testsuite/Magento/Elasticsearch/Model/Indexer/ReindexAllTest.php index dd906bb7d18..0c064f91199 100644 --- a/dev/tests/integration/testsuite/Magento/Elasticsearch/Model/Indexer/ReindexAllTest.php +++ b/dev/tests/integration/testsuite/Magento/Elasticsearch/Model/Indexer/ReindexAllTest.php @@ -22,7 +22,7 @@ * Important: Please make sure that each integration test file works with unique search index. In order to * achieve this, use @magentoConfigFixture to pass unique value for index_prefix for every test * method. - * E.g. '@magentoConfigFixture current_store catalog/search/elasticsearch7_index_prefix indexerhandlertest_configurable' + * E.g. '@magentoConfigFixture current_store catalog/search/elasticsearch8_index_prefix indexerhandlertest_configurable' * * @magentoDbIsolation disabled * @magentoAppIsolation enabled diff --git a/dev/tests/integration/testsuite/Magento/Elasticsearch/SearchAdapter/AdapterTest.php b/dev/tests/integration/testsuite/Magento/Elasticsearch/SearchAdapter/AdapterTest.php index 76c466defe6..75226fe6ee3 100644 --- a/dev/tests/integration/testsuite/Magento/Elasticsearch/SearchAdapter/AdapterTest.php +++ b/dev/tests/integration/testsuite/Magento/Elasticsearch/SearchAdapter/AdapterTest.php @@ -21,7 +21,7 @@ * * Important: Please make sure that each integration test file works with unique elastic search index. In order to * achieve this, use @ magentoConfigFixture to pass unique value for index_prefix for every test - * method. E.g. '@ magentoConfigFixture current_store catalog/search/elasticsearch7_index_prefix adaptertest' + * method. E.g. '@magentoConfigFixture current_store catalog/search/elasticsearch8_index_prefix adaptertest' * * In ElasticSearch, a reindex is required if the test includes a new data fixture with new items to search, see * testAdvancedSearchDateField(). diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/_files/extension_dependencies_test/extension_conflicts/ce.php b/dev/tests/static/testsuite/Magento/Test/Integrity/_files/extension_dependencies_test/extension_conflicts/ce.php index 81ee07df3a2..51ccc75b73e 100644 --- a/dev/tests/static/testsuite/Magento/Test/Integrity/_files/extension_dependencies_test/extension_conflicts/ce.php +++ b/dev/tests/static/testsuite/Magento/Test/Integrity/_files/extension_dependencies_test/extension_conflicts/ce.php @@ -10,7 +10,6 @@ // so core modules must not be dependent on them 'Magento\LiveSearch' => [ 'Magento\Elasticsearch', - 'Magento\Elasticsearch7', 'Magento\Elasticsearch8', 'Magento\OpenSearch' ], diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php index e7e4a3e4905..12626884700 100644 --- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php +++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php @@ -4330,23 +4330,15 @@ 'Magento\Elasticsearch\Test\Unit\SearchAdapter\Query\Builder\MatchQueryTest' ], [ - 'Magento\Elasticsearch6\Block\Adminhtml\System\Config\TestConnection', - 'Magento\Elasticsearch7\Block\Adminhtml\System\Config\TestConnection', 'Magento\Elasticsearch8\Block\Adminhtml\System\Config\TestConnection' ], [ - 'Magento\Elasticsearch6\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\DefaultResolver', - 'Magento\Elasticsearch7\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\DefaultResolver', 'Magento\Elasticsearch8\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\DefaultResolver' ], [ - 'Magento\Elasticsearch6\Model\Client\Elasticsearch', - 'Magento\Elasticsearch7\Model\Client\Elasticsearch', 'Magento\Elasticsearch8\Model\Client\Elasticsearch' ], ['Magento\Elasticsearch\Test\Unit\Model\DataProvider\Base\SuggestionsTest'], - ['Magento\Elasticsearch6\Test\Unit\Model\Client\ElasticsearchTest'], - ['Magento\Elasticsearch6\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\DefaultResolverTest'], ['Zend_Measure_Length', 'Magento\Framework\Measure\Length'], ['Zend_Measure_Weight', 'Magento\Framework\Measure\Weight'], ]; diff --git a/phpserver/README.md b/phpserver/README.md index 51235b458b7..5795d6bed88 100644 --- a/phpserver/README.md +++ b/phpserver/README.md @@ -22,7 +22,7 @@ php bin/magento setup:install --base-url=http://127.0.0.1:8082 \ --admin-firstname=Magento --admin-lastname=User --admin-email=user@example.com \ --admin-user=admin --admin-password=admin123 --language=en_US \ --currency=USD --timezone=America/Chicago --use-rewrites=1 \ ---search-engine=elasticsearch7 --elasticsearch-host=es-host.example.com --elasticsearch-port=9200 +--search-engine=elasticsearch8 --elasticsearch-host=es-host.example.com --elasticsearch-port=9200 ``` Note: By default, Magento creates a random Admin URI for you. Make sure to write this value down because it's how you access the Magento Admin later. For example: `http://127.0.0.1:8082/index.php/admin_1vpn01`. diff --git a/setup/src/Magento/Setup/Model/SearchConfigOptionsList.php b/setup/src/Magento/Setup/Model/SearchConfigOptionsList.php index d8815041c12..c4d11448a83 100644 --- a/setup/src/Magento/Setup/Model/SearchConfigOptionsList.php +++ b/setup/src/Magento/Setup/Model/SearchConfigOptionsList.php @@ -1,7 +1,7 @@ <?php /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. + * Copyright 2020 Adobe + * All Rights Reserved. */ declare(strict_types=1); @@ -149,7 +149,6 @@ public function getOptionsList(): array public function getAvailableSearchEngineList(): array { return [ - 'elasticsearch7' => 'Elasticsearch 7.x (deprecated)', 'elasticsearch8' => 'Elasticsearch 8.x (deprecated)', 'opensearch' => 'OpenSearch' ]; diff --git a/setup/src/Magento/Setup/Test/Unit/Model/SearchConfigOptionsListTest.php b/setup/src/Magento/Setup/Test/Unit/Model/SearchConfigOptionsListTest.php index 0fbc63c721b..636cd0e88a8 100644 --- a/setup/src/Magento/Setup/Test/Unit/Model/SearchConfigOptionsListTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Model/SearchConfigOptionsListTest.php @@ -1,7 +1,7 @@ <?php /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. + * Copyright 2020 Adobe + * All Rights Reserved. */ declare(strict_types=1); @@ -36,8 +36,7 @@ public function testGetOptionsList() $this->assertEquals('search-engine', $optionsList[0]->getName()); $selectOptions = $optionsList[0]->getSelectOptions(); - $this->assertCount(3, $selectOptions); - $this->assertContains('elasticsearch7', $selectOptions); + $this->assertCount(2, $selectOptions); $this->assertContains('elasticsearch8', $selectOptions); $this->assertContains('opensearch', $selectOptions); diff --git a/setup/src/Magento/Setup/Test/Unit/Model/SearchConfigTest.php b/setup/src/Magento/Setup/Test/Unit/Model/SearchConfigTest.php index a13d7c73a08..0d04d6a049f 100644 --- a/setup/src/Magento/Setup/Test/Unit/Model/SearchConfigTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Model/SearchConfigTest.php @@ -141,7 +141,7 @@ public static function installInputDataProvider() 'base-url-secure' => null, 'use-secure-admin' => null, 'admin-use-security-key' => null, - 'search-engine' => 'elasticsearch7', + 'search-engine' => 'elasticsearch8', 'elasticsearch-host' => 'localhost', 'elasticsearch-port' => '9200', 'elasticsearch-enable-auth' => false, @@ -150,7 +150,7 @@ public static function installInputDataProvider() 'no-interaction' => false, ], 'searchInput' => [ - 'search-engine' => 'elasticsearch7', + 'search-engine' => 'elasticsearch8', 'elasticsearch-host' => 'localhost', 'elasticsearch-port' => '9200', 'elasticsearch-enable-auth' => false, From 945556707dd5487c42c0ea1bafaa1d0032e74ca2 Mon Sep 17 00:00:00 2001 From: Rajesh Kumar <glo71317@adobe.com> Date: Mon, 10 Feb 2025 18:19:23 +0530 Subject: [PATCH 09/30] AC-13818::Make ES8 to be default for 2.4.8 instead of ES7 --- app/code/Magento/Elasticsearch8/etc/config.xml | 1 - app/code/Magento/Elasticsearch8/etc/di.xml | 17 +++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Elasticsearch8/etc/config.xml b/app/code/Magento/Elasticsearch8/etc/config.xml index 81b83e6dd31..a29334bcb67 100644 --- a/app/code/Magento/Elasticsearch8/etc/config.xml +++ b/app/code/Magento/Elasticsearch8/etc/config.xml @@ -9,7 +9,6 @@ <default> <catalog> <search> - <engine>elasticsearch8</engine> <elasticsearch8_server_hostname>localhost</elasticsearch8_server_hostname> <elasticsearch8_server_port>9200</elasticsearch8_server_port> <elasticsearch8_index_prefix>magento2</elasticsearch8_index_prefix> diff --git a/app/code/Magento/Elasticsearch8/etc/di.xml b/app/code/Magento/Elasticsearch8/etc/di.xml index 2a22f6f4657..42c8289c314 100644 --- a/app/code/Magento/Elasticsearch8/etc/di.xml +++ b/app/code/Magento/Elasticsearch8/etc/di.xml @@ -6,6 +6,7 @@ */ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> + <preference for="Magento\Elasticsearch\Model\Adapter\Elasticsearch" type="Magento\Elasticsearch8\Model\Adapter\Elasticsearch"/> <type name="Magento\Elasticsearch\Model\Config"> <arguments> <argument name="engineList" xsi:type="array"> @@ -14,6 +15,22 @@ </arguments> </type> + <type name="Magento\Elasticsearch\Model\Adapter\Elasticsearch"> + <arguments> + <argument name="responseErrorExceptionList" xsi:type="array"> + <item name="clientResponseException" xsi:type="string">Elastic\Elasticsearch\Exception\ClientResponseException</item> + </argument> + </arguments> + </type> + + <type name="Magento\Elasticsearch\Model\DataProvider\Base\Suggestions"> + <arguments> + <argument name="responseErrorExceptionList" xsi:type="array"> + <item name="clientResponseException" xsi:type="string">Elastic\Elasticsearch\Exception\ClientResponseException</item> + </argument> + </arguments> + </type> + <type name="Magento\Search\Model\Adminhtml\System\Config\Source\Engine"> <arguments> <argument name="engines" xsi:type="array"> From cf67d883b48b214722eaf2abc4b1f85c40665f4e Mon Sep 17 00:00:00 2001 From: Rajesh Kumar <glo71317@adobe.com> Date: Mon, 10 Feb 2025 22:14:42 +0530 Subject: [PATCH 10/30] AC-13818::Make ES8 to be default for 2.4.8 instead of ES7 --- .../ChooseElasticSearchAsSearchEngineActionGroup.xml | 6 +++--- .../Model/SearchEngineVersionReader.php | 4 ++-- .../Magento/Elasticsearch/Controller/QuickSearchTest.php | 4 ++-- .../Elasticsearch/Model/Indexer/IndexHandlerTest.php | 4 ++-- .../Magento/Elasticsearch/Model/Indexer/ReindexAllTest.php | 4 ++-- .../Magento/Elasticsearch/SearchAdapter/AdapterTest.php | 4 ++-- .../extension_dependencies_test/extension_conflicts/ce.php | 4 ++-- .../Magento/Test/Legacy/_files/obsolete_classes.php | 3 --- .../src/Magento/Setup/Test/Unit/Model/SearchConfigTest.php | 4 ++-- 9 files changed, 17 insertions(+), 20 deletions(-) diff --git a/app/code/Magento/Config/Test/Mftf/ActionGroup/ChooseElasticSearchAsSearchEngineActionGroup.xml b/app/code/Magento/Config/Test/Mftf/ActionGroup/ChooseElasticSearchAsSearchEngineActionGroup.xml index 7347b474bca..87702185cb1 100644 --- a/app/code/Magento/Config/Test/Mftf/ActionGroup/ChooseElasticSearchAsSearchEngineActionGroup.xml +++ b/app/code/Magento/Config/Test/Mftf/ActionGroup/ChooseElasticSearchAsSearchEngineActionGroup.xml @@ -1,9 +1,9 @@ <?xml version="1.0" encoding="UTF-8"?> <!-- /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ + * Copyright 2022 Adobe + * All Rights Reserved. + */ --> <actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" diff --git a/dev/tests/integration/_files/Magento/TestModuleCatalogSearch/Model/SearchEngineVersionReader.php b/dev/tests/integration/_files/Magento/TestModuleCatalogSearch/Model/SearchEngineVersionReader.php index 5b3bf26a306..21efb1be9d6 100644 --- a/dev/tests/integration/_files/Magento/TestModuleCatalogSearch/Model/SearchEngineVersionReader.php +++ b/dev/tests/integration/_files/Magento/TestModuleCatalogSearch/Model/SearchEngineVersionReader.php @@ -1,7 +1,7 @@ <?php /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. + * Copyright 2022 Adobe + * All Rights Reserved. */ declare(strict_types=1); diff --git a/dev/tests/integration/testsuite/Magento/Elasticsearch/Controller/QuickSearchTest.php b/dev/tests/integration/testsuite/Magento/Elasticsearch/Controller/QuickSearchTest.php index 775877b6647..f41b06c7806 100644 --- a/dev/tests/integration/testsuite/Magento/Elasticsearch/Controller/QuickSearchTest.php +++ b/dev/tests/integration/testsuite/Magento/Elasticsearch/Controller/QuickSearchTest.php @@ -1,7 +1,7 @@ <?php /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. + * Copyright 2020 Adobe + * All Rights Reserved. */ declare(strict_types=1); diff --git a/dev/tests/integration/testsuite/Magento/Elasticsearch/Model/Indexer/IndexHandlerTest.php b/dev/tests/integration/testsuite/Magento/Elasticsearch/Model/Indexer/IndexHandlerTest.php index 9ac265fa858..c5967ae5c1b 100644 --- a/dev/tests/integration/testsuite/Magento/Elasticsearch/Model/Indexer/IndexHandlerTest.php +++ b/dev/tests/integration/testsuite/Magento/Elasticsearch/Model/Indexer/IndexHandlerTest.php @@ -1,7 +1,7 @@ <?php /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. + * Copyright 2015 Adobe + * All Rights Reserved. */ namespace Magento\Elasticsearch\Model\Indexer; diff --git a/dev/tests/integration/testsuite/Magento/Elasticsearch/Model/Indexer/ReindexAllTest.php b/dev/tests/integration/testsuite/Magento/Elasticsearch/Model/Indexer/ReindexAllTest.php index 0c064f91199..da71a7c6244 100644 --- a/dev/tests/integration/testsuite/Magento/Elasticsearch/Model/Indexer/ReindexAllTest.php +++ b/dev/tests/integration/testsuite/Magento/Elasticsearch/Model/Indexer/ReindexAllTest.php @@ -1,7 +1,7 @@ <?php /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. + * Copyright 2017 Adobe + * All Rights Reserved. */ namespace Magento\Elasticsearch\Model\Indexer; diff --git a/dev/tests/integration/testsuite/Magento/Elasticsearch/SearchAdapter/AdapterTest.php b/dev/tests/integration/testsuite/Magento/Elasticsearch/SearchAdapter/AdapterTest.php index 75226fe6ee3..282b3ff992f 100644 --- a/dev/tests/integration/testsuite/Magento/Elasticsearch/SearchAdapter/AdapterTest.php +++ b/dev/tests/integration/testsuite/Magento/Elasticsearch/SearchAdapter/AdapterTest.php @@ -1,7 +1,7 @@ <?php /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. + * Copyright 2015 Adobe + * All Rights Reserved. */ namespace Magento\Elasticsearch\SearchAdapter; diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/_files/extension_dependencies_test/extension_conflicts/ce.php b/dev/tests/static/testsuite/Magento/Test/Integrity/_files/extension_dependencies_test/extension_conflicts/ce.php index 51ccc75b73e..c1c2fc275ee 100644 --- a/dev/tests/static/testsuite/Magento/Test/Integrity/_files/extension_dependencies_test/extension_conflicts/ce.php +++ b/dev/tests/static/testsuite/Magento/Test/Integrity/_files/extension_dependencies_test/extension_conflicts/ce.php @@ -1,7 +1,7 @@ <?php /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. + * Copyright 2022 Adobe + * All Rights Reserved. */ declare(strict_types=1); diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php index 12626884700..f1943587585 100644 --- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php +++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php @@ -4332,9 +4332,6 @@ [ 'Magento\Elasticsearch8\Block\Adminhtml\System\Config\TestConnection' ], - [ - 'Magento\Elasticsearch8\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\DefaultResolver' - ], [ 'Magento\Elasticsearch8\Model\Client\Elasticsearch' ], diff --git a/setup/src/Magento/Setup/Test/Unit/Model/SearchConfigTest.php b/setup/src/Magento/Setup/Test/Unit/Model/SearchConfigTest.php index 0d04d6a049f..196cca61b9d 100644 --- a/setup/src/Magento/Setup/Test/Unit/Model/SearchConfigTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Model/SearchConfigTest.php @@ -1,7 +1,7 @@ <?php /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. + * Copyright 2020 Adobe + * All Rights Reserved. */ declare(strict_types=1); From 994a7b2dab525a0cefc48c53e788dbfc1263ede8 Mon Sep 17 00:00:00 2001 From: Rajesh Kumar <glo71317@adobe.com> Date: Tue, 11 Feb 2025 12:19:12 +0530 Subject: [PATCH 11/30] AC-13818::Make ES8 to be default for 2.4.8 instead of ES7 --- .../Magento/Test/Legacy/_files/obsolete_classes.php | 6 ------ 1 file changed, 6 deletions(-) diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php index f1943587585..89353a71688 100644 --- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php +++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php @@ -4329,12 +4329,6 @@ 'Magento\Elasticsearch\Test\Unit\SearchAdapter\Query\Builder\MatchTest', 'Magento\Elasticsearch\Test\Unit\SearchAdapter\Query\Builder\MatchQueryTest' ], - [ - 'Magento\Elasticsearch8\Block\Adminhtml\System\Config\TestConnection' - ], - [ - 'Magento\Elasticsearch8\Model\Client\Elasticsearch' - ], ['Magento\Elasticsearch\Test\Unit\Model\DataProvider\Base\SuggestionsTest'], ['Zend_Measure_Length', 'Magento\Framework\Measure\Length'], ['Zend_Measure_Weight', 'Magento\Framework\Measure\Weight'], From 0bfdca3b3de937d8a0b2bd0eb757a0be662c7a01 Mon Sep 17 00:00:00 2001 From: Rajesh Kumar <glo71317@adobe.com> Date: Mon, 17 Feb 2025 15:07:26 +0530 Subject: [PATCH 12/30] AC-13818::Make ES8 to be default for 2.4.8 instead of ES7 --- composer.lock | 140 +++++++++++++++++++++++++------------------------- 1 file changed, 70 insertions(+), 70 deletions(-) diff --git a/composer.lock b/composer.lock index e94d5ca3504..e1adaed5181 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "4d21655c4853f2c9d7569fab31210516", + "content-hash": "7330c52f917fe6c3801295c19b69e717", "packages": [ { "name": "aws/aws-crt-php", @@ -1238,6 +1238,73 @@ }, "time": "2023-01-13T18:47:58+00:00" }, + { + "name": "egulias/email-validator", + "version": "4.0.3", + "source": { + "type": "git", + "url": "https://github.com/egulias/EmailValidator.git", + "reference": "b115554301161fa21467629f1e1391c1936de517" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/b115554301161fa21467629f1e1391c1936de517", + "reference": "b115554301161fa21467629f1e1391c1936de517", + "shasum": "" + }, + "require": { + "doctrine/lexer": "^2.0 || ^3.0", + "php": ">=8.1", + "symfony/polyfill-intl-idn": "^1.26" + }, + "require-dev": { + "phpunit/phpunit": "^10.2", + "vimeo/psalm": "^5.12" + }, + "suggest": { + "ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Egulias\\EmailValidator\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eduardo Gulias Davis" + } + ], + "description": "A library for validating emails against several RFCs", + "homepage": "https://github.com/egulias/EmailValidator", + "keywords": [ + "email", + "emailvalidation", + "emailvalidator", + "validation", + "validator" + ], + "support": { + "issues": "https://github.com/egulias/EmailValidator/issues", + "source": "https://github.com/egulias/EmailValidator/tree/4.0.3" + }, + "funding": [ + { + "url": "https://github.com/egulias", + "type": "github" + } + ], + "time": "2024-12-27T00:36:43+00:00" + }, { "name": "elastic/transport", "version": "v8.10.0", @@ -1354,73 +1421,6 @@ }, "time": "2024-12-18T11:00:27+00:00" }, - { - "name": "egulias/email-validator", - "version": "4.0.3", - "source": { - "type": "git", - "url": "https://github.com/egulias/EmailValidator.git", - "reference": "b115554301161fa21467629f1e1391c1936de517" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/b115554301161fa21467629f1e1391c1936de517", - "reference": "b115554301161fa21467629f1e1391c1936de517", - "shasum": "" - }, - "require": { - "doctrine/lexer": "^2.0 || ^3.0", - "php": ">=8.1", - "symfony/polyfill-intl-idn": "^1.26" - }, - "require-dev": { - "phpunit/phpunit": "^10.2", - "vimeo/psalm": "^5.12" - }, - "suggest": { - "ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Egulias\\EmailValidator\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eduardo Gulias Davis" - } - ], - "description": "A library for validating emails against several RFCs", - "homepage": "https://github.com/egulias/EmailValidator", - "keywords": [ - "email", - "emailvalidation", - "emailvalidator", - "validation", - "validator" - ], - "support": { - "issues": "https://github.com/egulias/EmailValidator/issues", - "source": "https://github.com/egulias/EmailValidator/tree/4.0.3" - }, - "funding": [ - { - "url": "https://github.com/egulias", - "type": "github" - } - ], - "time": "2024-12-27T00:36:43+00:00" - }, { "name": "ezimuel/guzzlestreams", "version": "3.1.0", @@ -14874,6 +14874,6 @@ "ext-zip": "*", "lib-libxml": "*" }, - "platform-dev": [], - "plugin-api-version": "2.2.0" + "platform-dev": {}, + "plugin-api-version": "2.6.0" } From 2e259e1bc6006485f93af1903cf6ecdc4ac5424d Mon Sep 17 00:00:00 2001 From: Deepak <deepaksoni@adobe.com> Date: Wed, 19 Feb 2025 13:43:15 +0530 Subject: [PATCH 13/30] LYNX-689: Guest user confirmation url is redirected to order status page as it is missing orderRef --- .../Model/CancelOrderGuest.php | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/OrderCancellationGraphQl/Model/CancelOrderGuest.php b/app/code/Magento/OrderCancellationGraphQl/Model/CancelOrderGuest.php index 1682da49015..8294472e330 100644 --- a/app/code/Magento/OrderCancellationGraphQl/Model/CancelOrderGuest.php +++ b/app/code/Magento/OrderCancellationGraphQl/Model/CancelOrderGuest.php @@ -14,6 +14,7 @@ use Magento\Sales\Api\OrderRepositoryInterface; use Magento\Sales\Model\Order; use Magento\SalesGraphQl\Model\Formatter\Order as OrderFormatter; +use Magento\SalesGraphQl\Model\Order\Token; class CancelOrderGuest { @@ -25,13 +26,15 @@ class CancelOrderGuest * @param ConfirmationKeySender $confirmationKeySender * @param GetConfirmationKey $confirmationKey * @param Uid $idEncoder + * @param Token $token */ public function __construct( private readonly OrderFormatter $orderFormatter, private readonly OrderRepositoryInterface $orderRepository, private readonly ConfirmationKeySender $confirmationKeySender, private readonly GetConfirmationKey $confirmationKey, - private readonly Uid $idEncoder + private readonly Uid $idEncoder, + private readonly Token $token ) { } @@ -72,7 +75,12 @@ private function sendConfirmationKeyEmail(Order $order, string $reason): void $order, [ 'order_id' => $this->idEncoder->encode((string)$order->getEntityId()), - 'confirmation_key' => $this->confirmationKey->execute($order, $reason) + 'confirmation_key' => $this->confirmationKey->execute($order, $reason), + 'orderRef' => $this->token->encrypt( + $order->getIncrementId(), + $order->getBillingAddress()->getEmail(), + $order->getBillingAddress()->getLastname() + ) ] ); From ee0f50834186355ac6750d5c2aa8fe2b25f037b2 Mon Sep 17 00:00:00 2001 From: Deepak <deepaksoni@adobe.com> Date: Wed, 19 Feb 2025 15:21:31 +0530 Subject: [PATCH 14/30] LYNX-687: Action parameter added for return and cancel confirmation links --- .../OrderCancellationGraphQl/Model/CancelOrderGuest.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/OrderCancellationGraphQl/Model/CancelOrderGuest.php b/app/code/Magento/OrderCancellationGraphQl/Model/CancelOrderGuest.php index 8294472e330..7aacaaa4f49 100644 --- a/app/code/Magento/OrderCancellationGraphQl/Model/CancelOrderGuest.php +++ b/app/code/Magento/OrderCancellationGraphQl/Model/CancelOrderGuest.php @@ -80,7 +80,8 @@ private function sendConfirmationKeyEmail(Order $order, string $reason): void $order->getIncrementId(), $order->getBillingAddress()->getEmail(), $order->getBillingAddress()->getLastname() - ) + ), + 'action' => 'cancel' ] ); From 1844ae81d80a0f02566f0c196ca2331813d07e17 Mon Sep 17 00:00:00 2001 From: Deepak <deepaksoni@adobe.com> Date: Wed, 19 Feb 2025 18:24:03 +0530 Subject: [PATCH 15/30] LYNX-753: Deliver Terms & Conditions configuration in StoreConfig --- .../Magento/QuoteGraphQl/etc/graphql/di.xml | 5 +- .../Magento/QuoteGraphQl/etc/schema.graphqls | 1 + .../GraphQl/Quote/StoreConfigResolverTest.php | 74 ++++++++++--------- 3 files changed, 42 insertions(+), 38 deletions(-) diff --git a/app/code/Magento/QuoteGraphQl/etc/graphql/di.xml b/app/code/Magento/QuoteGraphQl/etc/graphql/di.xml index b9bb066a22e..6a1bef49748 100644 --- a/app/code/Magento/QuoteGraphQl/etc/graphql/di.xml +++ b/app/code/Magento/QuoteGraphQl/etc/graphql/di.xml @@ -1,8 +1,8 @@ <?xml version="1.0"?> <!-- /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. + * Copyright 2025 Adobe + * All Rights Reserved. */ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> @@ -72,6 +72,7 @@ <item name="cart_expires_in_days" xsi:type="string">checkout/cart/delete_quote_after</item> <item name="grouped_product_image" xsi:type="string">checkout/cart/grouped_product_image</item> <item name="configurable_product_image" xsi:type="string">checkout/cart/configurable_product_image</item> + <item name="is_checkout_agreements_enabled" xsi:type="string">checkout/options/enable_agreements</item> </argument> </arguments> </type> diff --git a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls index 061f36df3a3..cd6c8c50d5a 100644 --- a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls +++ b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls @@ -533,6 +533,7 @@ type StoreConfig { cart_expires_in_days: Int @doc(description: "checkout/cart/delete_quote_after: quote lifetime in days.") grouped_product_image: ProductImageThumbnail! @doc(description: "checkout/cart/grouped_product_image: which image to use for grouped products.") @resolver(class: "Magento\\QuoteGraphQl\\Model\\Resolver\\StoreConfig") configurable_product_image: ProductImageThumbnail! @doc(description: "checkout/cart/configurable_product_image: which image to use for configurable products.") @resolver(class: "Magento\\QuoteGraphQl\\Model\\Resolver\\StoreConfig") + is_checkout_agreements_enabled: Boolean! @doc(description: "Configuration data from checkout/options/enable_agreements") } enum ProductImageThumbnail { diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/StoreConfigResolverTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/StoreConfigResolverTest.php index 9e4650ebe18..88ce4c7cb19 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/StoreConfigResolverTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/StoreConfigResolverTest.php @@ -1,7 +1,7 @@ <?php /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. + * Copyright 2025 Adobe + * All Rights Reserved. */ declare(strict_types=1); @@ -41,47 +41,49 @@ class StoreConfigResolverTest extends GraphQlAbstract 'default' ), ConfigFixture('checkout/cart/grouped_product_image', 'parent', ScopeInterface::SCOPE_STORE, 'default'), - ConfigFixture('checkout/cart/configurable_product_image', 'itself', ScopeInterface::SCOPE_STORE, 'default') + ConfigFixture('checkout/cart/configurable_product_image', 'itself', ScopeInterface::SCOPE_STORE, 'default'), + ConfigFixture('checkout/options/enable_agreements', true, ScopeInterface::SCOPE_STORE, 'default') ] public function testGetStoreConfig(): void { - $query - = <<<QUERY -{ - storeConfig { - is_guest_checkout_enabled, - is_one_page_checkout_enabled, - max_items_in_order_summary, - cart_summary_display_quantity, - minicart_display, - minicart_max_items, - cart_expires_in_days, - grouped_product_image, - configurable_product_image - } -} -QUERY; - $response = $this->graphQlQuery($query); - $this->assertArrayHasKey('storeConfig', $response); - $this->validateStoreConfig($response['storeConfig']); + $this->assertEquals([ + 'storeConfig' => [ + 'is_guest_checkout_enabled' => true, + 'is_one_page_checkout_enabled' => true, + 'max_items_in_order_summary' => self::MAX_ITEMS_TO_DISPLAY, + 'cart_summary_display_quantity' => self::CART_SUMMARY_DISPLAY_TOTAL, + 'minicart_display' => true, + 'minicart_max_items' => self::MINICART_MAX_ITEMS, + 'cart_expires_in_days' => self::CART_EXPIRES_IN_DAYS, + 'grouped_product_image' => 'PARENT', + 'configurable_product_image' => 'ITSELF', + 'is_checkout_agreements_enabled' => true + ] + ], $this->graphQlQuery($this->getStoreConfigQuery())); } /** - * Validate Store Config Data + * Generates storeConfig query * - * @param array $responseConfig + * @return string */ - private function validateStoreConfig( - array $responseConfig, - ): void { - $this->assertTrue($responseConfig['is_guest_checkout_enabled']); - $this->assertTrue($responseConfig['is_one_page_checkout_enabled']); - $this->assertEquals(self::MAX_ITEMS_TO_DISPLAY, $responseConfig['max_items_in_order_summary']); - $this->assertEquals(self::CART_SUMMARY_DISPLAY_TOTAL, $responseConfig['cart_summary_display_quantity']); - $this->assertTrue($responseConfig['minicart_display']); - $this->assertEquals(self::MINICART_MAX_ITEMS, $responseConfig['minicart_max_items']); - $this->assertEquals(self::CART_EXPIRES_IN_DAYS, $responseConfig['cart_expires_in_days']); - $this->assertEquals('PARENT', $responseConfig['grouped_product_image']); - $this->assertEquals('ITSELF', $responseConfig['configurable_product_image']); + private function getStoreConfigQuery(): string + { + return <<<QUERY + { + storeConfig { + is_guest_checkout_enabled + is_one_page_checkout_enabled + max_items_in_order_summary + cart_summary_display_quantity + minicart_display + minicart_max_items + cart_expires_in_days + grouped_product_image + configurable_product_image + is_checkout_agreements_enabled + } + } + QUERY; } } From 44231f79767646ce547cb5b690c1a9a1b912ebaf Mon Sep 17 00:00:00 2001 From: Shantanu Dasgupta <108055538+cod40403@users.noreply.github.com> Date: Wed, 19 Feb 2025 18:54:39 +0530 Subject: [PATCH 16/30] LYNX-644 Update date format returned by OrderStatusChangeDate resolver --- .../Model/Resolver/OrderStatusChangeDate.php | 25 +++++------ .../Sales/OrderStatusChangeDateTest.php | 41 ++++++++++--------- 2 files changed, 35 insertions(+), 31 deletions(-) diff --git a/app/code/Magento/SalesGraphQl/Model/Resolver/OrderStatusChangeDate.php b/app/code/Magento/SalesGraphQl/Model/Resolver/OrderStatusChangeDate.php index f1022eb13e7..b22f94c69cc 100644 --- a/app/code/Magento/SalesGraphQl/Model/Resolver/OrderStatusChangeDate.php +++ b/app/code/Magento/SalesGraphQl/Model/Resolver/OrderStatusChangeDate.php @@ -11,10 +11,8 @@ use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Query\ResolverInterface; -use Magento\Framework\Stdlib\DateTime; -use Magento\Framework\Stdlib\DateTime\TimezoneInterface; use Magento\Sales\Model\Order; -use \Magento\Sales\Model\ResourceModel\SalesOrderStatusChangeHistory; +use Magento\Sales\Model\ResourceModel\SalesOrderStatusChangeHistory; /** * Resolver for the OrderStatusChangeDate in CustomerOrder @@ -22,27 +20,30 @@ class OrderStatusChangeDate implements ResolverInterface { /** + * OrderStatusChangeDate Constructor + * * @param SalesOrderStatusChangeHistory $salesOrderStatusChangeHistory - * @param TimezoneInterface $localeDate */ public function __construct( private readonly SalesOrderStatusChangeHistory $salesOrderStatusChangeHistory, - private readonly TimezoneInterface $localeDate, ) { } /** * @inheritDoc */ - public function resolve(Field $field, $context, ResolveInfo $info, ?array $value = null, ?array $args = null): string - { + public function resolve( + Field $field, + $context, + ResolveInfo $info, + ?array $value = null, + ?array $args = null + ): string { if (!isset($value['model']) || !($value['model'] instanceof Order)) { throw new LocalizedException(__('"model" value should be specified')); } - $order = $value['model']; - $latestStatus = $this->salesOrderStatusChangeHistory->getLatestStatus((int)$order->getId()); - return ($latestStatus) - ? $this->localeDate->convertConfigTimeToUtc($latestStatus['created_at'], DateTime::DATE_PHP_FORMAT) - : ''; + $latestStatus = $this->salesOrderStatusChangeHistory->getLatestStatus((int)$value['model']->getId()); + + return $latestStatus['created_at'] ?? ''; } } diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Sales/OrderStatusChangeDateTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Sales/OrderStatusChangeDateTest.php index 25a4709fa65..657b8a032b4 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Sales/OrderStatusChangeDateTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Sales/OrderStatusChangeDateTest.php @@ -8,8 +8,10 @@ namespace Magento\GraphQl\Sales; use Magento\Checkout\Test\Fixture\SetGuestEmail as SetGuestEmailFixture; -use Magento\Framework\Stdlib\DateTime; -use Magento\Framework\Stdlib\DateTime\TimezoneInterface; +use Magento\Framework\Exception\AlreadyExistsException; +use Magento\Framework\Exception\InputException; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\Exception\NoSuchEntityException; use Magento\Quote\Test\Fixture\GuestCart; use Magento\Sales\Api\Data\OrderInterface; use Magento\Sales\Model\Order; @@ -69,16 +71,17 @@ public function testOrderStatusChangeDateWithStatusChange(): void * @param OrderInterface $order * @param string $status * @return void + * @throws AlreadyExistsException + * @throws InputException + * @throws LocalizedException + * @throws NoSuchEntityException */ private function assertOrderStatusChangeDate(OrderInterface $order, string $status): void { - $orderRepo = Bootstrap::getObjectManager()->get(OrderRepository::class); - $timeZone = Bootstrap::getObjectManager()->get(TimezoneInterface::class); - //Update order status $order->setStatus($status); $order->setState($status); - $orderRepo->save($order); + Bootstrap::getObjectManager()->get(OrderRepository::class)->save($order); $updatedGuestOrder = $this->graphQlMutation($this->getQuery( $order->getIncrementId(), @@ -90,7 +93,7 @@ private function assertOrderStatusChangeDate(OrderInterface $order, string $stat $updatedGuestOrder['guestOrder']['status'] ); self::assertEquals( - $timeZone->convertConfigTimeToUtc($order->getCreatedAt(), DateTime::DATE_PHP_FORMAT), + $order->getUpdatedAt(), $updatedGuestOrder['guestOrder']['order_status_change_date'] ); } @@ -106,17 +109,17 @@ private function assertOrderStatusChangeDate(OrderInterface $order, string $stat private function getQuery(string $number, string $email, string $lastname): string { return <<<QUERY -{ - guestOrder(input: { - number: "{$number}", - email: "{$email}", - lastname: "{$lastname}" - }) { - created_at - status - order_status_change_date - } -} -QUERY; + { + guestOrder(input: { + number: "{$number}", + email: "{$email}", + lastname: "{$lastname}" + }) { + created_at + status + order_status_change_date + } + } + QUERY; } } From 401229c41a5798a2b1dfe9f6f467cd9bb279a74f Mon Sep 17 00:00:00 2001 From: Deepak Soni <deepaksoni@adobe.com> Date: Wed, 19 Feb 2025 21:26:44 +0530 Subject: [PATCH 17/30] Update dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/StoreConfigResolverTest.php Co-authored-by: Shantanu Dasgupta <108055538+cod40403@users.noreply.github.com> --- .../GraphQl/Quote/StoreConfigResolverTest.php | 31 ++++++++++--------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/StoreConfigResolverTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/StoreConfigResolverTest.php index 88ce4c7cb19..d2c0165a185 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/StoreConfigResolverTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/StoreConfigResolverTest.php @@ -46,20 +46,23 @@ class StoreConfigResolverTest extends GraphQlAbstract ] public function testGetStoreConfig(): void { - $this->assertEquals([ - 'storeConfig' => [ - 'is_guest_checkout_enabled' => true, - 'is_one_page_checkout_enabled' => true, - 'max_items_in_order_summary' => self::MAX_ITEMS_TO_DISPLAY, - 'cart_summary_display_quantity' => self::CART_SUMMARY_DISPLAY_TOTAL, - 'minicart_display' => true, - 'minicart_max_items' => self::MINICART_MAX_ITEMS, - 'cart_expires_in_days' => self::CART_EXPIRES_IN_DAYS, - 'grouped_product_image' => 'PARENT', - 'configurable_product_image' => 'ITSELF', - 'is_checkout_agreements_enabled' => true - ] - ], $this->graphQlQuery($this->getStoreConfigQuery())); + $this->assertEquals( + [ + 'storeConfig' => [ + 'is_guest_checkout_enabled' => true, + 'is_one_page_checkout_enabled' => true, + 'max_items_in_order_summary' => self::MAX_ITEMS_TO_DISPLAY, + 'cart_summary_display_quantity' => self::CART_SUMMARY_DISPLAY_TOTAL, + 'minicart_display' => true, + 'minicart_max_items' => self::MINICART_MAX_ITEMS, + 'cart_expires_in_days' => self::CART_EXPIRES_IN_DAYS, + 'grouped_product_image' => 'PARENT', + 'configurable_product_image' => 'ITSELF', + 'is_checkout_agreements_enabled' => true, + ], + ], + $this->graphQlQuery($this->getStoreConfigQuery()) + ); } /** From aff8b7ec7f7a2c8f37d65ce66d446cc298d1bafc Mon Sep 17 00:00:00 2001 From: Dnyaneshwar Jambhulkar <pru34625@adobe.com> Date: Thu, 20 Feb 2025 01:17:23 +0530 Subject: [PATCH 18/30] Debug elastcisearch8 connection --- app/code/Magento/Elasticsearch/Setup/Validator.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/code/Magento/Elasticsearch/Setup/Validator.php b/app/code/Magento/Elasticsearch/Setup/Validator.php index bfeebfa62bd..7cd6fa1cb9a 100644 --- a/app/code/Magento/Elasticsearch/Setup/Validator.php +++ b/app/code/Magento/Elasticsearch/Setup/Validator.php @@ -38,6 +38,11 @@ public function validate(): array $errors = []; try { $client = $this->clientResolver->create(); + echo "Check elasticsearch8 server up or not with command line\n"; + shell_exec("curl localhost:9200/"); + + $output = shell_exec('netstat -tuln'); + echo "<pre>$output</pre>"; if (!$client->testConnection()) { $errors[] = 'Could not validate a connection to Elasticsearch.' . ' Verify that the Elasticsearch host and port are configured correctly.'; From 0f7807bd2082392f0e129cee9c62cb9e98a0d1b0 Mon Sep 17 00:00:00 2001 From: Deepak <deepaksoni@adobe.com> Date: Thu, 20 Feb 2025 11:30:59 +0530 Subject: [PATCH 19/30] Test case updated --- .../Magento/GraphQl/Quote/StoreConfigResolverTest.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/StoreConfigResolverTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/StoreConfigResolverTest.php index d2c0165a185..c2ffecb1a61 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/StoreConfigResolverTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/StoreConfigResolverTest.php @@ -47,7 +47,7 @@ class StoreConfigResolverTest extends GraphQlAbstract public function testGetStoreConfig(): void { $this->assertEquals( - [ + [ 'storeConfig' => [ 'is_guest_checkout_enabled' => true, 'is_one_page_checkout_enabled' => true, @@ -60,9 +60,9 @@ public function testGetStoreConfig(): void 'configurable_product_image' => 'ITSELF', 'is_checkout_agreements_enabled' => true, ], - ], - $this->graphQlQuery($this->getStoreConfigQuery()) - ); + ], + $this->graphQlQuery($this->getStoreConfigQuery()) + ); } /** From f8ed9a654fe400b66037f4fa1c584efd0831e4bd Mon Sep 17 00:00:00 2001 From: Deepak <deepaksoni@adobe.com> Date: Thu, 20 Feb 2025 12:29:59 +0530 Subject: [PATCH 20/30] LYNX-697: Deliver subtotals fields in placeOrder mutation --- .../Model/Resolver/OrderTotal.php | 6 +- .../Magento/SalesGraphQl/etc/schema.graphqls | 4 +- .../CustomerOrdersSubtotalFieldsTest.php | 137 ++++++++++++++++++ 3 files changed, 144 insertions(+), 3 deletions(-) create mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/Sales/CustomerOrdersSubtotalFieldsTest.php diff --git a/app/code/Magento/SalesGraphQl/Model/Resolver/OrderTotal.php b/app/code/Magento/SalesGraphQl/Model/Resolver/OrderTotal.php index f604613126f..4b3671f6269 100644 --- a/app/code/Magento/SalesGraphQl/Model/Resolver/OrderTotal.php +++ b/app/code/Magento/SalesGraphQl/Model/Resolver/OrderTotal.php @@ -1,7 +1,7 @@ <?php /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. + * Copyright 2025 Adobe + * All Rights Reserved. */ declare(strict_types=1); @@ -41,6 +41,8 @@ public function resolve( 'base_grand_total' => ['value' => $order->getBaseGrandTotal(), 'currency' => $baseCurrency], 'grand_total' => ['value' => $order->getGrandTotal(), 'currency' => $currency], 'subtotal' => ['value' => $order->getSubtotal(), 'currency' => $currency], + 'subtotal_incl_tax' => ['value' => $order->getSubtotalInclTax(), 'currency' => $currency], + 'subtotal_excl_tax' => ['value' => $order->getSubtotal(), 'currency' => $currency], 'total_tax' => ['value' => $order->getTaxAmount(), 'currency' => $currency], 'taxes' => $this->getAppliedTaxesDetails($order), 'discounts' => $this->getDiscountDetails($order), diff --git a/app/code/Magento/SalesGraphQl/etc/schema.graphqls b/app/code/Magento/SalesGraphQl/etc/schema.graphqls index 2e048d71aa6..ec33e4986d5 100644 --- a/app/code/Magento/SalesGraphQl/etc/schema.graphqls +++ b/app/code/Magento/SalesGraphQl/etc/schema.graphqls @@ -160,7 +160,7 @@ type TaxItem @doc(description: "Contains tax item details.") { } type OrderTotal @doc(description: "Contains details about the sales total amounts used to calculate the final price.") { - subtotal: Money! @doc(description: "The subtotal of the order, excluding shipping, discounts, and taxes.") + subtotal: Money! @doc(description: "The subtotal of the order, excluding shipping, discounts, and taxes.") @deprecated(reason: "Use subtotal_excl_tax field instead") discounts: [Discount] @doc(description: "The applied discounts to the order.") total_tax: Money! @doc(description: "The amount of tax applied to the order.") taxes: [TaxItem] @doc(description: "The order tax details.") @@ -168,6 +168,8 @@ type OrderTotal @doc(description: "Contains details about the sales total amount base_grand_total: Money! @doc(description: "The final base grand total amount in the base currency.") total_shipping: Money! @doc(description: "The shipping amount for the order.") shipping_handling: ShippingHandling @doc(description: "Details about the shipping and handling costs for the order.") + subtotal_incl_tax: Money! @doc(description: "The subtotal of the order, including taxes.") + subtotal_excl_tax: Money! @doc(description: "The subtotal of the order, excluding taxes.") } type Invoice @doc(description: "Contains invoice details.") { diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Sales/CustomerOrdersSubtotalFieldsTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Sales/CustomerOrdersSubtotalFieldsTest.php new file mode 100644 index 00000000000..2ffd32d7fe3 --- /dev/null +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Sales/CustomerOrdersSubtotalFieldsTest.php @@ -0,0 +1,137 @@ +<?php +/** + * Copyright 2025 Adobe + * All Rights Reserved. + */ +declare(strict_types=1); + +namespace Magento\GraphQl\Sales; + +use Exception; +use Magento\Catalog\Test\Fixture\Product as ProductFixture; +use Magento\Checkout\Test\Fixture\PlaceOrder as PlaceOrderFixture; +use Magento\Checkout\Test\Fixture\SetBillingAddress as SetBillingAddressFixture; +use Magento\Checkout\Test\Fixture\SetDeliveryMethod as SetDeliveryMethodFixture; +use Magento\Checkout\Test\Fixture\SetPaymentMethod as SetPaymentMethodFixture; +use Magento\Checkout\Test\Fixture\SetShippingAddress as SetShippingAddressFixture; +use Magento\Customer\Test\Fixture\Customer as CustomerFixture; +use Magento\Framework\Exception\AuthenticationException; +use Magento\Framework\Exception\LocalizedException; +use Magento\Integration\Api\CustomerTokenServiceInterface; +use Magento\Quote\Test\Fixture\AddProductToCart as AddProductToCartFixture; +use Magento\Quote\Test\Fixture\CustomerCart as CustomerCartFixture; +use Magento\Sales\Api\Data\OrderInterface; +use Magento\TestFramework\Fixture\DataFixture; +use Magento\TestFramework\Fixture\DataFixtureStorage; +use Magento\TestFramework\Fixture\DataFixtureStorageManager; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\TestCase\GraphQlAbstract; + +/** + * Test coverage for customerOrders.item.total.subtotal_incl_tax and subtotal_excl_tax + */ +class CustomerOrdersSubtotalFieldsTest extends GraphQlAbstract +{ + /** + * @var CustomerTokenServiceInterface + */ + private $customerTokenService; + + /** + * @var DataFixtureStorage + */ + private $fixtures; + + /** + * @return void + * @throws LocalizedException + */ + protected function setUp(): void + { + $this->customerTokenService = Bootstrap::getObjectManager()->get(CustomerTokenServiceInterface::class); + $this->fixtures = Bootstrap::getObjectManager()->get(DataFixtureStorageManager::class)->getStorage(); + } + + /** + * @throws Exception + */ + #[ + DataFixture(ProductFixture::class, as: 'product'), + DataFixture(CustomerFixture::class, as: 'customer'), + DataFixture(CustomerCartFixture::class, ['customer_id' => '$customer.id$'], as: 'quote'), + DataFixture(AddProductToCartFixture::class, ['cart_id' => '$quote.id$', 'product_id' => '$product.id$']), + DataFixture(SetBillingAddressFixture::class, ['cart_id' => '$quote.id$']), + DataFixture(SetShippingAddressFixture::class, ['cart_id' => '$quote.id$']), + DataFixture(SetDeliveryMethodFixture::class, ['cart_id' => '$quote.id$']), + DataFixture(SetPaymentMethodFixture::class, ['cart_id' => '$quote.id$']), + DataFixture(PlaceOrderFixture::class, ['cart_id' => '$quote.id$'], 'order') + ] + public function testOrdersSubtotalFields(): void + { + /** @var OrderInterface $order */ + $order = $this->fixtures->get('order'); + + self::assertEquals( + [ + 'customer' => [ + 'orders' => [ + 'items' => [ + [ + 'total' => [ + 'subtotal_incl_tax' => ['value' => $order->getSubtotalInclTax()], + 'subtotal_excl_tax' => ['value' => $order->getSubtotal()] + ] + ] + ] + ] + ] + ], + $this->graphQlQuery( + $this->getCustomerOrdersQuery(), + [], + '', + $this->getCustomerAuthHeaders($this->fixtures->get('customer')->getEmail()) + ) + ); + } + + /** + * Returns the header with customer token for GQL Mutation + * + * @param string $email + * @return array + * @throws AuthenticationException + */ + private function getCustomerAuthHeaders(string $email): array + { + $customerToken = $this->customerTokenService->createCustomerAccessToken($email, 'password'); + return ['Authorization' => 'Bearer ' . $customerToken]; + } + + /** + * Get customer orders query with subtotal fields + * + * @return string + */ + private function getCustomerOrdersQuery(): string + { + return <<<QUERY + query { + customer { + orders { + items { + total { + subtotal_incl_tax { + value + } + subtotal_excl_tax { + value + } + } + } + } + } + } + QUERY; + } +} From fc20c9d8c6034f4f36f58f79fa45a5caa00404e3 Mon Sep 17 00:00:00 2001 From: Shantanu Dasgupta <cod40403@adobe.com> Date: Thu, 20 Feb 2025 13:02:19 +0530 Subject: [PATCH 21/30] LYNX-699 Cannot return null for non-nullable field TaxItem.title on placeOrder GQL --- .../Model/Resolver/OrderTotal.php | 47 ++- .../GraphQl/Sales/PlaceOrderTaxTitleTest.php | 302 ++++++++++++++++++ 2 files changed, 333 insertions(+), 16 deletions(-) create mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/Sales/PlaceOrderTaxTitleTest.php diff --git a/app/code/Magento/SalesGraphQl/Model/Resolver/OrderTotal.php b/app/code/Magento/SalesGraphQl/Model/Resolver/OrderTotal.php index f604613126f..33c7aa15087 100644 --- a/app/code/Magento/SalesGraphQl/Model/Resolver/OrderTotal.php +++ b/app/code/Magento/SalesGraphQl/Model/Resolver/OrderTotal.php @@ -1,23 +1,36 @@ <?php /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. + * Copyright 2025 Adobe + * All Rights Reserved. */ declare(strict_types=1); namespace Magento\SalesGraphQl\Model\Resolver; use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Sales\Api\Data\OrderInterface; +use Magento\Tax\Api\OrderTaxManagementInterface; /** * Resolve order totals taxes and discounts for order */ class OrderTotal implements ResolverInterface { + + /** + * OrderTotal Constructor + * + * @param OrderTaxManagementInterface $orderTaxManagement + */ + public function __construct( + private readonly OrderTaxManagementInterface $orderTaxManagement, + ) { + } + /** * @inheritDoc */ @@ -35,10 +48,12 @@ public function resolve( /** @var OrderInterface $order */ $order = $value['model']; $currency = $order->getOrderCurrencyCode(); - $baseCurrency = $order->getBaseCurrencyCode(); return [ - 'base_grand_total' => ['value' => $order->getBaseGrandTotal(), 'currency' => $baseCurrency], + 'base_grand_total' => [ + 'value' => $order->getBaseGrandTotal(), + 'currency' => $order->getBaseCurrencyCode() + ], 'grand_total' => ['value' => $order->getGrandTotal(), 'currency' => $currency], 'subtotal' => ['value' => $order->getSubtotal(), 'currency' => $currency], 'total_tax' => ['value' => $order->getTaxAmount(), 'currency' => $currency], @@ -70,11 +85,12 @@ public function resolve( * * @param OrderInterface $order * @return array + * @throws NoSuchEntityException */ private function getAllAppliedTaxesOnOrders(OrderInterface $order): array { - $extensionAttributes = $order->getExtensionAttributes(); - $appliedTaxes = $extensionAttributes->getAppliedTaxes() ?? []; + $orderTaxDetails = $this->orderTaxManagement->getOrderTaxDetails($order->getEntityId()); + $appliedTaxes = $orderTaxDetails->getAppliedTaxes(); $allAppliedTaxOnOrders = []; foreach ($appliedTaxes as $taxIndex => $appliedTaxesData) { $allAppliedTaxOnOrders[$taxIndex] = [ @@ -83,6 +99,7 @@ private function getAllAppliedTaxesOnOrders(OrderInterface $order): array 'amount' => $appliedTaxesData->getDataByKey('amount'), ]; } + return $allAppliedTaxOnOrders; } @@ -91,23 +108,21 @@ private function getAllAppliedTaxesOnOrders(OrderInterface $order): array * * @param OrderInterface $order * @return array + * @throws NoSuchEntityException */ private function getAppliedTaxesDetails(OrderInterface $order): array { - $allAppliedTaxOnOrders = $this->getAllAppliedTaxesOnOrders($order); - $taxes = []; - foreach ($allAppliedTaxOnOrders as $appliedTaxes) { - $appliedTaxesArray = [ + return array_map( + fn($appliedTaxes) => [ 'rate' => $appliedTaxes['percent'] ?? 0, 'title' => $appliedTaxes['title'] ?? null, 'amount' => [ 'value' => $appliedTaxes['amount'] ?? 0, - 'currency' => $order->getOrderCurrencyCode() - ] - ]; - $taxes[] = $appliedTaxesArray; - } - return $taxes; + 'currency' => $order->getOrderCurrencyCode(), + ], + ], + $this->getAllAppliedTaxesOnOrders($order) + ); } /** diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Sales/PlaceOrderTaxTitleTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Sales/PlaceOrderTaxTitleTest.php new file mode 100644 index 00000000000..6eea988e79a --- /dev/null +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Sales/PlaceOrderTaxTitleTest.php @@ -0,0 +1,302 @@ +<?php +/** + * Copyright 2025 Adobe + * All Rights Reserved. + */ +declare(strict_types=1); + +namespace Magento\GraphQl\Sales; + +use Exception; +use Magento\Catalog\Test\Fixture\Product as ProductFixture; +use Magento\Customer\Test\Fixture\Customer as CustomerFixture; +use Magento\Framework\App\ResourceConnection; +use Magento\Framework\Exception\AuthenticationException; +use Magento\Framework\Exception\EmailNotConfirmedException; +use Magento\Integration\Api\CustomerTokenServiceInterface; +use Magento\Quote\Test\Fixture\AddProductToCart as AddProductToCartFixture; +use Magento\Quote\Test\Fixture\CustomerCart as CustomerCartFixture; +use Magento\Quote\Test\Fixture\QuoteIdMask; +use Magento\Tax\Test\Fixture\ProductTaxClass as ProductTaxClassFixture; +use Magento\Tax\Test\Fixture\TaxRate as TaxRateFixture; +use Magento\Tax\Test\Fixture\TaxRule as TaxRuleFixture; +use Magento\TestFramework\Fixture\DataFixture; +use Magento\TestFramework\Fixture\DataFixtureStorage; +use Magento\TestFramework\Fixture\DataFixtureStorageManager; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\TestCase\GraphQlAbstract; + +class PlaceOrderTaxTitleTest extends GraphQlAbstract +{ + /** + * @var DataFixtureStorage + */ + private $fixtures; + + /** + * @var CustomerTokenServiceInterface + */ + private $customerTokenService; + + /** + * @var ResourceConnection + */ + private $resourceConnection; + + /** + * @inheritdoc + */ + protected function setUp(): void + { + $this->fixtures = Bootstrap::getObjectManager()->get(DataFixtureStorageManager::class)->getStorage(); + $this->customerTokenService = Bootstrap::getObjectManager()->get(CustomerTokenServiceInterface::class); + $this->resourceConnection = Bootstrap::getObjectManager()->get(ResourceConnection::class); + } + + /** + * @throws Exception + */ + #[ + DataFixture(ProductTaxClassFixture::class, as: 'product_tax_class'), + DataFixture(TaxRateFixture::class, as: 'rate'), + DataFixture( + TaxRuleFixture::class, + [ + 'customer_tax_class_ids' => [3], + 'product_tax_class_ids' => ['$product_tax_class.classId$'], + 'tax_rate_ids' => ['$rate.id$'] + ], + 'rule' + ), + DataFixture( + ProductFixture::class, + [ + 'custom_attributes' => ['tax_class_id' => '$product_tax_class.classId$'] + ], + 'product' + ), + DataFixture(CustomerFixture::class, as: 'customer'), + DataFixture(CustomerCartFixture::class, ['customer_id' => '$customer.id$'], as: 'quote'), + DataFixture(AddProductToCartFixture::class, ['cart_id' => '$quote.id$', 'product_id' => '$product.id$']), + DataFixture(QuoteIdMask::class, ['cart_id' => '$quote.id$'], 'quoteIdMask'), + ] + public function testTaxTitleOnPlaceOrder(): void + { + $maskedQuoteId = $this->fixtures->get('quoteIdMask')->getMaskedId(); + $headerMap = $this->getCustomerAuthHeaders($this->fixtures->get('customer')->getEmail()); + + //set shipping address to cart (save_in_address_book => true) + $this->graphQlMutation($this->getSetShippingAddressOnCartMutation($maskedQuoteId), [], '', $headerMap); + + //set billing address to cart same as shipping + $this->graphQlMutation($this->getBillingAddressMutationSameAsShipping($maskedQuoteId), [], '', $headerMap); + + //set shipping method on cart + $this->graphQlMutation($this->getShippingMethodMutation($maskedQuoteId), [], '', $headerMap); + + //set payment method on cart + $this->graphQlMutation($this->getPaymentMethodMutation($maskedQuoteId), [], '', $headerMap); + + //place order + $orderResponse = $this->graphQlMutation($this->getPlaceOrderMutation($maskedQuoteId), [], '', $headerMap); + + //assert tax title + self::assertNotNull($orderResponse['placeOrder']['orderV2']['total']['taxes'][0]['title']); + self::assertNotEmpty($orderResponse['placeOrder']['orderV2']['total']['taxes'][0]['title']); + + //Revert order as it is created through mutations and not fixtures + $this->revertOrder($orderResponse['placeOrder']['order']['order_number']); + } + + /** + * Get Set shipping address on cart mutation with save_in_address_book as true + * + * @param string $maskedQuoteId + * @return string + */ + private function getSetShippingAddressOnCartMutation(string $maskedQuoteId) + { + return <<<MUTATION + mutation { + setShippingAddressesOnCart( + input: { + cart_id: "{$maskedQuoteId}" + shipping_addresses: [ + { + address: { + firstname: "John" + lastname: "Doe" + company: "test" + street: ["test", "test"] + city: "New York" + region: "NY" + postcode: "10001" + country_code: "US" + telephone: "9999999999" + save_in_address_book: false + }, + } + ] + } + ) { + cart { + id + shipping_addresses { + firstname + lastname + } + } + } + } + MUTATION; + } + + /** + * Returns GraphQl mutation for (setBillingAddressOnCart) with same_as_shipping: true + * + * @param string $maskedQuoteId + * @return string + */ + private function getBillingAddressMutationSameAsShipping(string $maskedQuoteId): string + { + return <<<MUTATION + mutation { + setBillingAddressOnCart( + input: { + cart_id: "{$maskedQuoteId}", + billing_address: { + same_as_shipping: true + } + } + ) { + cart { + id + shipping_addresses { + firstname + lastname + } + } + } + } + MUTATION; + } + + /** + * Get set shipping method on cart mutation + * + * @param string $maskedQuoteId + * @return string + */ + private function getShippingMethodMutation(string $maskedQuoteId): string + { + return <<<MUTATION + mutation { + setShippingMethodsOnCart( + input: { + cart_id: "{$maskedQuoteId}", + shipping_methods: [ + { + carrier_code: "flatrate" + method_code: "flatrate" + } + ] + } + ) { + cart { + id + } + } + } + MUTATION; + } + + /** + * Get set payment method on cart mutation + * + * @param string $maskedQuoteId + * @return string + */ + private function getPaymentMethodMutation(string $maskedQuoteId): string + { + return <<<MUTATION + mutation { + setPaymentMethodOnCart(input: { + cart_id: "{$maskedQuoteId}" + payment_method: { + code: "checkmo" + } + }) { + cart { + selected_payment_method { + code + title + } + } + } + } + MUTATION; + } + + /** + * Get place order mutation with orderV2 data + * + * @param string $maskedQuoteId + * @return string + */ + private function getPlaceOrderMutation(string $maskedQuoteId): string + { + return <<<MUTATION + mutation { + placeOrder(input: {cart_id: "{$maskedQuoteId}"}) { + order { + order_number + } + orderV2 { + total { + taxes { + amount { + value + currency + } + title + } + } + } + } + } + MUTATION; + } + + /** + * Delete Orders from sales_order and sales_order_grid table + * + * @param string $orderNumber + * @return void + */ + private function revertOrder(string $orderNumber): void + { + $connection = $this->resourceConnection->getConnection(); + $connection->delete( + $this->resourceConnection->getTableName('sales_order'), + ['increment_id = ?' => $orderNumber] + ); + $connection->delete( + $this->resourceConnection->getTableName('sales_order_grid'), + ['increment_id = ?' => $orderNumber] + ); + } + + /** + * Generates token for GQL and returns header with generated token + * + * @param string $customerEmail + * @return array + * @throws AuthenticationException + * @throws EmailNotConfirmedException + */ + private function getCustomerAuthHeaders(string $customerEmail): array + { + $customerToken = $this->customerTokenService->createCustomerAccessToken($customerEmail, 'password'); + return ['Authorization' => 'Bearer ' . $customerToken]; + } +} From 65dc8e496ecddd41656335f4ef224a050ee2e79d Mon Sep 17 00:00:00 2001 From: Dnyaneshwar Jambhulkar <pru34625@adobe.com> Date: Thu, 20 Feb 2025 14:07:15 +0530 Subject: [PATCH 22/30] Debug elastcisearch8 connection --- app/code/Magento/Elasticsearch/Setup/Validator.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Elasticsearch/Setup/Validator.php b/app/code/Magento/Elasticsearch/Setup/Validator.php index 7cd6fa1cb9a..e5f3ae96210 100644 --- a/app/code/Magento/Elasticsearch/Setup/Validator.php +++ b/app/code/Magento/Elasticsearch/Setup/Validator.php @@ -37,12 +37,13 @@ public function validate(): array { $errors = []; try { - $client = $this->clientResolver->create(); echo "Check elasticsearch8 server up or not with command line\n"; shell_exec("curl localhost:9200/"); - + $output = shell_exec('netstat -tuln'); echo "<pre>$output</pre>"; + + $client = $this->clientResolver->create(); if (!$client->testConnection()) { $errors[] = 'Could not validate a connection to Elasticsearch.' . ' Verify that the Elasticsearch host and port are configured correctly.'; From 7954f5dc2baddb982feb1b23b48032fecf9e5064 Mon Sep 17 00:00:00 2001 From: Shantanu Dasgupta <108055538+cod40403@users.noreply.github.com> Date: Thu, 20 Feb 2025 15:06:52 +0530 Subject: [PATCH 23/30] LYNX-699 Apply suggestions from code review Co-authored-by: Deepak Soni <deepaksoni@adobe.com> --- app/code/Magento/SalesGraphQl/Model/Resolver/OrderTotal.php | 4 ++-- .../Magento/GraphQl/Sales/PlaceOrderTaxTitleTest.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/SalesGraphQl/Model/Resolver/OrderTotal.php b/app/code/Magento/SalesGraphQl/Model/Resolver/OrderTotal.php index 33c7aa15087..65b4cf0f8e0 100644 --- a/app/code/Magento/SalesGraphQl/Model/Resolver/OrderTotal.php +++ b/app/code/Magento/SalesGraphQl/Model/Resolver/OrderTotal.php @@ -118,8 +118,8 @@ private function getAppliedTaxesDetails(OrderInterface $order): array 'title' => $appliedTaxes['title'] ?? null, 'amount' => [ 'value' => $appliedTaxes['amount'] ?? 0, - 'currency' => $order->getOrderCurrencyCode(), - ], + 'currency' => $order->getOrderCurrencyCode() + ] ], $this->getAllAppliedTaxesOnOrders($order) ); diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Sales/PlaceOrderTaxTitleTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Sales/PlaceOrderTaxTitleTest.php index 6eea988e79a..c0df287d795 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Sales/PlaceOrderTaxTitleTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Sales/PlaceOrderTaxTitleTest.php @@ -78,7 +78,7 @@ protected function setUp(): void DataFixture(CustomerFixture::class, as: 'customer'), DataFixture(CustomerCartFixture::class, ['customer_id' => '$customer.id$'], as: 'quote'), DataFixture(AddProductToCartFixture::class, ['cart_id' => '$quote.id$', 'product_id' => '$product.id$']), - DataFixture(QuoteIdMask::class, ['cart_id' => '$quote.id$'], 'quoteIdMask'), + DataFixture(QuoteIdMask::class, ['cart_id' => '$quote.id$'], 'quoteIdMask') ] public function testTaxTitleOnPlaceOrder(): void { @@ -114,7 +114,7 @@ public function testTaxTitleOnPlaceOrder(): void * @param string $maskedQuoteId * @return string */ - private function getSetShippingAddressOnCartMutation(string $maskedQuoteId) + private function getSetShippingAddressOnCartMutation(string $maskedQuoteId): string { return <<<MUTATION mutation { From 60c3b6f7d4d85a0e462427d8728bff0114a64296 Mon Sep 17 00:00:00 2001 From: Shantanu Dasgupta <cod40403@adobe.com> Date: Thu, 20 Feb 2025 15:12:06 +0530 Subject: [PATCH 24/30] LYNX-699 Review feedback fixed --- .../Model/Resolver/OrderTotal.php | 14 +++---- .../GraphQl/Sales/PlaceOrderTaxTitleTest.php | 37 ++++++++++++++++--- 2 files changed, 36 insertions(+), 15 deletions(-) diff --git a/app/code/Magento/SalesGraphQl/Model/Resolver/OrderTotal.php b/app/code/Magento/SalesGraphQl/Model/Resolver/OrderTotal.php index 65b4cf0f8e0..175a1acc4a0 100644 --- a/app/code/Magento/SalesGraphQl/Model/Resolver/OrderTotal.php +++ b/app/code/Magento/SalesGraphQl/Model/Resolver/OrderTotal.php @@ -89,18 +89,14 @@ public function resolve( */ private function getAllAppliedTaxesOnOrders(OrderInterface $order): array { - $orderTaxDetails = $this->orderTaxManagement->getOrderTaxDetails($order->getEntityId()); - $appliedTaxes = $orderTaxDetails->getAppliedTaxes(); - $allAppliedTaxOnOrders = []; - foreach ($appliedTaxes as $taxIndex => $appliedTaxesData) { - $allAppliedTaxOnOrders[$taxIndex] = [ + return array_map( + fn($appliedTaxesData) => [ 'title' => $appliedTaxesData->getDataByKey('title'), 'percent' => $appliedTaxesData->getDataByKey('percent'), 'amount' => $appliedTaxesData->getDataByKey('amount'), - ]; - } - - return $allAppliedTaxOnOrders; + ], + $this->orderTaxManagement->getOrderTaxDetails($order->getEntityId())->getAppliedTaxes() + ); } /** diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Sales/PlaceOrderTaxTitleTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Sales/PlaceOrderTaxTitleTest.php index c0df287d795..0ddb2f89fda 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Sales/PlaceOrderTaxTitleTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Sales/PlaceOrderTaxTitleTest.php @@ -83,22 +83,47 @@ protected function setUp(): void public function testTaxTitleOnPlaceOrder(): void { $maskedQuoteId = $this->fixtures->get('quoteIdMask')->getMaskedId(); - $headerMap = $this->getCustomerAuthHeaders($this->fixtures->get('customer')->getEmail()); + $customerAuthHeaders = $this->getCustomerAuthHeaders($this->fixtures->get('customer')->getEmail()); //set shipping address to cart (save_in_address_book => true) - $this->graphQlMutation($this->getSetShippingAddressOnCartMutation($maskedQuoteId), [], '', $headerMap); + $this->graphQlMutation( + $this->getSetShippingAddressOnCartMutation($maskedQuoteId), + [], + '', + $customerAuthHeaders + ); //set billing address to cart same as shipping - $this->graphQlMutation($this->getBillingAddressMutationSameAsShipping($maskedQuoteId), [], '', $headerMap); + $this->graphQlMutation( + $this->getBillingAddressMutationSameAsShipping($maskedQuoteId), + [], + '', + $customerAuthHeaders + ); //set shipping method on cart - $this->graphQlMutation($this->getShippingMethodMutation($maskedQuoteId), [], '', $headerMap); + $this->graphQlMutation( + $this->getShippingMethodMutation($maskedQuoteId), + [], + '', + $customerAuthHeaders + ); //set payment method on cart - $this->graphQlMutation($this->getPaymentMethodMutation($maskedQuoteId), [], '', $headerMap); + $this->graphQlMutation( + $this->getPaymentMethodMutation($maskedQuoteId), + [], + '', + $customerAuthHeaders + ); //place order - $orderResponse = $this->graphQlMutation($this->getPlaceOrderMutation($maskedQuoteId), [], '', $headerMap); + $orderResponse = $this->graphQlMutation( + $this->getPlaceOrderMutation($maskedQuoteId), + [], + '', + $customerAuthHeaders + ); //assert tax title self::assertNotNull($orderResponse['placeOrder']['orderV2']['total']['taxes'][0]['title']); From 602cbef958e39c10e632a51a6148a03dccb84f2f Mon Sep 17 00:00:00 2001 From: Shantanu Dasgupta <108055538+cod40403@users.noreply.github.com> Date: Thu, 20 Feb 2025 15:53:45 +0530 Subject: [PATCH 25/30] LYNX-714 Gift message configuration on product level --- .../Model/Config/Messages.php | 77 ++++ .../Model/Resolver/Cart/Item/GiftMessage.php | 32 +- .../Model/Resolver/Order/Item/GiftMessage.php | 31 +- .../Model/Resolver/Product/GiftMessage.php | 52 +++ .../Magento/GiftMessageGraphQl/composer.json | 7 +- .../GiftMessageGraphQl/etc/schema.graphqls | 8 +- .../CartItem/DataProvider/UpdateCartItems.php | 62 +-- app/code/Magento/QuoteGraphQl/composer.json | 1 + .../CartItemWithGiftMessageTest.php | 430 ++++++++++++++++++ 9 files changed, 611 insertions(+), 89 deletions(-) create mode 100644 app/code/Magento/GiftMessageGraphQl/Model/Config/Messages.php create mode 100644 app/code/Magento/GiftMessageGraphQl/Model/Resolver/Product/GiftMessage.php create mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/GiftMessage/CartItemWithGiftMessageTest.php diff --git a/app/code/Magento/GiftMessageGraphQl/Model/Config/Messages.php b/app/code/Magento/GiftMessageGraphQl/Model/Config/Messages.php new file mode 100644 index 00000000000..fe394072418 --- /dev/null +++ b/app/code/Magento/GiftMessageGraphQl/Model/Config/Messages.php @@ -0,0 +1,77 @@ +<?php +/** + * Copyright 2025 Adobe + * All Rights Reserved. + */ +declare(strict_types=1); + +namespace Magento\GiftMessageGraphQl\Model\Config; + +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Catalog\Model\Product\Attribute\Source\Boolean; +use Magento\Framework\DataObject; +use Magento\Quote\Model\Quote\Item; +use Magento\Store\Model\ScopeInterface; +use Magento\Store\Model\Store; + +class Messages +{ + public const XPATH_CONFIG_GIFT_MESSAGE_ALLOW_ITEMS = 'sales/gift_options/allow_items'; + + /** + * Messages Constructor + * + * @param ScopeConfigInterface $scopeConfig + */ + public function __construct( + private readonly ScopeConfigInterface $scopeConfig, + ) { + } + + /** + * Check if gift message allowed for specified entity + * + * @param string $type + * @param DataObject $entity + * @param int|Store|null $store + * @return bool + */ + public function isMessagesAllowed( + string $type, + DataObject $entity, + int|Store|null $store = null + ): bool { + if ($type === 'items' && !empty($entity->getAllItems())) { + foreach ($entity->getAllItems() as $item) { + if (!$item->getParentItem() && $this->isMessagesAllowed('item', $item, $store)) { + return true; + } + } + } + + return $this->isGiftMessageAllowedForProduct( + ($type === 'item' || $entity instanceof Item) ? + $entity->getProduct()->getGiftMessageAvailable() : null, + $store + ); + } + + /** + * Check if gift message allowed for specified product + * + * @param string|null $productConfig + * @param Store|int|null $store + * @return bool + */ + public function isGiftMessageAllowedForProduct( + ?string $productConfig, + Store|int|null $store + ): bool { + return in_array($productConfig, [null, '', Boolean::VALUE_USE_CONFIG]) + ? (bool) $this->scopeConfig->getValue( + self::XPATH_CONFIG_GIFT_MESSAGE_ALLOW_ITEMS, + ScopeInterface::SCOPE_STORE, + $store + ) : (bool) $productConfig; + } +} diff --git a/app/code/Magento/GiftMessageGraphQl/Model/Resolver/Cart/Item/GiftMessage.php b/app/code/Magento/GiftMessageGraphQl/Model/Resolver/Cart/Item/GiftMessage.php index dd887aa2158..389a0eba95c 100644 --- a/app/code/Magento/GiftMessageGraphQl/Model/Resolver/Cart/Item/GiftMessage.php +++ b/app/code/Magento/GiftMessageGraphQl/Model/Resolver/Cart/Item/GiftMessage.php @@ -1,7 +1,7 @@ <?php /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. + * Copyright 2025 Adobe + * All Rights Reserved. */ declare(strict_types=1); @@ -15,7 +15,7 @@ use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\GiftMessage\Api\ItemRepositoryInterface; -use Magento\GiftMessage\Helper\Message as GiftMessageHelper; +use Magento\GiftMessageGraphQl\Model\Config\Messages; /** * Class provides ability to get GiftMessage for cart item @@ -23,25 +23,15 @@ class GiftMessage implements ResolverInterface { /** - * @var ItemRepositoryInterface - */ - private $itemRepository; - - /** - * @var GiftMessageHelper - */ - private $giftMessageHelper; - - /** + * GiftMessage Constructor + * * @param ItemRepositoryInterface $itemRepository - * @param GiftMessageHelper $giftMessageHelper + * @param Messages $messagesConfig */ public function __construct( - ItemRepositoryInterface $itemRepository, - GiftMessageHelper $giftMessageHelper + private readonly ItemRepositoryInterface $itemRepository, + private readonly Messages $messagesConfig ) { - $this->itemRepository = $itemRepository; - $this->giftMessageHelper = $giftMessageHelper; } /** @@ -70,11 +60,11 @@ public function resolve( $quoteItem = $value['model']; - if (!$this->giftMessageHelper->isMessagesAllowed('items', $quoteItem)) { + if (!$this->messagesConfig->isMessagesAllowed('items', $quoteItem)) { return null; } - if (!$this->giftMessageHelper->isMessagesAllowed('item', $quoteItem)) { + if (!$this->messagesConfig->isMessagesAllowed('item', $quoteItem)) { return null; } @@ -84,7 +74,7 @@ public function resolve( throw new GraphQlInputException(__('Can\'t load cart item')); } - if (!isset($giftItemMessage)) { + if (!$giftItemMessage) { return null; } diff --git a/app/code/Magento/GiftMessageGraphQl/Model/Resolver/Order/Item/GiftMessage.php b/app/code/Magento/GiftMessageGraphQl/Model/Resolver/Order/Item/GiftMessage.php index d932d44c7d1..4d9cb303050 100644 --- a/app/code/Magento/GiftMessageGraphQl/Model/Resolver/Order/Item/GiftMessage.php +++ b/app/code/Magento/GiftMessageGraphQl/Model/Resolver/Order/Item/GiftMessage.php @@ -1,7 +1,7 @@ <?php /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. + * Copyright 2025 Adobe + * All Rights Reserved. */ declare(strict_types=1); @@ -16,6 +16,7 @@ use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\GiftMessage\Api\OrderItemRepositoryInterface; use Magento\GiftMessage\Helper\Message as GiftMessageHelper; +use Magento\GiftMessageGraphQl\Model\Config\Messages; /** * Class provides ability to get GiftMessage for order item @@ -23,25 +24,15 @@ class GiftMessage implements ResolverInterface { /** - * @var OrderItemRepositoryInterface - */ - private $orderItemRepository; - - /** - * @var GiftMessageHelper - */ - private $giftMessageHelper; - - /** - * @param OrderItemRepositoryInterface $itemRepository - * @param GiftMessageHelper $giftMessageHelper + * GiftMessage Constructor + * + * @param OrderItemRepositoryInterface $orderItemRepository + * @param Messages $messagesConfig */ public function __construct( - OrderItemRepositoryInterface $itemRepository, - GiftMessageHelper $giftMessageHelper + private readonly OrderItemRepositoryInterface $orderItemRepository, + private readonly Messages $messagesConfig ) { - $this->orderItemRepository = $itemRepository; - $this->giftMessageHelper = $giftMessageHelper; } /** @@ -70,11 +61,11 @@ public function resolve( $orderItem = $value['model']; - if (!$this->giftMessageHelper->isMessagesAllowed('items', $orderItem)) { + if (!$this->messagesConfig->isMessagesAllowed('items', $orderItem)) { return null; } - if (!$this->giftMessageHelper->isMessagesAllowed('item', $orderItem)) { + if (!$this->messagesConfig->isMessagesAllowed('item', $orderItem)) { return null; } diff --git a/app/code/Magento/GiftMessageGraphQl/Model/Resolver/Product/GiftMessage.php b/app/code/Magento/GiftMessageGraphQl/Model/Resolver/Product/GiftMessage.php new file mode 100644 index 00000000000..35bfa57b4da --- /dev/null +++ b/app/code/Magento/GiftMessageGraphQl/Model/Resolver/Product/GiftMessage.php @@ -0,0 +1,52 @@ +<?php +/** + * Copyright 2025 Adobe + * All Rights Reserved. + */ +declare(strict_types=1); + +namespace Magento\GiftMessageGraphQl\Model\Resolver\Product; + +use Magento\Catalog\Api\Data\ProductInterface; +use Magento\Catalog\Model\Product\Type as Virtual; +use Magento\Downloadable\Model\Product\Type as Downloadable; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\GraphQl\Config\Element\Field; +use Magento\Framework\GraphQl\Query\ResolverInterface; +use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; +use Magento\GiftMessageGraphQl\Model\Config\Messages; + +class GiftMessage implements ResolverInterface +{ + /** + * @param Messages $messagesConfig + */ + public function __construct( + private readonly Messages $messagesConfig + ) { + } + + /** + * @inheritDoc + */ + public function resolve( + Field $field, + $context, + ResolveInfo $info, + array $value = null, + array $args = null + ): bool { + if (!isset($value['model']) || !$value['model'] instanceof ProductInterface) { + throw new LocalizedException(__('The product model is not available.')); + } + + if (in_array($value['model']['type_id'], [Virtual::TYPE_VIRTUAL, Downloadable::TYPE_DOWNLOADABLE], true)) { + return false; + } + + return $this->messagesConfig->isGiftMessageAllowedForProduct( + $value['model']->getGiftMessageAvailable(), + $context->getExtensionAttributes()->getStore() + ); + } +} diff --git a/app/code/Magento/GiftMessageGraphQl/composer.json b/app/code/Magento/GiftMessageGraphQl/composer.json index 9a1a969c8a7..3f005fc2135 100644 --- a/app/code/Magento/GiftMessageGraphQl/composer.json +++ b/app/code/Magento/GiftMessageGraphQl/composer.json @@ -5,7 +5,12 @@ "require": { "php": "~8.2.0||~8.3.0||~8.4.0", "magento/framework": "*", - "magento/module-gift-message": "*" + "magento/module-gift-message": "*", + "magento/module-catalog": "*", + "magento/module-quote": "*", + "magento/module-store": "*", + "magento/module-downloadable": "*" + }, "suggest": { "magento/module-graph-ql": "*" diff --git a/app/code/Magento/GiftMessageGraphQl/etc/schema.graphqls b/app/code/Magento/GiftMessageGraphQl/etc/schema.graphqls index 74493911a3c..97762321ea6 100644 --- a/app/code/Magento/GiftMessageGraphQl/etc/schema.graphqls +++ b/app/code/Magento/GiftMessageGraphQl/etc/schema.graphqls @@ -1,5 +1,5 @@ -# Copyright © Magento, Inc. All rights reserved. -# See COPYING.txt for license details. +# Copyright 2025 Adobe +# All Rights Reserved. type StoreConfig { allow_order : String @doc(description: "The value of the Allow Gift Messages on Order Level option") @@ -49,3 +49,7 @@ type CustomerOrder { interface OrderItemInterface { gift_message: GiftMessage @resolver(class: "\\Magento\\GiftMessageGraphQl\\Model\\Resolver\\Order\\Item\\GiftMessage") @doc(description: "The selected gift message for the order item") } + +interface ProductInterface { + gift_message_available: Boolean! @doc(description: "Returns a value indicating gift message availability for the product.") @resolver(class: "\\Magento\\GiftMessageGraphQl\\Model\\Resolver\\Product\\GiftMessage") +} diff --git a/app/code/Magento/QuoteGraphQl/Model/CartItem/DataProvider/UpdateCartItems.php b/app/code/Magento/QuoteGraphQl/Model/CartItem/DataProvider/UpdateCartItems.php index c2e94b21595..9d15412413f 100644 --- a/app/code/Magento/QuoteGraphQl/Model/CartItem/DataProvider/UpdateCartItems.php +++ b/app/code/Magento/QuoteGraphQl/Model/CartItem/DataProvider/UpdateCartItems.php @@ -1,7 +1,7 @@ <?php /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. + * Copyright 2025 Adobe + * All Rights Reserved. */ declare(strict_types=1); @@ -12,7 +12,7 @@ use Magento\GiftMessage\Api\Data\MessageInterface; use Magento\GiftMessage\Api\Data\MessageInterfaceFactory; use Magento\GiftMessage\Api\ItemRepositoryInterface; -use Magento\GiftMessage\Helper\Message as GiftMessageHelper; +use Magento\GiftMessageGraphQl\Model\Config\Messages; use Magento\Quote\Api\CartItemRepositoryInterface; use Magento\Quote\Model\Quote; use Magento\QuoteGraphQl\Model\Cart\UpdateCartItem; @@ -23,49 +23,21 @@ class UpdateCartItems { /** - * @var CartItemRepositoryInterface - */ - private $cartItemRepository; - - /** - * @var UpdateCartItem - */ - private $updateCartItem; - - /** - * @var ItemRepositoryInterface - */ - private $itemRepository; - - /** - * @var GiftMessageHelper - */ - private $giftMessageHelper; - - /** - * @var MessageInterfaceFactory - */ - private $giftMessageFactory; - - /** + * UpdateCartItems Constructor + * * @param CartItemRepositoryInterface $cartItemRepository - * @param UpdateCartItem $updateCartItem - * @param ItemRepositoryInterface $itemRepository - * @param GiftMessageHelper $giftMessageHelper - * @param MessageInterfaceFactory $giftMessageFactory + * @param UpdateCartItem $updateCartItem + * @param ItemRepositoryInterface $itemRepository + * @param Messages $messagesConfig + * @param MessageInterfaceFactory $giftMessageFactory */ public function __construct( - CartItemRepositoryInterface $cartItemRepository, - UpdateCartItem $updateCartItem, - ItemRepositoryInterface $itemRepository, - GiftMessageHelper $giftMessageHelper, - MessageInterfaceFactory $giftMessageFactory + private readonly CartItemRepositoryInterface $cartItemRepository, + private readonly UpdateCartItem $updateCartItem, + private readonly ItemRepositoryInterface $itemRepository, + private readonly Messages $messagesConfig, + private readonly MessageInterfaceFactory $giftMessageFactory ) { - $this->cartItemRepository = $cartItemRepository; - $this->updateCartItem = $updateCartItem; - $this->itemRepository = $itemRepository; - $this->giftMessageHelper = $giftMessageHelper; - $this->giftMessageFactory = $giftMessageFactory; } /** @@ -108,17 +80,17 @@ public function processCartItems(Quote $cart, array $items): void if (!empty($item['gift_message'])) { try { - if (!$this->giftMessageHelper->isMessagesAllowed('items', $cartItem)) { + if (!$this->messagesConfig->isMessagesAllowed('items', $cartItem)) { continue; } - if (!$this->giftMessageHelper->isMessagesAllowed('item', $cartItem)) { + if (!$this->messagesConfig->isMessagesAllowed('item', $cartItem)) { continue; } /** @var MessageInterface $giftItemMessage */ $giftItemMessage = $this->itemRepository->get($cart->getEntityId(), $itemId); - if (empty($giftItemMessage)) { + if (!$giftItemMessage) { /** @var MessageInterface $giftMessage */ $giftMessage = $this->giftMessageFactory->create(); $this->updateGiftMessageForItem($cart, $giftMessage, $item, $itemId); diff --git a/app/code/Magento/QuoteGraphQl/composer.json b/app/code/Magento/QuoteGraphQl/composer.json index 6691ca753fc..a73baecd5be 100644 --- a/app/code/Magento/QuoteGraphQl/composer.json +++ b/app/code/Magento/QuoteGraphQl/composer.json @@ -16,6 +16,7 @@ "magento/module-directory": "*", "magento/module-graph-ql": "*", "magento/module-gift-message": "*", + "magento/module-gift-message-graph-ql": "*", "magento/module-catalog-inventory": "*", "magento/module-eav-graph-ql": "*", "magento/module-downloadable": "*" diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/GiftMessage/CartItemWithGiftMessageTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/GiftMessage/CartItemWithGiftMessageTest.php new file mode 100644 index 00000000000..d448329ef94 --- /dev/null +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/GiftMessage/CartItemWithGiftMessageTest.php @@ -0,0 +1,430 @@ +<?php +/** + * Copyright 2025 Adobe + * All Rights Reserved. + */ +declare(strict_types=1); + +namespace Magento\GraphQl\GiftMessage; + +use Exception; +use Magento\Catalog\Test\Fixture\Product as ProductFixture; +use Magento\Checkout\Test\Fixture\SetGuestEmail as SetGuestEmailFixture; +use Magento\Framework\App\ResourceConnection; +use Magento\Framework\Exception\NoSuchEntityException; +use Magento\GiftMessage\Test\Fixture\GiftMessage; +use Magento\Indexer\Test\Fixture\Indexer; +use Magento\Quote\Model\QuoteIdToMaskedQuoteIdInterface; +use Magento\Quote\Test\Fixture\AddProductToCart as AddProductToCartFixture; +use Magento\Quote\Test\Fixture\GuestCart; +use Magento\Downloadable\Test\Fixture\DownloadableProduct as DownloadableProductFixture; +use Magento\TestFramework\Fixture\Config; +use Magento\TestFramework\Fixture\DataFixture; +use Magento\TestFramework\Fixture\DataFixtureStorage; +use Magento\TestFramework\Fixture\DataFixtureStorageManager; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\TestCase\GraphQlAbstract; + +/** + * Test for getting gift message with cart item query + */ +class CartItemWithGiftMessageTest extends GraphQlAbstract +{ + /** + * @var DataFixtureStorage + */ + private $fixtures; + + /** + * @var ResourceConnection + */ + private $resourceConnection; + + /** + * @var QuoteIdToMaskedQuoteIdInterface + */ + private $quoteIdToMaskedQuoteId; + + /** + * @inheritdoc + */ + protected function setUp(): void + { + $this->fixtures = Bootstrap::getObjectManager()->get(DataFixtureStorageManager::class)->getStorage(); + $this->resourceConnection = Bootstrap::getObjectManager()->get(ResourceConnection::class); + $this->quoteIdToMaskedQuoteId= Bootstrap::getObjectManager()->get(QuoteIdToMaskedQuoteIdInterface::class); + } + + #[ + DataFixture(ProductFixture::class, ['type_id' => 'virtual'], as: 'product'), + DataFixture(Indexer::class, as: 'indexer'), + DataFixture(GiftMessage::class, as: 'message'), + DataFixture(GuestCart::class, ['message_id' => '$message.id$'], as: 'quote'), + DataFixture(SetGuestEmailFixture::class, ['cart_id' => '$quote.id$']), + DataFixture( + AddProductToCartFixture::class, + [ + 'cart_id' => '$quote.id$', + 'product_id' => '$product.id$' + ] + ), + Config('sales/gift_options/allow_order', 1), + Config('sales/gift_options/allow_items', 1) + ] + public function testCartQueryWithVirtualItem(): void + { + $maskedQuoteId = $this->quoteIdToMaskedQuoteId->execute((int)$this->fixtures->get('quote')->getId()); + $this->updateGiftMessageForCartItems($maskedQuoteId); + + self::assertEquals( + [ + 'cart' => [ + 'itemsV2' => [ + 'items' => [ + '0' => [ + 'product' => [ + 'gift_message_available' => false + ] + ] + ] + ] + ] + ], + $this->graphQlQuery($this->getCartItemsGraphQlQuery($maskedQuoteId)) + ); + } + + #[ + DataFixture(DownloadableProductFixture::class, [ + 'price' => 100, + 'type_id' => 'downloadable', + 'links_purchased_separately' => 0, + 'downloadable_product_links' => [ + [ + 'title' => 'Example 1', + 'price' => 0.00, + 'link_type' => 'file' + ], + [ + 'title' => 'Example 2', + 'price' => 0.00, + 'link_type' => 'file' + ] + ] + ], as: 'product'), + DataFixture(Indexer::class, as: 'indexer'), + DataFixture(GiftMessage::class, as: 'message'), + DataFixture(GuestCart::class, ['message_id' => '$message.id$'], as: 'quote'), + DataFixture(SetGuestEmailFixture::class, ['cart_id' => '$quote.id$']), + DataFixture( + AddProductToCartFixture::class, + [ + 'cart_id' => '$quote.id$', + 'product_id' => '$product.id$' + ] + ), + Config('sales/gift_options/allow_order', 1), + Config('sales/gift_options/allow_items', 1) + ] + public function testCartQueryWithDownloadableItem(): void + { + $maskedQuoteId = $this->quoteIdToMaskedQuoteId->execute((int)$this->fixtures->get('quote')->getId()); + $this->updateGiftMessageForCartItems($maskedQuoteId); + + self::assertEquals( + [ + 'cart' => [ + 'itemsV2' => [ + 'items' => [ + '0' => [ + 'product' => [ + 'gift_message_available' => false + ] + ] + ] + ] + ] + ], + $this->graphQlQuery($this->getCartItemsGraphQlQuery($maskedQuoteId)) + ); + } + + #[ + DataFixture( + ProductFixture::class, + ['type_id' => 'simple', 'weight' => 10, 'gift_message_available' => 2], + as: 'product' + ), + DataFixture(Indexer::class, as: 'indexer'), + DataFixture(GiftMessage::class, as: 'message'), + DataFixture(GuestCart::class, ['message_id' => '$message.id$'], as: 'quote'), + DataFixture(SetGuestEmailFixture::class, ['cart_id' => '$quote.id$']), + DataFixture( + AddProductToCartFixture::class, + [ + 'cart_id' => '$quote.id$', + 'product_id' => '$product.id$' + ] + ), + Config('sales/gift_options/allow_order', 1), + Config('sales/gift_options/allow_items', 1) + ] + public function testCartQueryWithSimpleItemWhenStoreConfigEnabled(): void + { + $this->updateCartItemWithGiftMessage(); + } + + #[ + DataFixture( + ProductFixture::class, + ['type_id' => 'simple', 'weight' => 10, 'gift_message_available' => 2], + as: 'product' + ), + DataFixture(Indexer::class, as: 'indexer'), + DataFixture(GiftMessage::class, as: 'message'), + DataFixture(GuestCart::class, ['message_id' => '$message.id$'], as: 'quote'), + DataFixture(SetGuestEmailFixture::class, ['cart_id' => '$quote.id$']), + DataFixture( + AddProductToCartFixture::class, + [ + 'cart_id' => '$quote.id$', + 'product_id' => '$product.id$' + ] + ), + Config('sales/gift_options/allow_order', 1), + Config('sales/gift_options/allow_items', 0) + ] + public function testCartQueryWithSimpleItemWhenStoreConfigDisabled(): void + { + $this->updateCartItemWithoutGiftMessage(); + } + + #[ + DataFixture( + ProductFixture::class, + ['type_id' => 'simple', 'weight' => 10, 'gift_message_available' => 0], + as: 'product' + ), + DataFixture(Indexer::class, as: 'indexer'), + DataFixture(GiftMessage::class, as: 'message'), + DataFixture(GuestCart::class, ['message_id' => '$message.id$'], as: 'quote'), + DataFixture(SetGuestEmailFixture::class, ['cart_id' => '$quote.id$']), + DataFixture( + AddProductToCartFixture::class, + [ + 'cart_id' => '$quote.id$', + 'product_id' => '$product.id$' + ] + ), + Config('sales/gift_options/allow_order', 1), + Config('sales/gift_options/allow_items', 0) + ] + public function testCartQueryWithSimpleItemWhenAllConfigDisabled(): void + { + $this->updateCartItemWithoutGiftMessage(); + } + + #[ + DataFixture( + ProductFixture::class, + ['type_id' => 'simple', 'weight' => 10, 'gift_message_available' => 1], + as: 'product' + ), + DataFixture(Indexer::class, as: 'indexer'), + DataFixture(GiftMessage::class, as: 'message'), + DataFixture(GuestCart::class, ['message_id' => '$message.id$'], as: 'quote'), + DataFixture(SetGuestEmailFixture::class, ['cart_id' => '$quote.id$']), + DataFixture( + AddProductToCartFixture::class, + [ + 'cart_id' => '$quote.id$', + 'product_id' => '$product.id$' + ] + ), + Config('sales/gift_options/allow_order', 1), + Config('sales/gift_options/allow_items', 0) + ] + public function testCartQueryWithSimpleItemWhenProductConfigEnabled(): void + { + $this->updateCartItemWithGiftMessage(); + } + + /** + * Get cart items query with gift message + * + * @param string $maskedQuoteId + * @return string + */ + private function getCartItemsGraphQlQuery(string $maskedQuoteId): string + { + return <<<QUERY + { + cart(cart_id: "$maskedQuoteId") { + itemsV2 { + items { + product { + gift_message_available + } + ... on SimpleCartItem { + gift_message { + from + to + message + } + } + } + } + } + } + QUERY; + } + + /** + * Update gift message mutation + * + * @param array $giftData + * @param string $maskedQuoteId + * @param int $itemId + * @return string + */ + private function updateGiftMessageMutation(array $giftData, string $maskedQuoteId, int $itemId): string + { + return <<<MUTATION + mutation { + updateCartItems( + input: { + cart_id: "$maskedQuoteId", + cart_items: [ + { + cart_item_id: $itemId + gift_message: { + to: "{$giftData['message_to']}" + from: "{$giftData['message_from']}" + message: "{$giftData['message']}" + } + quantity: 2 + } + ] + } + ) { + cart { + items { + id + } + } + } + } + MUTATION; + } + + /** + * Update gift message for cart items + * + * @param string $maskedQuoteId + * @return void + * @throws Exception + */ + private function updateGiftMessageForCartItems(string $maskedQuoteId): void + { + $giftMessage = $this->fixtures->get('message'); + + $this->graphQlMutation( + $this->updateGiftMessageMutation( + [ + 'message_to' => $giftMessage->getRecipient(), + 'message_from' => $giftMessage->getSender(), + 'message' => $giftMessage->getMessage(), + ], + $maskedQuoteId, + $this->getItemId( + (int)$this->fixtures->get('quote')->getId(), + (int)$this->fixtures->get('product')->getId() + ) + ) + ); + } + + /** + * Get item id from quote_id and product_id + * + * @param int $cartId + * @param int $productId + * @return int|null + */ + private function getItemId(int $cartId, int $productId): ?int + { + $connection = $this->resourceConnection->getConnection(); + return (int)$connection->fetchOne( + $connection->select() + ->from($this->resourceConnection->getTableName('quote_item')) + ->reset('columns') + ->columns('item_id') + ->where('quote_id = ?', $cartId) + ->where('product_id = ?', $productId) + ); + } + + /** + * Update Cart Item with gift message - for simple and physical gift card + * + * @return void + * @throws NoSuchEntityException + */ + public function updateCartItemWithGiftMessage(): void + { + $maskedQuoteId = $this->quoteIdToMaskedQuoteId->execute((int)$this->fixtures->get('quote')->getId()); + $this->updateGiftMessageForCartItems($maskedQuoteId); + + self::assertEquals( + [ + 'cart' => [ + 'itemsV2' => [ + 'items' => [ + '0' => [ + 'product' => [ + 'gift_message_available' => true + ], + 'gift_message' => [ + 'from' => 'Romeo', + 'to' => 'Mercutio', + 'message' => 'Fixture Test message.' + ] + ] + ] + ] + ] + ], + $this->graphQlQuery($this->getCartItemsGraphQlQuery($maskedQuoteId)) + ); + } + + /** + * Update Cart Item without gift message + * + * @return void + * @throws NoSuchEntityException + */ + public function updateCartItemWithoutGiftMessage(): void + { + $maskedQuoteId = $this->quoteIdToMaskedQuoteId->execute((int)$this->fixtures->get('quote')->getId()); + $this->updateGiftMessageForCartItems($maskedQuoteId); + + self::assertEquals( + [ + 'cart' => [ + 'itemsV2' => [ + 'items' => [ + '0' => [ + 'product' => [ + 'gift_message_available' => false + ], + 'gift_message' => null + ] + ] + ] + ] + ], + $this->graphQlQuery($this->getCartItemsGraphQlQuery($maskedQuoteId)) + ); + } +} From 2d55a0681b496c5826f5edcf97af1eb2b73ea54a Mon Sep 17 00:00:00 2001 From: Dnyaneshwar Jambhulkar <pru34625@adobe.com> Date: Fri, 21 Feb 2025 10:00:05 +0530 Subject: [PATCH 26/30] Debug elastcisearch8 connection --- app/code/Magento/Elasticsearch/Setup/Validator.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Elasticsearch/Setup/Validator.php b/app/code/Magento/Elasticsearch/Setup/Validator.php index e5f3ae96210..ed737419d54 100644 --- a/app/code/Magento/Elasticsearch/Setup/Validator.php +++ b/app/code/Magento/Elasticsearch/Setup/Validator.php @@ -38,11 +38,15 @@ public function validate(): array $errors = []; try { echo "Check elasticsearch8 server up or not with command line\n"; - shell_exec("curl localhost:9200/"); + shell_exec("curl http://127.0.0.1:9200/"); $output = shell_exec('netstat -tuln'); echo "<pre>$output</pre>"; + + $output = shell_exec("cat /var/log/elasticsearch/elasticsearch.log"); + echo "<pre>$output</pre>"; + $client = $this->clientResolver->create(); if (!$client->testConnection()) { $errors[] = 'Could not validate a connection to Elasticsearch.' From 7b0776d838d5d12cf82fbad6b13d4347a90597dc Mon Sep 17 00:00:00 2001 From: Dnyaneshwar Jambhulkar <pru34625@adobe.com> Date: Fri, 21 Feb 2025 10:49:52 +0530 Subject: [PATCH 27/30] Debug elastcisearch8 connection --- app/code/Magento/Elasticsearch/Setup/Validator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Elasticsearch/Setup/Validator.php b/app/code/Magento/Elasticsearch/Setup/Validator.php index ed737419d54..a302a38f90f 100644 --- a/app/code/Magento/Elasticsearch/Setup/Validator.php +++ b/app/code/Magento/Elasticsearch/Setup/Validator.php @@ -44,7 +44,7 @@ public function validate(): array echo "<pre>$output</pre>"; - $output = shell_exec("cat /var/log/elasticsearch/elasticsearch.log"); + $output = shell_exec("sudo cat /var/log/elasticsearch/elasticsearch.log"); echo "<pre>$output</pre>"; $client = $this->clientResolver->create(); From c27240230bf775b6514e15f5365362a58002aac5 Mon Sep 17 00:00:00 2001 From: Shantanu Dasgupta <108055538+cod40403@users.noreply.github.com> Date: Mon, 24 Feb 2025 16:31:17 +0530 Subject: [PATCH 28/30] LYNX-699 Unit Test fix for Delivery PR --- .../Model/Resolver/OrderTotal.php | 6 +-- .../Unit/Model/Resolver/OrderTotalTest.php | 37 +++++++++++++++++-- 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/SalesGraphQl/Model/Resolver/OrderTotal.php b/app/code/Magento/SalesGraphQl/Model/Resolver/OrderTotal.php index 907252d9204..ca6ddf804f0 100644 --- a/app/code/Magento/SalesGraphQl/Model/Resolver/OrderTotal.php +++ b/app/code/Magento/SalesGraphQl/Model/Resolver/OrderTotal.php @@ -93,9 +93,9 @@ private function getAllAppliedTaxesOnOrders(OrderInterface $order): array { return array_map( fn($appliedTaxesData) => [ - 'title' => $appliedTaxesData->getDataByKey('title'), - 'percent' => $appliedTaxesData->getDataByKey('percent'), - 'amount' => $appliedTaxesData->getDataByKey('amount'), + 'title' => $appliedTaxesData->getTitle(), + 'percent' => $appliedTaxesData->getPercent(), + 'amount' => $appliedTaxesData->getAmount(), ], $this->orderTaxManagement->getOrderTaxDetails($order->getEntityId())->getAppliedTaxes() ); diff --git a/app/code/Magento/SalesGraphQl/Test/Unit/Model/Resolver/OrderTotalTest.php b/app/code/Magento/SalesGraphQl/Test/Unit/Model/Resolver/OrderTotalTest.php index 1d7c0372a5b..033aaa2d0b9 100644 --- a/app/code/Magento/SalesGraphQl/Test/Unit/Model/Resolver/OrderTotalTest.php +++ b/app/code/Magento/SalesGraphQl/Test/Unit/Model/Resolver/OrderTotalTest.php @@ -9,6 +9,8 @@ use Magento\Framework\GraphQl\Query\Resolver\ContextInterface; use Magento\Framework\Api\ExtensionAttributesInterface; +use Magento\Tax\Api\Data\OrderTaxDetailsAppliedTaxInterface; +use Magento\Tax\Api\OrderTaxManagementInterface; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Magento\SalesGraphQl\Model\Resolver\OrderTotal; @@ -16,6 +18,7 @@ use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Framework\Exception\LocalizedException; +use Magento\Tax\Api\Data\OrderTaxDetailsInterface; class OrderTotalTest extends TestCase { @@ -49,6 +52,21 @@ class OrderTotalTest extends TestCase */ private $extensionAttributesMock; + /** + * @var OrderTaxManagementInterface|MockObject + */ + private $orderTaxManagementMock; + + /** + * @var OrderTaxDetailsInterface + */ + private $orderTaxDetailsMock; + + /** + * @var OrderTaxDetailsAppliedTaxInterface + */ + private $orderTaxDetailsAppliedTaxMock; + protected function setUp(): void { $this->contextMock = $this->createMock(ContextInterface::class); @@ -65,7 +83,11 @@ protected function setUp(): void $this->orderMock->method('getShippingInclTax')->willReturn(7.00); $this->orderMock->method('getDiscountAmount')->willReturn(7.00); $this->orderMock->method('getDiscountDescription')->willReturn('TEST123'); - $this->orderTotal = new OrderTotal(); + $this->orderMock->method('getEntityId')->willReturn(123); + $this->orderTaxManagementMock = $this->createMock(OrderTaxManagementInterface::class); + $this->orderTaxDetailsMock = $this->createMock(OrderTaxDetailsInterface::class); + $this->orderTaxDetailsAppliedTaxMock = $this->createMock(OrderTaxDetailsAppliedTaxInterface::class); + $this->orderTotal = new OrderTotal($this->orderTaxManagementMock); } public function testResolve(): void @@ -74,12 +96,21 @@ public function testResolve(): void $resolveInfoMock = $this->createMock(ResolveInfo::class); $value = ['model' => $this->orderMock]; $args = []; + $this->orderTaxDetailsAppliedTaxMock->expects($this->atMost(1))->method('setTitle')->willReturn('TestTitle'); + $this->orderTaxDetailsAppliedTaxMock->expects($this->atMost(1))->method('setAmount')->willReturn(100.00); + $this->orderTaxDetailsAppliedTaxMock->expects($this->atMost(1))->method('setPercent')->willReturn(10); + $this->orderTaxDetailsMock->expects($this->any())->method('getAppliedTaxes')->willReturn([ + $this->orderTaxDetailsAppliedTaxMock + ]); + $this->orderTaxManagementMock->expects($this->any())->method('getOrderTaxDetails')->willReturn( + $this->orderTaxDetailsMock + ); $this->extensionAttributesMock = $this->getMockBuilder(ExtensionAttributesInterface::class) ->addMethods(['getAppliedTaxes', 'getItemAppliedTaxes']) ->disableOriginalConstructor() ->getMock(); - $this->extensionAttributesMock->expects($this->once())->method('getAppliedTaxes')->willReturn([]); - $this->extensionAttributesMock->expects($this->once())->method('getItemAppliedTaxes')->willReturn([]); + $this->extensionAttributesMock->expects($this->atMost(1))->method('getAppliedTaxes')->willReturn([]); + $this->extensionAttributesMock->expects($this->atMost(1))->method('getItemAppliedTaxes')->willReturn([]); $this->orderMock->method('getExtensionAttributes')->willReturn($this->extensionAttributesMock); $result = $this->orderTotal->resolve($fieldMock, $this->contextMock, $resolveInfoMock, $value, $args); $this->assertArrayHasKey('base_grand_total', $result); From a0e38672f10612691ae30b4b0e861e1a395b8659 Mon Sep 17 00:00:00 2001 From: Rajesh Kumar <glo71317@adobe.com> Date: Tue, 25 Feb 2025 15:30:13 +0530 Subject: [PATCH 29/30] AC-13818::Make ES8 to be default for 2.4.8 instead of ES7 --- app/code/Magento/Elasticsearch8/Model/Client/Elasticsearch.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Elasticsearch8/Model/Client/Elasticsearch.php b/app/code/Magento/Elasticsearch8/Model/Client/Elasticsearch.php index ed47ffaf2d9..fe6af19c6dd 100644 --- a/app/code/Magento/Elasticsearch8/Model/Client/Elasticsearch.php +++ b/app/code/Magento/Elasticsearch8/Model/Client/Elasticsearch.php @@ -60,7 +60,7 @@ class Elasticsearch implements ClientInterface */ public function __construct( array $options = [], - $elasticsearchClient = null, + ?Client $elasticsearchClient = null, array $fieldsMappingPreprocessors = [], ?DynamicTemplatesProvider $dynamicTemplatesProvider = null ) { From 57f5690ab7ef4e1091df93de490de968a545e8b3 Mon Sep 17 00:00:00 2001 From: Rajesh Kumar <glo71317@adobe.com> Date: Tue, 25 Feb 2025 19:22:48 +0530 Subject: [PATCH 30/30] AC-13818::Make ES8 to be default for 2.4.8 instead of ES7 --- app/code/Magento/Elasticsearch/Setup/Validator.php | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/app/code/Magento/Elasticsearch/Setup/Validator.php b/app/code/Magento/Elasticsearch/Setup/Validator.php index a302a38f90f..bfeebfa62bd 100644 --- a/app/code/Magento/Elasticsearch/Setup/Validator.php +++ b/app/code/Magento/Elasticsearch/Setup/Validator.php @@ -37,16 +37,6 @@ public function validate(): array { $errors = []; try { - echo "Check elasticsearch8 server up or not with command line\n"; - shell_exec("curl http://127.0.0.1:9200/"); - - $output = shell_exec('netstat -tuln'); - echo "<pre>$output</pre>"; - - - $output = shell_exec("sudo cat /var/log/elasticsearch/elasticsearch.log"); - echo "<pre>$output</pre>"; - $client = $this->clientResolver->create(); if (!$client->testConnection()) { $errors[] = 'Could not validate a connection to Elasticsearch.'