diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 19fa5f34..8ecbe433 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -25,6 +25,12 @@ - Fix error "Invalid template file..." when reindexing cms blocks/pages by cron. ([#191](https://github.com/DivanteLtd/magento2-vsbridge-indexer/pull/351)) - Fix providing label for the configurable_options field. Field is now using the label assigned for the currently active (reindex) store. ([#339](https://github.com/DivanteLtd/magento2-vsbridge-indexer/pull/352)) +## [2.0] + +- Added support for ES6+. You can choose ES version in configuration (by default ES5 is selected). For ES 5 only one index is created, for ES6+ we have separated indices per type +- vsbridge_indexer.xml was replaced with vsbridge.xml. You declare type/entity and mapping in vsbridge.xml +- Dataproviders configuration was moved to di.xml + ## [1.21.0] (2020.09.16) ### Fixed diff --git a/README.md b/README.md index 02a3cfad..7014e4d4 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,21 @@ Sign up for a demo at https://vuestorefront.io/ (Vue Storefront integrated with ## Overview -### Version 1.5.0/1.5.1 - support for aliases. + + +### Version 1.x +Pull Requests should be made against 1.x branch. Changes from this branch won't be merge to main branch. +Only fixes will be accepted. + +### Version 2.0 +Support ES5 and ES6+. + +##### To read what changed click [here](CHANGELOG.MD#20) + +##### How to upgrade to 2.0 +Click here to find out [more](docs/upgrade-to-2.0.md) + +##### Version 1.5.0/1.5.1 - support for aliases. Command ` php bin/magento vsbridge:reindex --all` will reindex all data to new index. It will create new index and update aliases at the end. @@ -79,7 +93,7 @@ Configure the module in Magento panel and run full indexation. **Check configuration [here](docs/configuration.md)** -### Update VSF/VSF-API configuration +### Update VSF/VSF-API configuration for ES5 **Important**: It is crucial to update configuration `elasticsearch.index` in the VSF and `elasticsearch.indices` in VSF-API *Index Alias Prefix* → define prefixes for ElasticSearch indexes. The panel allows adding prefix only to the catalog name e.g.: *vue_storefront_catalog*. For each store (store view) index name is generated on the base of defined prefix and either ID or Store Code. Aliases cannot be created. @@ -195,7 +209,10 @@ If you need a list off all available index-names, you can use `php bin/magento i *Update on Schedule* mode observes changes in corresponding tables, and probably will be more relevant in most cases. It is the default mode in any bigger stores. + + ### Compatibility +--- version 2.0 - tested with ES: 5.6.11, 6.8.0, 7.6.2 -- Vue Storefront >= 1.4.4 Module was tested on: diff --git a/composer.json b/composer.json index bcaf2613..ea8de6c7 100644 --- a/composer.json +++ b/composer.json @@ -1,57 +1,47 @@ { - "name": "divante/magento2-vsbridge-indexer", - "type": "magento2-component", - "license": "MIT", - "authors": [{ - "name": "Agata", - "email": "afirlejczyk@divante.pl" - }], - "keywords": [ - "magento", - "magento2", - "vuestorefront" - ], - "repositories": [ - { - "type": "composer", - "url": "https://repo.magento.com/" - } - ], - "require": { - "php": ">=7.0.2", - "magento/framework": ">=101.0.0", - "magento/module-store": ">=100.2.0", - "magento/module-backend": ">=100.2.0", - "magento/module-catalog": ">=102.0.0", - "magento/magento-composer-installer": "*", - "elasticsearch/elasticsearch": "~5.1|~6.1" - }, - "replace": { - "divante/module-vsf-indexer-core": "self.version", - "divante/module-vsf-indexer-catalog": "self.version", - "divante/module-vsf-indexer-tax": "self.version", - "divante/module-vsf-indexer-cms": "self.version" - }, - "autoload": { - "files": [ - "src/module-vsbridge-indexer-agreement/registration.php", - "src/module-vsbridge-indexer-core/registration.php", - "src/module-vsbridge-indexer-catalog/registration.php", - "src/module-vsbridge-indexer-cms/registration.php", - "src/module-vsbridge-indexer-review/registration.php", - "src/module-vsbridge-indexer-tax/registration.php", - "src/module-vsbridge-downloadable/registration.php" + "name": "divante/magento2-vsbridge-indexer", + "type": "magento2-component", + "license": "MIT", + "keywords": [ + "magento", + "magento2", + "vuestorefront" ], - "psr-4": { - "Divante\\VsbridgeIndexerAgreement\\": "src/module-vsbridge-indexer-agreement", - "Divante\\VsbridgeIndexerCore\\": "src/module-vsbridge-indexer-core", - "Divante\\VsbridgeIndexerCatalog\\": "src/module-vsbridge-indexer-catalog", - "Divante\\VsbridgeIndexerCms\\": "src/module-vsbridge-indexer-cms", - "Divante\\VsbridgeIndexerReview\\": "src/module-vsbridge-indexer-review", - "Divante\\VsbridgeIndexerTax\\": "src/module-vsbridge-indexer-tax", - "Divante\\VsbridgeDownloadable\\": "src/module-vsbridge-downloadable" - } - }, - "minimum-stability": "dev", - "prefer-stable": true + "repositories": [ + { + "type": "composer", + "url": "https://repo.magento.com/" + } + ], + "require": { + "php": ">=7.0.2", + "magento/framework": ">=101.0.0", + "magento/module-store": ">=100.2.0", + "magento/module-backend": ">=100.2.0", + "magento/module-catalog": ">=102.0.0", + "magento/magento-composer-installer": "*", + "elasticsearch/elasticsearch": "~5.1|~6.1|~7.1" + }, + "autoload": { + "files": [ + "src/module-vsbridge-indexer-core/registration.php", + "src/module-vsbridge-indexer-catalog/registration.php", + "src/module-vsbridge-indexer-cms/registration.php", + "src/module-vsbridge-indexer-review/registration.php", + "src/module-vsbridge-indexer-tax/registration.php", + "src/module-vsbridge-downloadable/registration.php", + "src/module-vsbridge-indexer-agreement/registration.php" + ], + "psr-4": { + "Divante\\VsbridgeIndexerAgreement\\": "src/module-vsbridge-indexer-agreement", + "Divante\\VsbridgeIndexerCore\\": "src/module-vsbridge-indexer-core", + "Divante\\VsbridgeIndexerCatalog\\": "src/module-vsbridge-indexer-catalog", + "Divante\\VsbridgeIndexerCms\\": "src/module-vsbridge-indexer-cms", + "Divante\\VsbridgeIndexerReview\\": "src/module-vsbridge-indexer-review", + "Divante\\VsbridgeIndexerTax\\": "src/module-vsbridge-indexer-tax", + "Divante\\VsbridgeDownloadable\\": "src/module-vsbridge-downloadable" + } + }, + "minimum-stability": "dev", + "prefer-stable": true } diff --git a/docs/configuration.md b/docs/configuration.md index b483e8e0..375409b2 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -1,14 +1,16 @@ ### Magento Configuration Go to the new ‘Indexer’ section (Stores → Configuration → Vuestorefront → Indexer), available now in the in the Magento Panel, and configure it in the listed areas: -1. ####General settings → Enable VS Bridge - - Enable to export data to elasticsearch. By default indexing is disable. +1. ####General settings - ![](./images/config-general-enable.png) - -1. ####General settings → List of stores to reindex - - Select stores for which data must be exported to ElasticSearch. By default stores 0 to 1 are selected. For each store view, a new, separate ElasticSearch index is created. + **Enable VS Bridge** → Enable to export data to elasticsearch. By default indexing is disable. + + **Elasticsearch version** + + Select ES version depends on which ES you are using/is used by magento. + If you are using ES 5.x.x, choose Elasticsearch5, if you are using version 6.x.x or 7.x.x choose Elasticsearch6+. + By default Elasticsearch5 option is selected. + + **List of stores to reindex** → Select stores for which data must be exported to ElasticSearch. By default store with ID 1 is selected. For each store view, a new, separate ElasticSearch index is created. ![](./images/config-general.png) diff --git a/docs/images/config-general-enable.png b/docs/images/config-general-enable.png deleted file mode 100644 index 7c989c9a..00000000 Binary files a/docs/images/config-general-enable.png and /dev/null differ diff --git a/docs/images/config-general.png b/docs/images/config-general.png index d5e5dc4a..71fc8786 100644 Binary files a/docs/images/config-general.png and b/docs/images/config-general.png differ diff --git a/docs/upgrade-to-2.0.md b/docs/upgrade-to-2.0.md new file mode 100644 index 00000000..9bf9316b --- /dev/null +++ b/docs/upgrade-to-2.0.md @@ -0,0 +1,43 @@ +1. Vsbridge_indexer.xml was replaced with vsbridge.xml +- Vsbridge.xml keep information about type/entity and mapping. +- Datapvoriderds were moved to di.xml +Example: + +Before: +``` + + + + + + Divante\VsbridgeIndexerTax\Model\Indexer\DataProvider\TaxClasses + Divante\VsbridgeIndexerTax\Model\Indexer\DataProvider\TaxRates + + + + +``` + +After: +**vsbridge:xml** +``` + + + +``` + +**di.xml** +``` + + + + + Divante\VsbridgeIndexerTax\Model\Indexer\DataProvider\TaxClasses + Divante\VsbridgeIndexerTax\Model\Indexer\DataProvider\TaxRates + + + + +``` diff --git a/src/module-vsbridge-indexer-agreement/Model/Indexer/Action/Agreement.php b/src/module-vsbridge-indexer-agreement/Model/Indexer/Action/Agreement.php index 07861398..8beea3aa 100644 --- a/src/module-vsbridge-indexer-agreement/Model/Indexer/Action/Agreement.php +++ b/src/module-vsbridge-indexer-agreement/Model/Indexer/Action/Agreement.php @@ -1,15 +1,14 @@ indexHandler = $indexerHandler; - $this->agreementAction = $action; - $this->storeManager = $storeManager; - } - - /** - * @inheritdoc - */ - public function execute($ids) - { - $stores = $this->storeManager->getStores(); - - foreach ($stores as $store) { - $this->indexHandler->saveIndex($this->agreementAction->rebuild($store->getId(), $ids), $store); - $this->indexHandler->cleanUpByTransactionKey($store, $ids); - } - } - - /** - * @inheritdoc - */ - public function executeFull() - { - $stores = $this->storeManager->getStores(); - - foreach ($stores as $store) { - $this->indexHandler->saveIndex($this->agreementAction->rebuild($store->getId()), $store); - $this->indexHandler->cleanUpByTransactionKey($store); - } - } - - /** - * @inheritdoc - */ - public function executeList(array $ids) - { - $this->execute($ids); - } - - /** - * @inheritdoc - */ - public function executeRow($id) - { - $this->execute([$id]); - } -} diff --git a/src/module-vsbridge-indexer-agreement/etc/di.xml b/src/module-vsbridge-indexer-agreement/etc/di.xml index 3ec84e5a..557a0350 100644 --- a/src/module-vsbridge-indexer-agreement/etc/di.xml +++ b/src/module-vsbridge-indexer-agreement/etc/di.xml @@ -1,15 +1,18 @@ - + + - vue_storefront_catalog agreement - + + - Divante\VsbridgeIndexerAgreement\Indexer\AgreementIndexerHandlerVirtual + + Divante\VsbridgeIndexerAgreement\Model\Indexer\Action\Agreement + diff --git a/src/module-vsbridge-indexer-agreement/etc/vsbridge.xml b/src/module-vsbridge-indexer-agreement/etc/vsbridge.xml new file mode 100644 index 00000000..26884c27 --- /dev/null +++ b/src/module-vsbridge-indexer-agreement/etc/vsbridge.xml @@ -0,0 +1,4 @@ + + + diff --git a/src/module-vsbridge-indexer-agreement/etc/vsbridge_indices.xml b/src/module-vsbridge-indexer-agreement/etc/vsbridge_indices.xml deleted file mode 100644 index 3e540428..00000000 --- a/src/module-vsbridge-indexer-agreement/etc/vsbridge_indices.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - diff --git a/src/module-vsbridge-indexer-catalog/ArrayConverter/Product/CustomOptionConverter.php b/src/module-vsbridge-indexer-catalog/ArrayConverter/Product/CustomOptionConverter.php index ef313517..eb0b1958 100644 --- a/src/module-vsbridge-indexer-catalog/ArrayConverter/Product/CustomOptionConverter.php +++ b/src/module-vsbridge-indexer-catalog/ArrayConverter/Product/CustomOptionConverter.php @@ -9,7 +9,7 @@ namespace Divante\VsbridgeIndexerCatalog\ArrayConverter\Product; -use Divante\VsbridgeIndexerCore\Indexer\DataFilter; +use Divante\VsbridgeIndexerCore\Index\DataFilter; use Divante\VsbridgeIndexerCatalog\Api\ArrayConverter\Product\CustomOptionConverterInterface; /** @@ -60,7 +60,7 @@ public function process(array $options, array $optionValues): array $optionValue = $this->prepareValue($optionValue); $options[$optionId]['values'][] = $optionValue; } - + foreach ($options as $option) { $productId = $option['product_id']; $option = $this->prepareOption($option); @@ -77,7 +77,7 @@ public function process(array $options, array $optionValues): array */ private function prepareValue(array $option): array { - $option = $this->unsetFields($option); + $option = $this->filterData($option); unset($option['option_id']); return $option; @@ -88,9 +88,13 @@ private function prepareValue(array $option): array * * @return array */ - private function unsetFields(array $option): array + private function filterData(array $option): array { $option = $this->dataFilter->execute($option, $this->fieldsToDelete); + $option['sort_order'] = (int) $option['sort_order']; + $option['option_id'] = (int) $option['sort_order']; + $option['option_type_id'] = (int) $option['sort_order']; + $option['price'] = (float) $option['price']; if (isset($option['sku']) !== true) { unset($option['sku']); @@ -110,9 +114,8 @@ private function unsetFields(array $option): array */ private function prepareOption(array $option): array { - $option = $this->unsetFields($option); - - $option = $this->dataFilter->execute($option, $this->fieldsToDelete); + $option['is_require'] = (boolean)$option['is_require']; + $option = $this->filterData($option); if ('drop_down' === $option['type']) { $option['type'] = 'select'; diff --git a/src/module-vsbridge-indexer-catalog/Console/Command/IndexerInfoCommand.php b/src/module-vsbridge-indexer-catalog/Console/Command/IndexerInfoCommand.php deleted file mode 100644 index 387b69e1..00000000 --- a/src/module-vsbridge-indexer-catalog/Console/Command/IndexerInfoCommand.php +++ /dev/null @@ -1,28 +0,0 @@ - - * @copyright 2020 Divante Sp. z o.o. - * @license See LICENSE_DIVANTE.txt for license details. - */ - -namespace Divante\VsbridgeIndexerCatalog\Console\Command; - -use Divante\VsbridgeIndexerCatalog\Model\Indexer\ProductCategoryProcessor; - -/** - * @inheritDoc - */ -class IndexerInfoCommand extends \Magento\Indexer\Console\Command\IndexerInfoCommand -{ - /** - * @inheritdoc - */ - protected function getAllIndexers() - { - $indexers = parent::getAllIndexers(); - unset($indexers[ProductCategoryProcessor::INDEXER_ID]); - - return $indexers; - } -} diff --git a/src/module-vsbridge-indexer-catalog/Console/Command/IndexerReindexCommand.php b/src/module-vsbridge-indexer-catalog/Console/Command/IndexerReindexCommand.php deleted file mode 100644 index d77490d1..00000000 --- a/src/module-vsbridge-indexer-catalog/Console/Command/IndexerReindexCommand.php +++ /dev/null @@ -1,29 +0,0 @@ - - * @copyright 2019 Divante Sp. z o.o. - * @license See LICENSE_DIVANTE.txt for license details. - */ - -namespace Divante\VsbridgeIndexerCatalog\Console\Command; - -use Divante\VsbridgeIndexerCatalog\Model\Indexer\ProductCategoryProcessor; -use Symfony\Component\Console\Input\InputInterface; - -/** - * Class IndexerReindexCommand - */ -class IndexerReindexCommand extends \Magento\Indexer\Console\Command\IndexerReindexCommand -{ - /** - * @inheritdoc - */ - protected function getAllIndexers() - { - $indexers = parent::getAllIndexers(); - unset($indexers[ProductCategoryProcessor::INDEXER_ID]); - - return $indexers; - } -} diff --git a/src/module-vsbridge-indexer-catalog/Model/Indexer/Action/Attribute.php b/src/module-vsbridge-indexer-catalog/Model/Indexer/Action/Attribute.php index 306c4159..089b639d 100644 --- a/src/module-vsbridge-indexer-catalog/Model/Indexer/Action/Attribute.php +++ b/src/module-vsbridge-indexer-catalog/Model/Indexer/Action/Attribute.php @@ -1,21 +1,16 @@ - * @copyright 2019 Divante Sp. z o.o. - * @license See LICENSE_DIVANTE.txt for license details. - */ namespace Divante\VsbridgeIndexerCatalog\Model\Indexer\Action; use Divante\VsbridgeIndexerCatalog\Model\ResourceModel\Attribute as ResourceModel; use Divante\VsbridgeIndexerCatalog\Index\Mapping\Attribute as AttributeMapping; use Divante\VsbridgeIndexerCore\Api\ConvertValueInterface; +use Divante\VsbridgeIndexerCore\Indexer\RebuildActionInterface; /** * Class Attribute */ -class Attribute +class Attribute implements RebuildActionInterface { /** * @var ResourceModel @@ -50,11 +45,12 @@ public function __construct( } /** + * @param int $storeId * @param array $attributeIds * * @return \Traversable */ - public function rebuild(array $attributeIds = []) + public function rebuild(int $storeId, array $attributeIds): \Traversable { $lastAttributeId = 0; diff --git a/src/module-vsbridge-indexer-catalog/Model/Indexer/Action/Category.php b/src/module-vsbridge-indexer-catalog/Model/Indexer/Action/Category.php index 813da968..f44a6953 100644 --- a/src/module-vsbridge-indexer-catalog/Model/Indexer/Action/Category.php +++ b/src/module-vsbridge-indexer-catalog/Model/Indexer/Action/Category.php @@ -1,19 +1,14 @@ - * @copyright 2019 Divante Sp. z o.o. - * @license See LICENSE_DIVANTE.txt for license details. - */ namespace Divante\VsbridgeIndexerCatalog\Model\Indexer\Action; use Divante\VsbridgeIndexerCatalog\Model\ResourceModel\Category as ResourceModel; +use Divante\VsbridgeIndexerCore\Indexer\RebuildActionInterface; /** * Class Category */ -class Category +class Category implements RebuildActionInterface { /** * @var ResourceModel @@ -37,7 +32,7 @@ public function __construct(ResourceModel $resourceModel) * @return \Generator * @throws \Magento\Framework\Exception\NoSuchEntityException */ - public function rebuild($storeId = 1, array $categoryIds = []) + public function rebuild(int $storeId, array $categoryIds): \Traversable { $lastCategoryId = 0; @@ -50,10 +45,9 @@ public function rebuild($storeId = 1, array $categoryIds = []) foreach ($categories as $category) { $lastCategoryId = $category['entity_id']; - $categoryData['id'] = (int)$category['entity_id']; - $categoryData = $category; + $category['id'] = (int)$category['entity_id']; - yield $lastCategoryId => $categoryData; + yield $lastCategoryId => $category; } } while (!empty($categories)); } diff --git a/src/module-vsbridge-indexer-catalog/Model/Indexer/Action/Product.php b/src/module-vsbridge-indexer-catalog/Model/Indexer/Action/Product.php index c9817921..ad4f31c4 100644 --- a/src/module-vsbridge-indexer-catalog/Model/Indexer/Action/Product.php +++ b/src/module-vsbridge-indexer-catalog/Model/Indexer/Action/Product.php @@ -1,19 +1,14 @@ - * @copyright 2019 Divante Sp. z o.o. - * @license See LICENSE_DIVANTE.txt for license details. - */ namespace Divante\VsbridgeIndexerCatalog\Model\Indexer\Action; use Divante\VsbridgeIndexerCatalog\Model\ResourceModel\Product as ResourceModel; +use Divante\VsbridgeIndexerCore\Indexer\RebuildActionInterface; /** * Class Product */ -class Product +class Product implements RebuildActionInterface { /** * @var ResourceModel @@ -38,7 +33,7 @@ public function __construct(ResourceModel $resourceModel) * @throws \Magento\Framework\Exception\LocalizedException * @throws \Magento\Framework\Exception\NoSuchEntityException */ - public function rebuild($storeId = 1, array $productIds = []) + public function rebuild(int $storeId, array $productIds) : \Traversable { $lastProductId = 0; diff --git a/src/module-vsbridge-indexer-catalog/Model/Indexer/Attribute.php b/src/module-vsbridge-indexer-catalog/Model/Indexer/Attribute.php deleted file mode 100644 index fd462a48..00000000 --- a/src/module-vsbridge-indexer-catalog/Model/Indexer/Attribute.php +++ /dev/null @@ -1,95 +0,0 @@ - - * @copyright 2019 Divante Sp. z o.o. - * @license See LICENSE_DIVANTE.txt for license details. - */ - -namespace Divante\VsbridgeIndexerCatalog\Model\Indexer; - -use Divante\VsbridgeIndexerCatalog\Model\Indexer\Action\Attribute as AttributeAction; -use Divante\VsbridgeIndexerCore\Indexer\GenericIndexerHandler; -use Divante\VsbridgeIndexerCore\Indexer\StoreManager; - -/** - * Class Attribute - */ -class Attribute implements \Magento\Framework\Indexer\ActionInterface, \Magento\Framework\Mview\ActionInterface -{ - /** - * @var GenericIndexerHandler - */ - private $indexHandler; - - /** - * @var AttributeAction - */ - private $attributeAction; - - /** - * @var StoreManager - */ - private $storeManager; - - /** - * Attribute constructor. - * - * @param GenericIndexerHandler $indexerHandler - * @param StoreManager $storeManager - * @param AttributeAction $action - */ - public function __construct( - GenericIndexerHandler $indexerHandler, - StoreManager $storeManager, - AttributeAction $action - ) { - $this->indexHandler = $indexerHandler; - $this->attributeAction = $action; - $this->storeManager = $storeManager; - } - - /** - * @param int[] $ids - * - * @throws \Magento\Framework\Exception\NoSuchEntityException - */ - public function execute($ids) - { - $stores = $this->storeManager->getStores(); - - foreach ($stores as $store) { - $this->indexHandler->saveIndex($this->attributeAction->rebuild($ids), $store); - $this->indexHandler->cleanUpByTransactionKey($store, $ids); - } - } - - /** - * @inheritdoc - */ - public function executeFull() - { - $stores = $this->storeManager->getStores(); - - foreach ($stores as $store) { - $this->indexHandler->saveIndex($this->attributeAction->rebuild(), $store); - $this->indexHandler->cleanUpByTransactionKey($store); - } - } - - /** - * @inheritdoc - */ - public function executeList(array $ids) - { - $this->execute($ids); - } - - /** - * @inheritdoc - */ - public function executeRow($id) - { - $this->execute([$id]); - } -} diff --git a/src/module-vsbridge-indexer-catalog/Model/Indexer/Category.php b/src/module-vsbridge-indexer-catalog/Model/Indexer/Category.php deleted file mode 100644 index 59cc2653..00000000 --- a/src/module-vsbridge-indexer-catalog/Model/Indexer/Category.php +++ /dev/null @@ -1,105 +0,0 @@ - - * @copyright 2019 Divante Sp. z o.o. - * @license See LICENSE_DIVANTE.txt for license details. - */ - -namespace Divante\VsbridgeIndexerCatalog\Model\Indexer; - -use Divante\VsbridgeIndexerCatalog\Model\Indexer\Action\Category as Action; -use Divante\VsbridgeIndexerCore\Indexer\GenericIndexerHandler; -use Divante\VsbridgeIndexerCore\Indexer\StoreManager; -use Divante\VsbridgeIndexerCore\Cache\Processor as CacheProcessor; - -/** - * Class Category - */ -class Category implements \Magento\Framework\Indexer\ActionInterface, \Magento\Framework\Mview\ActionInterface -{ - /** - * @var GenericIndexerHandler - */ - private $indexHandler; - - /** - * @var Action - */ - private $categoryAction; - - /** - * @var StoreManager - */ - private $storeManager; - - /** - * @var CacheProcessor - */ - private $cacheProcessor; - - /** - * Category constructor. - * - * @param CacheProcessor $cacheProcessor - * @param GenericIndexerHandler $indexerHandler - * @param StoreManager $storeManager - * @param Action $action - */ - public function __construct( - CacheProcessor $cacheProcessor, - GenericIndexerHandler $indexerHandler, - StoreManager $storeManager, - Action $action - ) { - $this->categoryAction = $action; - $this->storeManager = $storeManager; - $this->indexHandler = $indexerHandler; - $this->cacheProcessor = $cacheProcessor; - } - - /** - * @inheritdoc - */ - public function execute($ids) - { - $stores = $this->storeManager->getStores(); - - foreach ($stores as $store) { - $storeId = $store->getId(); - $this->indexHandler->saveIndex($this->categoryAction->rebuild($storeId, $ids), $store); - $this->indexHandler->cleanUpByTransactionKey($store, $ids); - $this->cacheProcessor->cleanCacheByDocIds($storeId, $this->indexHandler->getTypeName(), $ids); - } - } - - /** - * @inheritdoc - */ - public function executeFull() - { - $stores = $this->storeManager->getStores(); - - foreach ($stores as $store) { - $this->indexHandler->saveIndex($this->categoryAction->rebuild($store->getId()), $store); - $this->indexHandler->cleanUpByTransactionKey($store); - $this->cacheProcessor->cleanCacheByTags($store->getId(), [$this->indexHandler->getTypeName()]); - } - } - - /** - * @inheritdoc - */ - public function executeList(array $ids) - { - $this->execute($ids); - } - - /** - * @inheritdoc - */ - public function executeRow($id) - { - $this->execute([$id]); - } -} diff --git a/src/module-vsbridge-indexer-catalog/Model/Indexer/DataProvider/Category/AttributeData.php b/src/module-vsbridge-indexer-catalog/Model/Indexer/DataProvider/Category/AttributeData.php index 733708bc..12cb74b4 100644 --- a/src/module-vsbridge-indexer-catalog/Model/Indexer/DataProvider/Category/AttributeData.php +++ b/src/module-vsbridge-indexer-catalog/Model/Indexer/DataProvider/Category/AttributeData.php @@ -9,7 +9,6 @@ namespace Divante\VsbridgeIndexerCatalog\Model\Indexer\DataProvider\Category; use Divante\VsbridgeIndexerCatalog\Model\ResourceModel\Category\Children as CategoryChildrenResource; -use Divante\VsbridgeIndexerCore\Indexer\DataFilter; use Divante\VsbridgeIndexerCatalog\Model\Attributes\CategoryAttributes; use Divante\VsbridgeIndexerCatalog\Model\Attributes\CategoryChildAttributes; use Divante\VsbridgeIndexerCatalog\Model\SystemConfig\CategoryConfigInterface; @@ -66,11 +65,6 @@ class AttributeData implements AttributeDataProviderInterface */ private $productCountResource; - /** - * @var \Divante\VsbridgeIndexerCore\Indexer\DataFilter - */ - private $dataFilter; - /** * @var array */ @@ -101,7 +95,6 @@ class AttributeData implements AttributeDataProviderInterface * @param CategoryConfigInterface $configSettings * @param CategoryAttributes $categoryAttributes * @param CategoryChildAttributes $categoryChildAttributes - * @param DataFilter $dataFilter */ public function __construct( AttributeDataProvider $attributeResource, @@ -110,15 +103,13 @@ public function __construct( ApplyCategorySlugInterface $applyCategorySlug, CategoryConfigInterface $configSettings, CategoryAttributes $categoryAttributes, - CategoryChildAttributes $categoryChildAttributes, - DataFilter $dataFilter + CategoryChildAttributes $categoryChildAttributes ) { $this->settings = $configSettings; $this->applyCategorySlug = $applyCategorySlug; $this->productCountResource = $productCountResource; $this->attributeResourceModel = $attributeResource; $this->childrenResourceModel = $childrenResource; - $this->dataFilter = $dataFilter; $this->categoryAttributes = $categoryAttributes; $this->childAttributes = $categoryChildAttributes; } @@ -285,7 +276,9 @@ private function prepareCategory(array $categoryDTO, int $storeId) } $categoryDTO = array_diff_key($categoryDTO, array_flip($this->fieldsToRemove)); - $categoryDTO = $this->filterData($categoryDTO); + $categoryDTO['parent_id'] = (int) $categoryDTO['parent_id']; + $categoryDTO['position'] = (int) $categoryDTO['position']; + $categoryDTO['level'] = (int) $categoryDTO['level']; return $categoryDTO; } @@ -341,22 +334,4 @@ private function addSlug(array $categoryDTO) { return $this->applyCategorySlug->execute($categoryDTO); } - - /** - * @param array $categoryData - * - * @return array - */ - private function filterData(array $categoryData) - { - return $this->getDataFilter()->execute($categoryData); - } - - /** - * @return DataFilter - */ - private function getDataFilter() - { - return $this->dataFilter; - } } diff --git a/src/module-vsbridge-indexer-catalog/Model/Indexer/DataProvider/Product/AttributeData.php b/src/module-vsbridge-indexer-catalog/Model/Indexer/DataProvider/Product/AttributeData.php index dacf52f4..0e707368 100644 --- a/src/module-vsbridge-indexer-catalog/Model/Indexer/DataProvider/Product/AttributeData.php +++ b/src/module-vsbridge-indexer-catalog/Model/Indexer/DataProvider/Product/AttributeData.php @@ -10,7 +10,6 @@ use Divante\VsbridgeIndexerCatalog\Model\ResourceModel\Product\AttributeDataProvider; use Divante\VsbridgeIndexerCore\Api\DataProviderInterface; -use Divante\VsbridgeIndexerCore\Indexer\DataFilter; use Divante\VsbridgeIndexerCatalog\Api\CatalogConfigurationInterface; use Divante\VsbridgeIndexerCatalog\Api\SlugGeneratorInterface; use Divante\VsbridgeIndexerCatalog\Model\ProductUrlPathGenerator; @@ -26,11 +25,6 @@ class AttributeData implements DataProviderInterface */ private $resourceModel; - /** - * @var DataFilter - */ - private $dataFilter; - /** * @var CatalogConfigurationInterface */ @@ -54,10 +48,10 @@ class AttributeData implements DataProviderInterface /** * AttributeData constructor. * + * @param ProductAttributes $productAttributes * @param CatalogConfigurationInterface $configSettings * @param SlugGeneratorInterface $slugGenerator * @param ProductUrlPathGenerator $productUrlPathGenerator - * @param DataFilter $dataFilter * @param AttributeDataProvider $resourceModel */ public function __construct( @@ -65,13 +59,11 @@ public function __construct( CatalogConfigurationInterface $configSettings, SlugGeneratorInterface $slugGenerator, ProductUrlPathGenerator $productUrlPathGenerator, - DataFilter $dataFilter, AttributeDataProvider $resourceModel ) { $this->slugGenerator = $slugGenerator; $this->settings = $configSettings; $this->resourceModel = $resourceModel; - $this->dataFilter = $dataFilter; $this->productAttributes = $productAttributes; $this->productUrlPathGenerator = $productUrlPathGenerator; } diff --git a/src/module-vsbridge-indexer-catalog/Model/Indexer/DataProvider/Product/ConfigurableData.php b/src/module-vsbridge-indexer-catalog/Model/Indexer/DataProvider/Product/ConfigurableData.php index a4f7ad27..00debab0 100644 --- a/src/module-vsbridge-indexer-catalog/Model/Indexer/DataProvider/Product/ConfigurableData.php +++ b/src/module-vsbridge-indexer-catalog/Model/Indexer/DataProvider/Product/ConfigurableData.php @@ -9,7 +9,7 @@ namespace Divante\VsbridgeIndexerCatalog\Model\Indexer\DataProvider\Product; use Divante\VsbridgeIndexerCore\Api\DataProviderInterface; -use Divante\VsbridgeIndexerCore\Indexer\DataFilter; +use Divante\VsbridgeIndexerCore\Index\DataFilter; use Divante\VsbridgeIndexerCatalog\Api\LoadInventoryInterface; use Divante\VsbridgeIndexerCatalog\Model\Indexer\DataProvider\Product\Configurable\LoadChildrenRawAttributes; diff --git a/src/module-vsbridge-indexer-catalog/Model/Indexer/DataProvider/Product/ProductLinksData.php b/src/module-vsbridge-indexer-catalog/Model/Indexer/DataProvider/Product/ProductLinksData.php index 45b5e34f..4d3096f2 100644 --- a/src/module-vsbridge-indexer-catalog/Model/Indexer/DataProvider/Product/ProductLinksData.php +++ b/src/module-vsbridge-indexer-catalog/Model/Indexer/DataProvider/Product/ProductLinksData.php @@ -40,8 +40,8 @@ public function addData(array $indexData, $storeId) $this->resourceModel->clear(); $this->resourceModel->setProducts($indexData); - foreach ($indexData as &$productDTO) { - $productDTO['product_links'] = $this->resourceModel->getLinkedProduct($productDTO); + foreach ($indexData as $productId => $productDTO) { + $indexData[$productId]['product_links'] = $this->resourceModel->getLinkedProduct($productDTO); } $this->resourceModel->clear(); diff --git a/src/module-vsbridge-indexer-catalog/Model/Indexer/Product.php b/src/module-vsbridge-indexer-catalog/Model/Indexer/Product.php deleted file mode 100644 index 6fd3a418..00000000 --- a/src/module-vsbridge-indexer-catalog/Model/Indexer/Product.php +++ /dev/null @@ -1,106 +0,0 @@ - - * @copyright 2019 Divante Sp. z o.o. - * @license See LICENSE_DIVANTE.txt for license details. - */ - -namespace Divante\VsbridgeIndexerCatalog\Model\Indexer; - -use Divante\VsbridgeIndexerCatalog\Model\Indexer\Action\Product as ProductAction; - -use Divante\VsbridgeIndexerCore\Indexer\StoreManager; -use Divante\VsbridgeIndexerCore\Indexer\GenericIndexerHandler; -use Divante\VsbridgeIndexerCore\Cache\Processor as CacheProcessor; - -/** - * Class Product - */ -class Product implements \Magento\Framework\Indexer\ActionInterface, \Magento\Framework\Mview\ActionInterface -{ - /** - * @var GenericIndexerHandler - */ - private $indexHandler; - - /** - * @var ProductAction - */ - private $productAction; - - /** - * @var StoreManager - */ - private $storeManager; - - /** - * @var CacheProcessor - */ - private $cacheProcessor; - - /** - * Product constructor. - * - * @param CacheProcessor $cacheProcessor - * @param GenericIndexerHandler $indexerHandler - * @param StoreManager $storeManager - * @param ProductAction $action - */ - public function __construct( - CacheProcessor $cacheProcessor, - GenericIndexerHandler $indexerHandler, - StoreManager $storeManager, - ProductAction $action - ) { - $this->productAction = $action; - $this->indexHandler = $indexerHandler; - $this->storeManager = $storeManager; - $this->cacheProcessor = $cacheProcessor; - } - - /** - * @inheritdoc - */ - public function execute($ids) - { - $stores = $this->storeManager->getStores(); - - foreach ($stores as $store) { - $storeId = $store->getId(); - $this->indexHandler->saveIndex($this->productAction->rebuild($storeId, $ids), $store); - $this->indexHandler->cleanUpByTransactionKey($store, $ids); - $this->cacheProcessor->cleanCacheByDocIds($storeId, $this->indexHandler->getTypeName(), $ids); - } - } - - /** - * @inheritdoc - */ - public function executeFull() - { - $stores = $this->storeManager->getStores(); - - foreach ($stores as $store) { - $this->indexHandler->saveIndex($this->productAction->rebuild($store->getId()), $store); - $this->indexHandler->cleanUpByTransactionKey($store); - $this->cacheProcessor->cleanCacheByTags($store->getId(), [$this->indexHandler->getTypeName()]); - } - } - - /** - * @inheritdoc - */ - public function executeList(array $ids) - { - $this->execute($ids); - } - - /** - * @inheritdoc - */ - public function executeRow($id) - { - $this->execute([$id]); - } -} diff --git a/src/module-vsbridge-indexer-catalog/Model/Indexer/ProductCategory.php b/src/module-vsbridge-indexer-catalog/Model/Indexer/ProductCategory.php deleted file mode 100644 index 038c1c61..00000000 --- a/src/module-vsbridge-indexer-catalog/Model/Indexer/ProductCategory.php +++ /dev/null @@ -1,115 +0,0 @@ - - * @copyright 2019 Divante Sp. z o.o. - * @license See LICENSE_DIVANTE.txt for license details. - */ - -namespace Divante\VsbridgeIndexerCatalog\Model\Indexer; - -use Divante\VsbridgeIndexerCatalog\Model\Indexer\Action\Product as ProductAction; -use Divante\VsbridgeIndexerCore\Indexer\GenericIndexerHandler; -use Divante\VsbridgeIndexerCore\Indexer\StoreManager; -use Divante\VsbridgeIndexerCore\Cache\Processor as CacheProcessor; - -/** - * Class ProductCategory - */ -class ProductCategory implements \Magento\Framework\Indexer\ActionInterface, \Magento\Framework\Mview\ActionInterface -{ - /** - * @var GenericIndexerHandler - */ - private $indexHandler; - - /** - * @var ProductAction - */ - private $productAction; - - /** - * @var StoreManager - */ - private $storeManager; - - /** - * @var CacheProcessor - */ - private $cacheProcessor; - - /** - * Category constructor. - * - * @param CacheProcessor $cacheProcessor - * @param GenericIndexerHandler $indexerHandler - * @param StoreManager $storeManager - * @param ProductAction $action - */ - public function __construct( - CacheProcessor $cacheProcessor, - GenericIndexerHandler $indexerHandler, - StoreManager $storeManager, - ProductAction $action - ) { - $this->productAction = $action; - $this->storeManager = $storeManager; - $this->indexHandler = $indexerHandler; - $this->cacheProcessor = $cacheProcessor; - } - - /** - * @inheritdoc - */ - public function execute($ids) - { - $stores = $this->storeManager->getStores(); - - foreach ($stores as $store) { - $this->rebuild($store, $ids); - } - } - - /** - * @inheritdoc - */ - public function executeFull() - { - $stores = $this->storeManager->getStores(); - - foreach ($stores as $store) { - $this->rebuild($store); - } - } - - /** - * @param \Magento\Store\Api\Data\StoreInterface $store - * @param array $productIds - * - * @throws \Magento\Framework\Exception\NoSuchEntityException - */ - private function rebuild($store, array $productIds = []) - { - $this->indexHandler->updateIndex( - $this->productAction->rebuild($store->getId(), $productIds), - $store, - ['category_data'] - ); - } - - /** - * @inheritdoc - */ - public function executeList(array $ids) - { - $this->execute($ids); - } - - /** - * @inheritdoc - */ - public function executeRow($id) - { - $this->execute([$id]); - } -} diff --git a/src/module-vsbridge-indexer-catalog/Model/Indexer/ProductCategoryProcessor.php b/src/module-vsbridge-indexer-catalog/Model/Indexer/ProductCategoryProcessor.php deleted file mode 100644 index b53e31ef..00000000 --- a/src/module-vsbridge-indexer-catalog/Model/Indexer/ProductCategoryProcessor.php +++ /dev/null @@ -1,30 +0,0 @@ - - * @copyright 2019 Divante Sp. z o.o. - * @license See LICENSE_DIVANTE.txt for license details. - */ - -namespace Divante\VsbridgeIndexerCatalog\Model\Indexer; - -/** - * Class ProductCategoryProcessor - */ -class ProductCategoryProcessor extends \Magento\Framework\Indexer\AbstractProcessor -{ - /** - * Indexer ID - */ - const INDEXER_ID = 'vsbridge_product_category'; - - /** - * Mark Vsbridge Product indexer as invalid - * - * @return void - */ - public function markIndexerAsInvalid() - { - $this->getIndexer()->invalidate(); - } -} diff --git a/src/module-vsbridge-indexer-catalog/Model/Product/LoadTierPrices.php b/src/module-vsbridge-indexer-catalog/Model/Product/LoadTierPrices.php index fcb84069..cbe6613d 100644 --- a/src/module-vsbridge-indexer-catalog/Model/Product/LoadTierPrices.php +++ b/src/module-vsbridge-indexer-catalog/Model/Product/LoadTierPrices.php @@ -80,37 +80,38 @@ public function __construct( */ public function execute(array $indexData, int $storeId): array { - if ($this->syncTierPrices()) { - $linkField = $this->productMetaData->get()->getLinkField(); - $linkFieldIds = array_column($indexData, $linkField); - $websiteId = $this->getWebsiteId($storeId); - - $tierPrices = $this->tierPriceResource->loadTierPrices($websiteId, $linkFieldIds); - /** @var \Magento\Catalog\Model\Product\Attribute\Backend\TierPrice $backend */ - $backend = $this->getTierPriceAttribute()->getBackend(); - - foreach ($indexData as $productId => $product) { - $linkFieldValue = $product[$linkField]; - - if (isset($tierPrices[$linkFieldValue])) { - $tierRowsData = $tierPrices[$linkFieldValue]; - $tierRowsData = $backend->preparePriceData( - $tierRowsData, - $indexData[$productId]['type_id'], - $websiteId - ); - - foreach ($tierRowsData as $tierRowData) { - if (Group::NOT_LOGGED_IN_ID === $tierRowData['cust_group'] && $tierRowData['price_qty'] == 1) { - $price = (float) $indexData[$productId]['price']; - $price = min((float) $tierRowData['price'], $price); - $indexData[$productId]['price'] = $price; - } - - $indexData[$productId]['tier_prices'][] = $this->prepareTierPrices($tierRowData); + if (!$this->syncTierPrices()) { + return $indexData; + } + + $linkField = $this->productMetaData->get()->getLinkField(); + $linkFieldIds = array_column($indexData, $linkField); + $websiteId = $this->getWebsiteId($storeId); + + $tierPrices = $this->tierPriceResource->loadTierPrices($websiteId, $linkFieldIds); + /** @var \Magento\Catalog\Model\Product\Attribute\Backend\TierPrice $backend */ + $backend = $this->getTierPriceAttribute()->getBackend(); + + foreach ($indexData as $productId => $product) { + $linkFieldValue = $product[$linkField]; + $indexData[$productId]['tier_prices'] = []; + + if (isset($tierPrices[$linkFieldValue])) { + $tierRowsData = $tierPrices[$linkFieldValue]; + $tierRowsData = $backend->preparePriceData( + $tierRowsData, + $indexData[$productId]['type_id'], + $websiteId + ); + + foreach ($tierRowsData as $tierRowData) { + if (Group::NOT_LOGGED_IN_ID === $tierRowData['cust_group'] && $tierRowData['price_qty'] == 1) { + $price = (float) $indexData[$productId]['price']; + $price = min((float) $tierRowData['price'], $price); + $indexData[$productId]['price'] = $price; } - } else { - $indexData[$productId]['tier_prices'] = []; + + $indexData[$productId]['tier_prices'][] = $this->prepareTierPrices($tierRowData); } } } @@ -150,15 +151,10 @@ private function prepareTierPrices(array $productTierPrice) private function getWebsiteId($storeId) { $attribute = $this->getTierPriceAttribute(); - $websiteId = 0; - - if ($attribute->isScopeGlobal()) { - $websiteId = 0; - } elseif ($storeId) { - $websiteId = (int) ($this->storeManager->getStore($storeId)->getWebsiteId()); - } - return $websiteId; + return $attribute->isScopeGlobal() + ? 0 + : $this->storeManager->getStore($storeId)->getWebsiteId(); } /** diff --git a/src/module-vsbridge-indexer-catalog/Model/ResourceModel/Product/Category.php b/src/module-vsbridge-indexer-catalog/Model/ResourceModel/Product/Category.php index 0796ea2a..ad4c1ad2 100644 --- a/src/module-vsbridge-indexer-catalog/Model/ResourceModel/Product/Category.php +++ b/src/module-vsbridge-indexer-catalog/Model/ResourceModel/Product/Category.php @@ -82,10 +82,12 @@ public function loadCategoryData($storeId, array $productIds) $storeCategoryName = $this->loadCategoryNames(array_unique($categoryIds), $storeId); - foreach ($categoryData as &$categoryDataRow) { - $categoryDataRow['name'] = ''; - if (isset($storeCategoryName[(int) $categoryDataRow['category_id']])) { - $categoryDataRow['name'] = $storeCategoryName[(int) $categoryDataRow['category_id']]; + foreach ($categoryData as $index => $categoryDataRow) { + $categoryId = (int) $categoryDataRow['category_id']; + $categoryData[$index]['name'] = ''; + + if (isset($storeCategoryName[$categoryId])) { + $categoryData[$index]['name'] = $storeCategoryName[$categoryId]; } } diff --git a/src/module-vsbridge-indexer-catalog/Plugin/Indexer/Category/Save/UpdateProductPlugin.php b/src/module-vsbridge-indexer-catalog/Plugin/Indexer/Category/Save/UpdateProductPlugin.php deleted file mode 100644 index 3a16cde7..00000000 --- a/src/module-vsbridge-indexer-catalog/Plugin/Indexer/Category/Save/UpdateProductPlugin.php +++ /dev/null @@ -1,63 +0,0 @@ - - * @copyright 2019 Divante Sp. z o.o. - * @license See LICENSE_DIVANTE.txt for license details. - */ - -namespace Divante\VsbridgeIndexerCatalog\Plugin\Indexer\Category\Save; - -use Divante\VsbridgeIndexerCatalog\Model\Indexer\ProductCategoryProcessor; -use Divante\VsbridgeIndexerCatalog\Model\Indexer\ProductProcessor; - -/** - * Class UpdateProductPlugin - */ -class UpdateProductPlugin -{ - /** - * @var ProductCategoryProcessor - */ - private $productCategoryProcessor; - - /** - * @var ProductProcessor - */ - private $productProcessor; - - /** - * UpdateProduct constructor. - * - * @param ProductProcessor $productProcessor - * @param ProductCategoryProcessor $processor - */ - public function __construct( - ProductProcessor $productProcessor, - ProductCategoryProcessor $processor - ) { - $this->productProcessor = $productProcessor; - $this->productCategoryProcessor = $processor; - } - - /** - * Update product category data in ES after changing category products - * - * @param \Magento\Catalog\Model\Category $category - * @return \Magento\Catalog\Model\Category - */ - public function afterSave(\Magento\Catalog\Model\Category $category) - { - $isChangedProductList = $category->getData('is_changed_product_list'); - - if (!$isChangedProductList) { - return $category; - } - - if (!$this->productProcessor->isIndexerScheduled() && !$this->productCategoryProcessor->isIndexerScheduled()) { - $this->productCategoryProcessor->reindexList($category->getAffectedProductIds()); - } - - return $category; - } -} diff --git a/src/module-vsbridge-indexer-catalog/Plugin/Ui/DataProvider/Indexer/DataCollectionPlugin.php b/src/module-vsbridge-indexer-catalog/Plugin/Ui/DataProvider/Indexer/DataCollectionPlugin.php deleted file mode 100644 index 9bd512e0..00000000 --- a/src/module-vsbridge-indexer-catalog/Plugin/Ui/DataProvider/Indexer/DataCollectionPlugin.php +++ /dev/null @@ -1,52 +0,0 @@ -findIndexerKey($items); - - if ($keyToRemove) { - unset($items[$keyToRemove]); - $subject->removeItemByKey($keyToRemove); - } - - return $items; - } - - /** - * @param \Magento\Framework\DataObject[] $items - * - * @return int - */ - private function findIndexerKey($items): int - { - $keyToRemove = - 1; - - foreach ($items as $key => $item) { - if ($item->getData('indexer_id') === ProductCategoryProcessor::INDEXER_ID) { - $keyToRemove = $key; - break; - } - } - - return $keyToRemove; - } -} diff --git a/src/module-vsbridge-indexer-catalog/Test/Model/LoadTierPricesTest.php b/src/module-vsbridge-indexer-catalog/Test/Model/LoadTierPricesTest.php new file mode 100644 index 00000000..f27fb675 --- /dev/null +++ b/src/module-vsbridge-indexer-catalog/Test/Model/LoadTierPricesTest.php @@ -0,0 +1,120 @@ +attributeDataProviderMock = $this->getMockBuilder(AttributeDataProvider::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->tierPriceResourceMock = $this->getMockBuilder(TierPrices::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->storeManagerMock = $this->getMockBuilder(StoreManagerInterface::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->productMetaDataMock = $this->getMockBuilder(ProductMetaData::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->configSettingsMock = $this->getMockBuilder(CatalogConfigurationInterface::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->storeMock = $this->getMockBuilder(Store::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->attributeMock = $this->getMockBuilder(Attribute::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->loadTierPrices = new LoadTierPrices( + $this->configSettingsMock, + $this->tierPriceResourceMock, + $this->storeManagerMock, + $this->productMetaDataMock, + $this->attributeDataProviderMock + ); + } + + public function testGetWebsiteIdWhenScopeIsNotGlobal() + { + $storeId = 1; + $reflector = new ReflectionClass( LoadTierPrices::class ); + $method = $reflector->getMethod( 'getWebsiteId' ); + $method->setAccessible( true ); + + $this->attributeMock->method('isScopeGlobal')->willReturn(false); + + $this->storeManagerMock->method('getStore')->willReturn($this->storeMock); + $this->storeMock->method('getWebsiteId')->willReturn(1); + + $this->attributeDataProviderMock->method('getAttributeByCode') + ->willReturn($this->attributeMock); + + $result = $method->invokeArgs( $this->loadTierPrices, array( $storeId ) ); + $this->assertEquals( 1, $result ); + } + + public function testGetWebsiteIdWhenScopeIsGlobal() + { + $storeId = 1; + $reflector = new ReflectionClass( LoadTierPrices::class ); + $method = $reflector->getMethod( 'getWebsiteId' ); + $method->setAccessible( true ); + + $this->attributeDataProviderMock->method('getAttributeByCode') + ->willReturn($this->attributeMock); + + $this->attributeMock->method('isScopeGlobal')->willReturn(true); + $result = $method->invokeArgs( $this->loadTierPrices, array( $storeId ) ); + $this->assertEquals( 0, $result ); + } +} diff --git a/src/module-vsbridge-indexer-catalog/etc/di.xml b/src/module-vsbridge-indexer-catalog/etc/di.xml index ce759c93..efb29f24 100644 --- a/src/module-vsbridge-indexer-catalog/etc/di.xml +++ b/src/module-vsbridge-indexer-catalog/etc/di.xml @@ -1,8 +1,5 @@ - - - @@ -38,101 +35,55 @@ - + - vue_storefront_catalog - product + attribute - + + - vue_storefront_catalog - product + category - + + - vue_storefront_catalog - category + product - - vue_storefront_catalog - attribute + product - - - - - - - - - - Divante\VsbridgeIndexerCatalog\Indexer\ProductIndexerHandlerVirtual - - Divante\VsbridgeIndexerCatalog\Indexer\ProductCategoryHandlerVirtual - - - Divante\VsbridgeIndexerCatalog\Indexer\CategoryIndexerHandlerVirtual - - - - - Divante\VsbridgeIndexerCatalog\Indexer\AttributeIndexerHandlerVirtual - - - + - - level - id - parent_id - position - children_count + + Divante\VsbridgeIndexerCatalog\Model\Indexer\Action\Attribute + Divante\VsbridgeIndexerCatalog\Model\Indexer\Action\Product + Divante\VsbridgeIndexerCatalog\Model\Indexer\Action\Category - - - - Divante\VsbridgeIndexerCatalog\Indexer\CategoryDataFilterVirtual - - - - - sort_order - option_id - option_type_id - - - price - - - - - - Divante\VsbridgeIndexerCatalog\Indexer\CustomOptionsDataFilterVirtual - + + + @@ -179,7 +130,6 @@ - @@ -274,10 +224,27 @@ - - - - Divante\VsbridgeIndexerCatalog\Model\Indexer\ProductCategoryProcessor::INDEXER_ID + + + + + Divante\VsbridgeIndexerCatalog\Model\Indexer\DataProvider\Product\AttributeData + Divante\VsbridgeIndexerCatalog\Model\Indexer\DataProvider\Product\BundleOptionsData + Divante\VsbridgeIndexerCatalog\Model\Indexer\DataProvider\Product\CategoryData + Divante\VsbridgeIndexerCatalog\Model\Indexer\DataProvider\Product\PriceData + Divante\VsbridgeIndexerCatalog\Model\Indexer\DataProvider\Product\MediaGalleryData + Divante\VsbridgeIndexerCatalog\Model\Indexer\DataProvider\Product\ProductLinksData + Divante\VsbridgeIndexerCatalog\Model\Indexer\DataProvider\Product\Inventory + Divante\VsbridgeIndexerCatalog\Model\Indexer\DataProvider\Product\ConfigurableData + Divante\VsbridgeIndexerCatalog\Model\Indexer\DataProvider\Product\CustomOptions + Divante\VsbridgeIndexerCatalog\Model\Indexer\DataProvider\Product\AttributesMetadata + + + Divante\VsbridgeIndexerCatalog\Model\Indexer\DataProvider\Category\AttributeData + + + Divante\VsbridgeIndexerCatalog\Model\Indexer\DataProvider\Attribute\Options + diff --git a/src/module-vsbridge-indexer-catalog/etc/indexer.xml b/src/module-vsbridge-indexer-catalog/etc/indexer.xml index ce3eed4c..d1322e28 100644 --- a/src/module-vsbridge-indexer-catalog/etc/indexer.xml +++ b/src/module-vsbridge-indexer-catalog/etc/indexer.xml @@ -19,9 +19,4 @@ Vsbridge Attributes Indexer Update Product Attributes Meta Data in Elastic - - Vsbridge Product Category Indexer - Partial Product update - update category, category_ids fields in ES - diff --git a/src/module-vsbridge-indexer-catalog/etc/mview.xml b/src/module-vsbridge-indexer-catalog/etc/mview.xml index 123a0a42..d623ab6f 100644 --- a/src/module-vsbridge-indexer-catalog/etc/mview.xml +++ b/src/module-vsbridge-indexer-catalog/etc/mview.xml @@ -18,10 +18,6 @@ - - - - diff --git a/src/module-vsbridge-indexer-catalog/etc/vsbridge.xml b/src/module-vsbridge-indexer-catalog/etc/vsbridge.xml new file mode 100755 index 00000000..a418c128 --- /dev/null +++ b/src/module-vsbridge-indexer-catalog/etc/vsbridge.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/src/module-vsbridge-indexer-catalog/etc/vsbridge_indices.xml b/src/module-vsbridge-indexer-catalog/etc/vsbridge_indices.xml deleted file mode 100755 index f75a53f2..00000000 --- a/src/module-vsbridge-indexer-catalog/etc/vsbridge_indices.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - Divante\VsbridgeIndexerCatalog\Model\Indexer\DataProvider\Product\AttributeData - Divante\VsbridgeIndexerCatalog\Model\Indexer\DataProvider\Product\BundleOptionsData - Divante\VsbridgeIndexerCatalog\Model\Indexer\DataProvider\Product\CategoryData - Divante\VsbridgeIndexerCatalog\Model\Indexer\DataProvider\Product\PriceData - Divante\VsbridgeIndexerCatalog\Model\Indexer\DataProvider\Product\MediaGalleryData - Divante\VsbridgeIndexerCatalog\Model\Indexer\DataProvider\Product\ProductLinksData - Divante\VsbridgeIndexerCatalog\Model\Indexer\DataProvider\Product\Inventory - Divante\VsbridgeIndexerCatalog\Model\Indexer\DataProvider\Product\ConfigurableData - Divante\VsbridgeIndexerCatalog\Model\Indexer\DataProvider\Product\CustomOptions - Divante\VsbridgeIndexerCatalog\Model\Indexer\DataProvider\Product\AttributesMetadata - Divante\VsbridgeIndexerCatalog\Model\Indexer\DataProvider\Product\ParentSku - - - - - Divante\VsbridgeIndexerCatalog\Model\Indexer\DataProvider\Category\AttributeData - - - - - Divante\VsbridgeIndexerCatalog\Model\Indexer\DataProvider\Attribute\Options - - - - diff --git a/src/module-vsbridge-indexer-cms/Model/Indexer/Action/CmsBlock.php b/src/module-vsbridge-indexer-cms/Model/Indexer/Action/CmsBlock.php index 2dc78653..bfee6629 100644 --- a/src/module-vsbridge-indexer-cms/Model/Indexer/Action/CmsBlock.php +++ b/src/module-vsbridge-indexer-cms/Model/Indexer/Action/CmsBlock.php @@ -9,11 +9,12 @@ namespace Divante\VsbridgeIndexerCms\Model\Indexer\Action; use Divante\VsbridgeIndexerCms\Model\ResourceModel\CmsBlock as CmsBlockResource; +use Divante\VsbridgeIndexerCore\Indexer\RebuildActionInterface; /** * Class CmsBlock */ -class CmsBlock +class CmsBlock implements RebuildActionInterface { /** * @var CmsBlockResource @@ -37,7 +38,7 @@ public function __construct( * * @return \Traversable */ - public function rebuild($storeId = 1, array $blockIds = []) + public function rebuild(int $storeId, array $blockIds): \Traversable { $lastBlockId = 0; diff --git a/src/module-vsbridge-indexer-cms/Model/Indexer/Action/CmsPage.php b/src/module-vsbridge-indexer-cms/Model/Indexer/Action/CmsPage.php index 157c5275..0356665d 100644 --- a/src/module-vsbridge-indexer-cms/Model/Indexer/Action/CmsPage.php +++ b/src/module-vsbridge-indexer-cms/Model/Indexer/Action/CmsPage.php @@ -9,11 +9,12 @@ namespace Divante\VsbridgeIndexerCms\Model\Indexer\Action; use Divante\VsbridgeIndexerCms\Model\ResourceModel\CmsPage as CmsPageResource; +use Divante\VsbridgeIndexerCore\Indexer\RebuildActionInterface; /** * Class CmsPage */ -class CmsPage +class CmsPage implements RebuildActionInterface { /** * @var CmsPageResource @@ -36,7 +37,7 @@ public function __construct(CmsPageResource $cmsBlockResource) * * @return \Traversable */ - public function rebuild($storeId = 1, array $pageIds = []) + public function rebuild(int $storeId, array $pageIds): \Traversable { $lastPageId = 0; @@ -46,7 +47,7 @@ public function rebuild($storeId = 1, array $pageIds = []) foreach ($cmsPages as $pageData) { $lastPageId = (int)$pageData['page_id']; $pageData['id'] = $lastPageId; - $pageData['content'] = $pageData['content']; + $pageData['content'] = (string) $pageData['content']; $pageData['active'] = (bool)$pageData['is_active']; if (isset($pageData['sort_order'])) { diff --git a/src/module-vsbridge-indexer-cms/Model/Indexer/CmsBlock.php b/src/module-vsbridge-indexer-cms/Model/Indexer/CmsBlock.php deleted file mode 100644 index 08790d7c..00000000 --- a/src/module-vsbridge-indexer-cms/Model/Indexer/CmsBlock.php +++ /dev/null @@ -1,93 +0,0 @@ - - * @copyright 2019 Divante Sp. z o.o. - * @license See LICENSE_DIVANTE.txt for license details. - */ - -namespace Divante\VsbridgeIndexerCms\Model\Indexer; - -use Divante\VsbridgeIndexerCore\Indexer\StoreManager; -use Divante\VsbridgeIndexerCms\Model\Indexer\Action\CmsBlock as CmsBlockAction; -use Divante\VsbridgeIndexerCore\Indexer\GenericIndexerHandler; - -/** - * Class CmsBlock - */ -class CmsBlock implements \Magento\Framework\Indexer\ActionInterface, \Magento\Framework\Mview\ActionInterface -{ - /** - * @var GenericIndexerHandler - */ - private $indexHandler; - - /** - * @var CmsBlockAction - */ - private $cmsBlockAction; - - /** - * @var StoreManager - */ - private $storeManager; - - /** - * CmsBlock constructor. - * - * @param GenericIndexerHandler $indexerHandler - * @param StoreManager $storeManager - * @param CmsBlockAction $action - */ - public function __construct( - GenericIndexerHandler $indexerHandler, - StoreManager $storeManager, - CmsBlockAction $action - ) { - $this->indexHandler = $indexerHandler; - $this->cmsBlockAction = $action; - $this->storeManager = $storeManager; - } - - /** - * @inheritdoc - */ - public function execute($ids) - { - $stores = $this->storeManager->getStores(); - - foreach ($stores as $store) { - $this->indexHandler->saveIndex($this->cmsBlockAction->rebuild($store->getId(), $ids), $store); - $this->indexHandler->cleanUpByTransactionKey($store, $ids); - } - } - - /** - * @inheritdoc - */ - public function executeFull() - { - $stores = $this->storeManager->getStores(); - - foreach ($stores as $store) { - $this->indexHandler->saveIndex($this->cmsBlockAction->rebuild($store->getId()), $store); - $this->indexHandler->cleanUpByTransactionKey($store); - } - } - - /** - * @inheritdoc - */ - public function executeList(array $ids) - { - $this->execute($ids); - } - - /** - * @inheritdoc - */ - public function executeRow($id) - { - $this->execute([$id]); - } -} diff --git a/src/module-vsbridge-indexer-cms/Model/Indexer/CmsPage.php b/src/module-vsbridge-indexer-cms/Model/Indexer/CmsPage.php deleted file mode 100644 index dd31f631..00000000 --- a/src/module-vsbridge-indexer-cms/Model/Indexer/CmsPage.php +++ /dev/null @@ -1,93 +0,0 @@ - - * @copyright 2019 Divante Sp. z o.o. - * @license See LICENSE_DIVANTE.txt for license details. - */ - -namespace Divante\VsbridgeIndexerCms\Model\Indexer; - -use Divante\VsbridgeIndexerCore\Indexer\StoreManager; -use Divante\VsbridgeIndexerCms\Model\Indexer\Action\CmsPage as CmsPageAction; -use Divante\VsbridgeIndexerCore\Indexer\GenericIndexerHandler; - -/** - * Class CmsPage - */ -class CmsPage implements \Magento\Framework\Indexer\ActionInterface, \Magento\Framework\Mview\ActionInterface -{ - /** - * @var GenericIndexerHandler - */ - private $indexHandler; - - /** - * @var CmsPageAction - */ - private $cmsPageAction; - - /** - * @var StoreManager - */ - private $storeManager; - - /** - * CmsBlock constructor. - * - * @param GenericIndexerHandler $indexerHandler - * @param StoreManager $storeManager - * @param CmsPageAction $action - */ - public function __construct( - GenericIndexerHandler $indexerHandler, - StoreManager $storeManager, - CmsPageAction $action - ) { - $this->indexHandler = $indexerHandler; - $this->storeManager = $storeManager; - $this->cmsPageAction = $action; - } - - /** - * @inheritdoc - */ - public function execute($ids) - { - $stores = $this->storeManager->getStores(); - - foreach ($stores as $store) { - $this->indexHandler->saveIndex($this->cmsPageAction->rebuild($store->getId(), $ids), $store); - $this->indexHandler->cleanUpByTransactionKey($store, $ids); - } - } - - /** - * @inheritdoc - */ - public function executeFull() - { - $stores = $this->storeManager->getStores(); - - foreach ($stores as $store) { - $this->indexHandler->saveIndex($this->cmsPageAction->rebuild($store->getId()), $store); - $this->indexHandler->cleanUpByTransactionKey($store); - } - } - - /** - * @inheritdoc - */ - public function executeList(array $ids) - { - $this->execute($ids); - } - - /** - * @inheritdoc - */ - public function executeRow($id) - { - $this->execute([$id]); - } -} diff --git a/src/module-vsbridge-indexer-cms/Model/Indexer/DataProvider/CmsContentFilter.php b/src/module-vsbridge-indexer-cms/Model/Indexer/DataProvider/CmsContentFilter.php index d482d27a..2daa2a25 100644 --- a/src/module-vsbridge-indexer-cms/Model/Indexer/DataProvider/CmsContentFilter.php +++ b/src/module-vsbridge-indexer-cms/Model/Indexer/DataProvider/CmsContentFilter.php @@ -1,10 +1,4 @@ - * @copyright 2019 Divante Sp. z o.o. - * @license See LICENSE_DIVANTE.txt for license details. - */ namespace Divante\VsbridgeIndexerCms\Model\Indexer\DataProvider; diff --git a/src/module-vsbridge-indexer-cms/Model/ResourceModel/CmsPage.php b/src/module-vsbridge-indexer-cms/Model/ResourceModel/CmsPage.php index c7ba9026..a92d6951 100644 --- a/src/module-vsbridge-indexer-cms/Model/ResourceModel/CmsPage.php +++ b/src/module-vsbridge-indexer-cms/Model/ResourceModel/CmsPage.php @@ -52,7 +52,7 @@ public function __construct( */ public function loadPages($storeId = 1, array $pageIds = [], $fromId = 0, $limit = 1000) { - $metaData = $this->getCmsPageMetaData(); + $metaData = $this->metaDataPool->getMetadata(PageInterface::class); $linkFieldId = $metaData->getLinkField(); $select = $this->getConnection()->select()->from(['cms_page' => $metaData->getEntityTable()]); @@ -89,13 +89,4 @@ private function getConnection() { return $this->resource->getConnection(); } - - /** - * @return \Magento\Framework\EntityManager\EntityMetadataInterface - * @throws \Exception - */ - private function getCmsPageMetaData() - { - return $this->metaDataPool->getMetadata(PageInterface::class); - } } diff --git a/src/module-vsbridge-indexer-cms/etc/di.xml b/src/module-vsbridge-indexer-cms/etc/di.xml index f1dd1847..af27eb8e 100644 --- a/src/module-vsbridge-indexer-cms/etc/di.xml +++ b/src/module-vsbridge-indexer-cms/etc/di.xml @@ -1,29 +1,39 @@ - + + - vue_storefront_catalog cms_block - + - Divante\VsbridgeIndexerCms\Indexer\CmsBlockIndexerHandlerVirtual + cms_page - + - + - vue_storefront_catalog - cms_page + + Divante\VsbridgeIndexerCms\Model\Indexer\Action\CmsPage + Divante\VsbridgeIndexerCms\Model\Indexer\Action\CmsBlock + - - + + + - Divante\VsbridgeIndexerCms\Indexer\CmsPageIndexerHandlerVirtual + + + Divante\VsbridgeIndexerCms\Model\Indexer\DataProvider\Page\ContentData + + + Divante\VsbridgeIndexerCms\Model\Indexer\DataProvider\Page\ContentData + + @@ -33,6 +43,7 @@ + Magento\Widget\Model\Template\FilterEmulate diff --git a/src/module-vsbridge-indexer-cms/etc/vsbridge.xml b/src/module-vsbridge-indexer-cms/etc/vsbridge.xml new file mode 100644 index 00000000..c73f258e --- /dev/null +++ b/src/module-vsbridge-indexer-cms/etc/vsbridge.xml @@ -0,0 +1,5 @@ + + + + diff --git a/src/module-vsbridge-indexer-cms/etc/vsbridge_indices.xml b/src/module-vsbridge-indexer-cms/etc/vsbridge_indices.xml deleted file mode 100644 index f8131068..00000000 --- a/src/module-vsbridge-indexer-cms/etc/vsbridge_indices.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - Divante\VsbridgeIndexerCms\Model\Indexer\DataProvider\Block\ContentData - - - - - Divante\VsbridgeIndexerCms\Model\Indexer\DataProvider\Page\ContentData - - - - diff --git a/src/module-vsbridge-indexer-core/Api/BulkRequestInterface.php b/src/module-vsbridge-indexer-core/Api/BulkRequestInterface.php index 804e46b1..61cc9cc1 100644 --- a/src/module-vsbridge-indexer-core/Api/BulkRequestInterface.php +++ b/src/module-vsbridge-indexer-core/Api/BulkRequestInterface.php @@ -55,17 +55,4 @@ public function addDocuments($index, $type, array $data); * @return \Divante\VsbridgeIndexerCore\Api\BulkRequestInterface */ public function deleteDocuments($index, $type, array $docIds); - - /** - * Update several documents to the index. - * - * $data format have to be an array of all documents with document id as key. - * - * @param string $index Index the documents have to be added to. - * @param string $type Document type. - * @param array $data Document data. - * - * @return \Divante\VsbridgeIndexerCore\Api\BulkRequestInterface - */ - public function updateDocuments($index, $type, array $data); } diff --git a/src/module-vsbridge-indexer-core/Api/Index/DataProviderResolverInterface.php b/src/module-vsbridge-indexer-core/Api/Index/DataProviderResolverInterface.php new file mode 100644 index 00000000..bf56e399 --- /dev/null +++ b/src/module-vsbridge-indexer-core/Api/Index/DataProviderResolverInterface.php @@ -0,0 +1,19 @@ +collectionFactory = $collectionFactory; + $this->excludedIndices = $excludedIndices; + } + + /** + * @return \Magento\Framework\Indexer\IndexerInterface[] + */ + public function getValidIndices() + { + $indexers = $this->collectionFactory->create()->getItems(); + + return array_filter($indexers, function ($indexer) { + if (in_array($indexer->getId(), $this->excludedIndices)) { + return false; + } + + return substr($indexer->getId(), 0, 9) === self::VSBRIDGE_INDEXER_PREFIX; + }); + } + + /** + * @return string[] + */ + public function getInvalidIndicesNames(): array + { + $invalid = []; + + foreach ($this->getValidIndices() as $indexer) { + if (!$indexer->isWorking()) { + continue; + } + + $invalid[] = $indexer->getTitle(); + } + + return $invalid; + } +} diff --git a/src/module-vsbridge-indexer-core/Console/Command/Rebuild/Rebuild.php b/src/module-vsbridge-indexer-core/Console/Command/Rebuild/Rebuild.php new file mode 100644 index 00000000..b0981368 --- /dev/null +++ b/src/module-vsbridge-indexer-core/Console/Command/Rebuild/Rebuild.php @@ -0,0 +1,160 @@ +indexOperations = $indexOperations; + $this->indexerStoreManager = $indexerStoreManager; + $this->indexerRegistry = $indexerRegistry; + $this->output = $output; + $this->indicesProvider = $indicesProvider; + $this->elasticsearchResolver = $elasticsearchResolver; + } + + /** + * @param string|null $storeId + * @throws \Magento\Framework\Exception\NoSuchEntityException + */ + public function execute(string $storeId = null) + { + if (!$this->validate()) { + return; + } + + if ($storeId && !$this->indexerStoreManager->isStoreAllowedToReindex($storeId)) { + $this->output->writeln("Store " . $storeId . " is not allowed."); + return; + } + + $storeList = $this->indexerStoreManager->getStores($storeId); + + foreach ($storeList as $store) { + $this->output->writeln( + "Reindexing all VS indexes for store " . $store->getName() . "..." + ); + $this->reindexStore($store); + $this->output->writeln("Reindexing has completed!"); + } + } + + /** + * Validate indices + * + * @return bool + */ + private function validate(): bool + { + $invalidIndices = $this->indicesProvider->getInvalidIndicesNames(); + + if (!empty($invalidIndices)) { + $message = 'Some indices has invalid status: '. implode(', ', $invalidIndices) . '. '; + $message .= 'Please change indices status to VALID manually or use bin/magento vsbridge:reset command.'; + $this->output->writeln("WARNING: Indexation can't be executed. $message"); + + return false; + } + + return true; + } + + /** + * Reindex each vsbridge index for the specified store + * + * @param StoreInterface $store + */ + private function reindexStore(StoreInterface $store) + { + $this->indexerStoreManager->override([$store]); + $esVersion = $this->elasticsearchResolver->getVersion(); + + if ($esVersion === ElasticsearchResolverInterface::DEFAULT_ES_VERSION) { + $index = $this->indexOperations->createIndex(IndexSettings::DUMMY_INDEX_IDENTIFIER, $store); + $this->indexerRegistry->setFullReIndexationIsInProgress(); + } + + foreach ($this->indicesProvider->getValidIndices() as $indexer) { + try { + $startTime = microtime(true); + $indexer->reindexAll(); + + $resultTime = microtime(true) - $startTime; + + $this->output->writeln( + $indexer->getTitle() . ' index has been rebuilt successfully in ' . gmdate('H:i:s', $resultTime) + ); + } catch (LocalizedException $e) { + $this->output->writeln(sprintf('%s', $e->getMessage())); + } catch (\Exception $e) { + $this->output->writeln($indexer->getTitle()); + $this->output->writeln(sprintf('%s', $e->getMessage())); + } + } + + if ($esVersion === ElasticsearchResolverInterface::DEFAULT_ES_VERSION) { + $this->indexOperations->switchIndexer($store->getId(), $index->getName(), $index->getAlias()); + $this->output->writeln( + sprintf('Index name: %s, index alias: %s', $index->getName(), $index->getAlias()) + ); + } + } +} diff --git a/src/module-vsbridge-indexer-core/Console/Command/Rebuild/RebuildFactory.php b/src/module-vsbridge-indexer-core/Console/Command/Rebuild/RebuildFactory.php new file mode 100644 index 00000000..3d221744 --- /dev/null +++ b/src/module-vsbridge-indexer-core/Console/Command/Rebuild/RebuildFactory.php @@ -0,0 +1,36 @@ +objectManager = $objectManager; + } + + /** + * @param OutputInterface $output + * @return Rebuild + */ + public function create(OutputInterface $output): Rebuild + { + return $this->objectManager->create(Rebuild::class, ['output' => $output]); + } +} diff --git a/src/module-vsbridge-indexer-core/Console/Command/RebuildEsIndexCommand.php b/src/module-vsbridge-indexer-core/Console/Command/RebuildEsIndexCommand.php index 223032a7..1c49b910 100644 --- a/src/module-vsbridge-indexer-core/Console/Command/RebuildEsIndexCommand.php +++ b/src/module-vsbridge-indexer-core/Console/Command/RebuildEsIndexCommand.php @@ -1,84 +1,52 @@ - * @copyright 2019 Divante Sp. z o.o. - * @license See LICENSE_DIVANTE.txt for license details. - */ namespace Divante\VsbridgeIndexerCore\Console\Command; -use Divante\VsbridgeIndexerCore\Indexer\StoreManager; -use Divante\VsbridgeIndexerCore\Api\IndexOperationInterface; -use Divante\VsbridgeIndexerCore\Model\IndexerRegistry; -use Magento\Framework\App\ObjectManagerFactory; -use Magento\Framework\Console\Cli; +use Divante\VsbridgeIndexerCore\Console\Command\Rebuild\RebuildFactory; +use Divante\VsbridgeIndexerCore\Console\Command\Rebuild\Rebuild; +use Magento\Backend\App\Area\FrontNameResolver; +use Magento\Framework\App\State; use Magento\Framework\Event\ManagerInterface; use Magento\Framework\Exception\LocalizedException; -use Magento\Framework\Indexer\IndexerInterface; -use Magento\Indexer\Console\Command\AbstractIndexerCommand; -use Magento\Store\Api\Data\StoreInterface; +use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; -use Magento\Store\Model\StoreManagerInterface; /** * Class IndexerReindexCommand */ -class RebuildEsIndexCommand extends AbstractIndexerCommand +class RebuildEsIndexCommand extends Command { const INPUT_STORE = 'store'; const INPUT_ALL_STORES = 'all'; - const INDEX_IDENTIFIER = 'vue_storefront_catalog'; - - /** - * @var IndexOperationInterface - */ - private $indexOperations; - - /** - * @var StoreManager - */ - private $indexerStoreManager; - - /** - * @var StoreManagerInterface - */ - private $storeManager; - - /** - * @var IndexerRegistry - */ - private $indexerRegistry; + /** @var RebuildFactory */ + private $rebuildIndicesFactory; - /** - * @var array - */ - private $excludeIndices = []; + /** @var State */ + private $appState; - /** - * @var ManagerInterface - */ + /** @var ManagerInterface */ private $eventManager; /** * RebuildEsIndexCommand constructor. - * - * @param ObjectManagerFactory $objectManagerFactory - * @param ManagerInterface $eventManager - * @param array $excludeIndices + * @param RebuildFactory $rebuildIndicesFactory + * @param ManagerInterface $manager + * @param State $appState */ public function __construct( - ObjectManagerFactory $objectManagerFactory, - ManagerInterface $eventManager, // Proxy - array $excludeIndices = [] + RebuildFactory $rebuildIndicesFactory, + ManagerInterface $manager, + State $appState ) { - $this->excludeIndices = $excludeIndices; - parent::__construct($objectManagerFactory); - $this->eventManager = $eventManager; + $this->appState = $appState; + $this->eventManager = $manager; + $this->rebuildIndicesFactory = $rebuildIndicesFactory; + + parent::__construct(); } /** @@ -111,242 +79,43 @@ protected function configure() */ protected function execute(InputInterface $input, OutputInterface $output) { - $this->initObjectManager(); $output->setDecorated(true); - $storeId = $input->getOption(self::INPUT_STORE); - $allStores = $input->getOption(self::INPUT_ALL_STORES); - - $invalidIndices = $this->getInvalidIndices(); - if (!empty($invalidIndices)) { - $message = 'Some indices has invalid status: '. implode(', ', $invalidIndices) . '. '; - $message .= 'Please change indices status to VALID manually or use bin/magento vsbridge:reset command.'; - $output->writeln("WARNING: Indexation can't be executed. $message"); - return; + try { + $this->appState->getAreaCode(); + } catch (LocalizedException $exception) { + $this->appState->setAreaCode(FrontNameResolver::AREA_CODE); } - if (!$storeId && !$allStores) { + $store = $input->getOption(self::INPUT_STORE); + $allStores = $input->getOption(self::INPUT_ALL_STORES); + + if (!$store && !$allStores) { $output->writeln( - "Not enough information provided, nothing has been reindexed. Try using --help for more information." + "Not enough information provided, nothing has been reindexed. +Try using --help for more information." ); - } else { - $this->reindex($output, $storeId, $allStores); - } - } - /** - * @return array - */ - private function getInvalidIndices() - { - $invalid = []; - - foreach ($this->getIndexers() as $indexer) { - if ($indexer->isWorking()) { - $invalid[] = $indexer->getTitle(); - } - } - - return $invalid; - } - - /*** - * @param OutputInterface $output - * @param $storeId - * @param $allStores - * - * @return int - * @throws \Magento\Framework\Exception\NoSuchEntityException - */ - private function reindex(OutputInterface $output, $storeId, $allStores) - { - $this->eventManager->dispatch('vsbridge_indexer_reindex_before', [ - 'storeId' => $storeId, - 'allStores' => $allStores, - ]); - - if ($storeId) { - $store = $this->getStoreManager()->getStore($storeId); - $returnValue = false; - - if ($this->isAllowedToReindex($store)) { - $output->writeln("Reindexing all VS indexes for store " . $store->getName() . "..."); - $returnValue = $this->reindexStore($store, $output); - $output->writeln("Reindexing has completed!"); - } else { - $output->writeln("Store " . $store->getName() . " is not allowed."); - } - - return $returnValue; - } elseif ($allStores) { - $output->writeln("Reindexing all stores..."); - $returnValues = []; - $allowedStores = $this->getStoresAllowedToReindex(); - - /** @var \Magento\Store\Api\Data\StoreInterface $store */ - foreach ($allowedStores as $store) { - $output->writeln("Reindexing store " . $store->getName() . "..."); - $returnValues[] = $this->reindexStore($store, $output); - } - - $output->writeln("All stores have been reindexed!"); - - // If failure returned in any store return failure now - return in_array(Cli::RETURN_FAILURE, $returnValues) ? Cli::RETURN_FAILURE : Cli::RETURN_SUCCESS; - } - - $this->eventManager->dispatch('vsbridge_indexer_reindex_after', [ - 'storeId' => $storeId, - 'allStores' => $allStores, - ]); - } - - /** - * Check if Store is allowed to reindex - * - * @param StoreInterface $store - * - * @return bool - * @throws \Magento\Framework\Exception\NoSuchEntityException - */ - private function isAllowedToReindex(\Magento\Store\Api\Data\StoreInterface $store): bool - { - $allowedStores = $this->getStoresAllowedToReindex(); - - foreach ($allowedStores as $allowedStore) { - if ($store->getId() === $allowedStore->getId()) { - return true; - } - } - - return false; - } - - /** - * Reindex each vsbridge index for the specified store - * - * @param \Magento\Store\Api\Data\StoreInterface $store - * @param \Symfony\Component\Console\Output\OutputInterface $output - * - * @return int - */ - private function reindexStore(StoreInterface $store, OutputInterface $output) - { - $this->getIndexerStoreManager()->override([$store]); - $index = $this->getIndexOperations()->createIndex(self::INDEX_IDENTIFIER, $store); - $this->getIndexerRegistry()->setFullReIndexationIsInProgress(); - - $returnValue = Cli::RETURN_FAILURE; - - foreach ($this->getIndexers() as $indexer) { - try { - $startTime = microtime(true); - $indexer->reindexAll(); - - $resultTime = microtime(true) - $startTime; - $output->writeln( - $indexer->getTitle() . ' index has been rebuilt successfully in ' . gmdate('H:i:s', $resultTime) - ); - $returnValue = Cli::RETURN_SUCCESS; - } catch (LocalizedException $e) { - $output->writeln("" . $e->getMessage() . ""); - } catch (\Exception $e) { - $output->writeln("" . $indexer->getTitle() . ' indexer process unknown error:'); - $output->writeln("" . $e->getMessage() . ""); - } + return; } - $this->getIndexOperations()->switchIndexer($store->getId(), $index->getName(), $index->getAlias()); - - $output->writeln( - sprintf('Index name: %s, index alias: %s', $index->getName(), $index->getAlias()) + $this->eventManager->dispatch( + 'vsbridge_indexer_reindex_before', + [ + 'store' => $store, + 'allStores' => $allStores, + ] ); - return $returnValue; - } - - /** - * @return IndexerInterface[] - */ - private function getIndexers() - { - /** @var IndexerInterface[] */ - $indexers = $this->getAllIndexers(); - $vsbridgeIndexers = []; - - foreach ($indexers as $indexer) { - $indexId = $indexer->getId(); - - if (substr($indexId, 0, 9) === 'vsbridge_' && !in_array($indexId, $this->excludeIndices)) { - $vsbridgeIndexers[] = $indexer; - } - } - - return $vsbridgeIndexers; - } - - /** - * @return array - * @throws \Magento\Framework\Exception\NoSuchEntityException - */ - private function getStoresAllowedToReindex(): array - { - return $this->getIndexerStoreManager()->getStores(); - } - - /** - * @return StoreManagerInterface - */ - private function getStoreManager() - { - if (null === $this->storeManager) { - $this->storeManager = $this->getObjectManager()->get(StoreManagerInterface::class); - } - - return $this->storeManager; - } - - /** - * @return StoreManager - */ - private function getIndexerStoreManager() - { - if (null === $this->indexerStoreManager) { - $this->indexerStoreManager = $this->getObjectManager()->get(StoreManager::class); - } - - return $this->indexerStoreManager; - } - - /** - * @return IndexerRegistry - */ - private function getIndexerRegistry() - { - if (null === $this->indexerRegistry) { - $this->indexerRegistry = $this->getObjectManager()->get(IndexerRegistry::class); - } + $rebuildIndicesCommand = $this->rebuildIndicesFactory->create($output); + $rebuildIndicesCommand->execute($input->getOption(self::INPUT_STORE)); - return $this->indexerRegistry; - } - - /** - * @return IndexOperationInterface - */ - private function getIndexOperations() - { - if (null === $this->indexOperations) { - $this->indexOperations = $this->getObjectManager()->get(IndexOperationInterface::class); - } - - return $this->indexOperations; - } - - /** - * Initiliaze object manager - */ - private function initObjectManager() - { - $this->getObjectManager(); + $this->eventManager->dispatch( + 'vsbridge_indexer_reindex_after', + [ + 'store' => $store, + 'allStores' => $allStores, + ] + ); } } diff --git a/src/module-vsbridge-indexer-core/Elasticsearch/Client.php b/src/module-vsbridge-indexer-core/Elasticsearch/Client.php index 66c656a5..05c3f634 100644 --- a/src/module-vsbridge-indexer-core/Elasticsearch/Client.php +++ b/src/module-vsbridge-indexer-core/Elasticsearch/Client.php @@ -3,6 +3,7 @@ namespace Divante\VsbridgeIndexerCore\Elasticsearch; use Divante\VsbridgeIndexerCore\Api\Client\ClientInterface; +use Divante\VsbridgeIndexerCore\Model\ElasticsearchResolverInterface; /** * Class Client @@ -14,14 +15,23 @@ class Client implements ClientInterface */ private $client; + /** + * @var ElasticsearchResolverInterface + */ + private $esVersionResolver; + /** * Client constructor. * + * @param ElasticsearchResolverInterface $esVersionResolver * @param \Elasticsearch\Client $client */ - public function __construct(\Elasticsearch\Client $client) - { + public function __construct( + ElasticsearchResolverInterface $esVersionResolver, + \Elasticsearch\Client $client + ) { $this->client = $client; + $this->esVersionResolver = $esVersionResolver; } /** @@ -161,13 +171,19 @@ public function deleteIndex(string $indexName) */ public function putMapping(string $indexName, string $type, array $mapping) { - $this->client->indices()->putMapping( - [ - 'index' => $indexName, - 'type' => $type, - 'body' => [$type => $mapping], - ] - ); + $requestPayload = [ + 'index' => $indexName, + 'type' => $type, + 'body' => [$type => $mapping] + ]; + + $esVersion = $this->esVersionResolver->getVersion(); + + if ($esVersion === ElasticsearchResolverInterface::ES_6_PLUS_VERSION) { + $requestPayload['include_type_name'] = true; + } + + $this->client->indices()->putMapping($requestPayload); } /** diff --git a/src/module-vsbridge-indexer-core/Exception/ConfigParserNotExistException.php b/src/module-vsbridge-indexer-core/Exception/ConfigParserNotExistException.php new file mode 100644 index 00000000..008b8d8d --- /dev/null +++ b/src/module-vsbridge-indexer-core/Exception/ConfigParserNotExistException.php @@ -0,0 +1,10 @@ + - * @copyright 2019 Divante Sp. z o.o. - * @license See LICENSE_DIVANTE.txt for license details. - */ namespace Divante\VsbridgeIndexerCore\Exception; /** * Class ConnectionDisabledException - * - * @package \Divante\VsbridgeIndexerCore */ class ConnectionDisabledException extends \RuntimeException { diff --git a/src/module-vsbridge-indexer-core/Exception/IndexNotExistException.php b/src/module-vsbridge-indexer-core/Exception/IndexNotExistException.php new file mode 100644 index 00000000..3746e498 --- /dev/null +++ b/src/module-vsbridge-indexer-core/Exception/IndexNotExistException.php @@ -0,0 +1,18 @@ + $documentData) { - $documentData = $this->prepareDocument($documentData); - $this->updateDocument($index, $type, $docId, $documentData); - } - - return $this; - } - - /** - * @inheritdoc - */ - private function updateDocument($index, $type, $docId, array $data) - { - $this->bulkData[] = [ - 'update' => [ - '_index' => $index, - '_id' => $docId, - '_type' => $type, - ] - ]; - - $this->bulkData[] = ['doc' => $data]; - - return $this; - } - /** * @inheritdoc */ diff --git a/src/module-vsbridge-indexer-core/Indexer/ConvertValue.php b/src/module-vsbridge-indexer-core/Index/ConvertValue.php similarity index 87% rename from src/module-vsbridge-indexer-core/Indexer/ConvertValue.php rename to src/module-vsbridge-indexer-core/Index/ConvertValue.php index 888928ab..270a3a88 100644 --- a/src/module-vsbridge-indexer-core/Indexer/ConvertValue.php +++ b/src/module-vsbridge-indexer-core/Index/ConvertValue.php @@ -6,14 +6,14 @@ * @license See LICENSE_DIVANTE.txt for license details. */ -namespace Divante\VsbridgeIndexerCore\Indexer; +namespace Divante\VsbridgeIndexerCore\Index; use Divante\VsbridgeIndexerCore\Api\Mapping\FieldInterface; use Divante\VsbridgeIndexerCore\Api\MappingInterface; use Divante\VsbridgeIndexerCore\Api\ConvertValueInterface; /** - * Class ConvertValue + * Responsible for converting field value to: int, bool, float; depends on field type. */ class ConvertValue implements ConvertValueInterface { @@ -69,6 +69,10 @@ private function getFieldTypeByCode(array $mapping, string $field) return $this->castMapping[$type]; } + if (strstr($field, 'is_') || strstr($field, 'has_')) { + return 'bool'; + } + return null; } diff --git a/src/module-vsbridge-indexer-core/Index/DataFilter.php b/src/module-vsbridge-indexer-core/Index/DataFilter.php new file mode 100644 index 00000000..74b0544a --- /dev/null +++ b/src/module-vsbridge-indexer-core/Index/DataFilter.php @@ -0,0 +1,32 @@ + + * @copyright 2019 Divante Sp. z o.o. + * @license See LICENSE_DIVANTE.txt for license details. + */ + +namespace Divante\VsbridgeIndexerCore\Index; + +/** + * Class responsible for removing fields from array + */ +class DataFilter +{ + /** + * @param array $dtoToFilter + * @param array $blackList + * + * @return array + */ + public function execute(array $dtoToFilter, array $blackList) + { + foreach ($dtoToFilter as $key => $val) { + if (in_array($key, $blackList)) { + unset($dtoToFilter[$key]); + } + } + + return $dtoToFilter; + } +} diff --git a/src/module-vsbridge-indexer-core/Indexer/DataProvider/TransactionKey.php b/src/module-vsbridge-indexer-core/Index/DataProvider/TransactionKey.php similarity index 87% rename from src/module-vsbridge-indexer-core/Indexer/DataProvider/TransactionKey.php rename to src/module-vsbridge-indexer-core/Index/DataProvider/TransactionKey.php index f318729c..73da15a3 100644 --- a/src/module-vsbridge-indexer-core/Indexer/DataProvider/TransactionKey.php +++ b/src/module-vsbridge-indexer-core/Index/DataProvider/TransactionKey.php @@ -6,9 +6,9 @@ * @license See LICENSE_DIVANTE.txt for license details. */ -namespace Divante\VsbridgeIndexerCore\Indexer\DataProvider; +namespace Divante\VsbridgeIndexerCore\Index\DataProvider; -use Divante\VsbridgeIndexerCore\Api\Indexer\TransactionKeyInterface; +use Divante\VsbridgeIndexerCore\Api\Index\TransactionKeyInterface; use Divante\VsbridgeIndexerCore\Api\DataProviderInterface; /** diff --git a/src/module-vsbridge-indexer-core/Index/DataProviderResolver.php b/src/module-vsbridge-indexer-core/Index/DataProviderResolver.php new file mode 100644 index 00000000..e73f7a01 --- /dev/null +++ b/src/module-vsbridge-indexer-core/Index/DataProviderResolver.php @@ -0,0 +1,72 @@ +validateProviders($typeDataProviders); + } + + $this->dataProviders = $dataProviders; + $this->transactionKeyDataProvider = $transactionKey; + } + + /** + * Check if validators implements DataProviderInterface + * + * @param array $dataProviders + * + * @return void + */ + private function validateProviders(array $dataProviders) + { + foreach ($dataProviders as $dataProvider) { + if (! $dataProvider instanceof DataProviderInterface) { + throw new \InvalidArgumentException( + 'DataProvider must implement ' . DataProviderInterface::class + ); + } + } + } + + /** + * @param string $indexName + * @return DataProviderInterface[] + */ + public function getDataProviders(string $indexName) + { + $dataProviders = $this->dataProviders[$indexName] ?? []; + $dataProviders[] = $this->transactionKeyDataProvider; + + return $dataProviders; + } +} diff --git a/src/module-vsbridge-indexer-core/Index/Index.php b/src/module-vsbridge-indexer-core/Index/Index.php index 6a61be07..421f1d65 100644 --- a/src/module-vsbridge-indexer-core/Index/Index.php +++ b/src/module-vsbridge-indexer-core/Index/Index.php @@ -10,7 +10,6 @@ */ class Index implements IndexInterface { - /** * Name of the index. * @@ -26,6 +25,8 @@ class Index implements IndexInterface private $types; /** + * Index alias + * * @var string */ private $alias; diff --git a/src/module-vsbridge-indexer-core/Index/IndexOperations.php b/src/module-vsbridge-indexer-core/Index/IndexOperations.php index 80dc99ef..5858ce21 100644 --- a/src/module-vsbridge-indexer-core/Index/IndexOperations.php +++ b/src/module-vsbridge-indexer-core/Index/IndexOperations.php @@ -1,10 +1,4 @@ - * @copyright 2019 Divante Sp. z o.o. - * @license See LICENSE_DIVANTE.txt for license details. - */ namespace Divante\VsbridgeIndexerCore\Index; @@ -20,6 +14,8 @@ use Divante\VsbridgeIndexerCore\Config\OptimizationSettings; use Divante\VsbridgeIndexerCore\Elasticsearch\ClientResolver; use Divante\VsbridgeIndexerCore\Exception\ConnectionUnhealthyException; +use Divante\VsbridgeIndexerCore\Exception\ConfigurationNotFoundException; +use Divante\VsbridgeIndexerCore\Exception\IndexNotExistException; use Magento\Store\Api\Data\StoreInterface; /** @@ -145,13 +141,11 @@ public function indexExists($storeId, $indexName) */ public function getIndexByName($indexIdentifier, StoreInterface $store) { - $indexAlias = $this->getIndexAlias($store); + $indexAlias = $this->indexSettings->getIndexAlias($indexIdentifier, $store); if (!isset($this->indicesByIdentifier[$indexAlias])) { if (!$this->indexExists($store->getId(), $indexAlias)) { - throw new \LogicException( - "{$indexIdentifier} index does not exist yet." - ); + throw new IndexNotExistException($indexIdentifier); } $this->initIndex($indexIdentifier, $store, true); @@ -160,14 +154,6 @@ public function getIndexByName($indexIdentifier, StoreInterface $store) return $this->indicesByIdentifier[$indexAlias]; } - /** - * @inheritdoc - */ - public function getIndexAlias(StoreInterface $store) - { - return $this->indexSettings->getIndexAlias($store); - } - /** * @inheritdoc */ @@ -196,6 +182,14 @@ public function createIndex($indexIdentifier, StoreInterface $store) return $index; } + /** + * @inheritdoc + */ + public function getIndexAlias($indexIdentifier, StoreInterface $store) + { + return $this->indexSettings->getIndexAlias($indexIdentifier, $store); + } + /** * @inheritdoc */ @@ -252,11 +246,11 @@ private function initIndex($indexIdentifier, StoreInterface $store, $existingInd $this->getIndicesConfiguration(); if (!isset($this->indicesConfiguration[$indexIdentifier])) { - throw new \LogicException('No configuration found'); + throw new ConfigurationNotFoundException(); } - $indexAlias = $this->getIndexAlias($store); - $indexName = $this->indexSettings->createIndexName($store); + $indexName = $this->indexSettings->createIndexName($indexIdentifier, $store); + $indexAlias = $this->indexSettings->getIndexAlias($indexIdentifier, $store); if ($existingIndex) { $indexName = $indexAlias; @@ -298,7 +292,7 @@ public function getBatchIndexingSize() private function getIndicesConfiguration() { if (null === $this->indicesConfiguration) { - $this->indicesConfiguration = $this->indexSettings->getIndicesConfig(); + $this->indicesConfiguration = $this->indexSettings->getConfig(); } return $this->indicesConfiguration; diff --git a/src/module-vsbridge-indexer-core/Index/IndexSettings.php b/src/module-vsbridge-indexer-core/Index/IndexSettings.php index ff844937..4a89220c 100644 --- a/src/module-vsbridge-indexer-core/Index/IndexSettings.php +++ b/src/module-vsbridge-indexer-core/Index/IndexSettings.php @@ -2,7 +2,9 @@ namespace Divante\VsbridgeIndexerCore\Index; -use Divante\VsbridgeIndexerCore\Index\Indicies\Config as IndicesConfig; +use Divante\VsbridgeIndexerCore\Index\Indices\Config; +use Divante\VsbridgeIndexerCore\Index\Indices\ConfigParserInterface; +use Divante\VsbridgeIndexerCore\Index\Indices\ConfigResolver; use Divante\VsbridgeIndexerCore\Config\IndicesSettings; use Magento\Framework\Intl\DateTimeFactory; use Magento\Store\Api\Data\StoreInterface; @@ -13,15 +15,17 @@ */ class IndexSettings { + const DUMMY_INDEX_IDENTIFIER = 'vue_storefront_catalog'; + /** * @var StoreManagerInterface */ private $storeManager; /** - * @var IndicesConfig + * @var ConfigResolver */ - private $indicesConfig; + private $configResolver; /** * @var IndicesSettings @@ -37,36 +41,30 @@ class IndexSettings * IndexSettings constructor. * * @param StoreManagerInterface $storeManager - * @param IndicesConfig $config - * @param IndicesSettings $settingsConfig + * @param ConfigResolver $config * @param DateTimeFactory $dateTimeFactory + * @param IndicesSettings $settingsConfig */ public function __construct( StoreManagerInterface $storeManager, - IndicesConfig $config, + ConfigResolver $config, IndicesSettings $settingsConfig, DateTimeFactory $dateTimeFactory ) { - $this->indicesConfig = $config; + $this->configResolver = $config; $this->configuration = $settingsConfig; $this->storeManager = $storeManager; $this->dateTimeFactory = $dateTimeFactory; } /** - * @return int - */ - public function getBatchIndexingSize() - { - return $this->configuration->getBatchIndexingSize(); - } - - /** + * Retrieve vsbridge configuration + * * @return array */ - public function getIndicesConfig() + public function getConfig(): array { - return $this->indicesConfig->get(); + return $this->configResolver->resolve(); } /** @@ -75,23 +73,25 @@ public function getIndicesConfig() public function getEsConfig() { return [ - 'index.mapping.total_fields.limit' => $this->configuration->getFieldsLimit(), - 'analysis' => [ - 'analyzer' => [ - 'autocomplete' => [ - 'tokenizer' => 'autocomplete', - 'filter' => ['lowercase'], + 'settings' => [ + 'index.mapping.total_fields.limit' => $this->configuration->getFieldsLimit(), + 'analysis' => [ + 'analyzer' => [ + 'autocomplete' => [ + 'tokenizer' => 'autocomplete', + 'filter' => ['lowercase'], + ], + 'autocomplete_search' => [ + 'tokenizer'=> 'lowercase' + ] ], - 'autocomplete_search' => [ - 'tokenizer'=> 'lowercase' - ] - ], - 'tokenizer' => [ - 'autocomplete' => [ - 'type' => 'edge_ngram', - 'min_gram' => 2, - 'max_gram' => 10, - 'token_chars' => ['letter'], + 'tokenizer' => [ + 'autocomplete' => [ + 'type' => 'edge_ngram', + 'min_gram' => 2, + 'max_gram' => 10, + 'token_chars' => ['letter'], + ] ] ] ] @@ -99,32 +99,41 @@ public function getEsConfig() } /** + * @param string $indexIdentifier * @param StoreInterface $store * * @return string */ - public function createIndexName(StoreInterface $store) + public function createIndexName($indexIdentifier, StoreInterface $store) { - $name = $this->getIndexAlias($store); + $name = $this->getIndexAlias($indexIdentifier, $store); $currentDate = $this->dateTimeFactory->create(); return $name . '_' . $currentDate->getTimestamp(); } /** + * Create index alias + * + * @param string $indexIdentifier * @param StoreInterface $store * * @return string */ - public function getIndexAlias(StoreInterface $store) + public function getIndexAlias(string $indexIdentifier, StoreInterface $store) { - $indexNamePrefix = $this->configuration->getIndexNamePrefix(); + $indexNamePrefix = $this->getIndexNamePrefix(); $storeIdentifier = $this->getStoreIdentifier($store); if ($storeIdentifier) { $indexNamePrefix .= '_' . $storeIdentifier; } + $indexNamePrefix .= + $indexIdentifier === self::DUMMY_INDEX_IDENTIFIER + ? '' + : '_' . $indexIdentifier; + return strtolower($indexNamePrefix); } @@ -143,8 +152,30 @@ private function getStoreIdentifier(StoreInterface $store) } } - $indexIdentifier = $this->configuration->getIndexIdentifier(); + return ('code' === $this->getIndexIdentifier()) ? $store->getCode() : (string) $store->getId(); + } + + /** + * @return string + */ + private function getIndexNamePrefix() + { + return $this->configuration->getIndexNamePrefix(); + } - return ('code' === $indexIdentifier) ? $store->getCode() : (string) $store->getId(); + /** + * @return string + */ + private function getIndexIdentifier() + { + return $this->configuration->getIndexIdentifier(); + } + + /** + * @return int + */ + public function getBatchIndexingSize() + { + return $this->configuration->getBatchIndexingSize(); } } diff --git a/src/module-vsbridge-indexer-core/Index/Indices/Config/Converter.php b/src/module-vsbridge-indexer-core/Index/Indices/Config/Converter.php new file mode 100644 index 00000000..35786a49 --- /dev/null +++ b/src/module-vsbridge-indexer-core/Index/Indices/Config/Converter.php @@ -0,0 +1,48 @@ +query($indexSearchPath) as $indexNode) { + $indexIdentifier = $indexNode->getAttribute('identifier'); + $indices[$indexIdentifier] = $this->parseTypeConfig($indexNode); + } + + return $indices; + } + + /** + * Parse type node configuration. + * + * @param \DOMNode $typeRootNode Type node to be parsed. + * + * @return array + */ + private function parseTypeConfig(\DOMNode $typeRootNode) + { + $mapping = $typeRootNode->getAttribute('mapping'); + + return ['mapping' => $mapping]; + } +} diff --git a/src/module-vsbridge-indexer-core/Index/Indicies/Config/Data.php b/src/module-vsbridge-indexer-core/Index/Indices/Config/Data.php similarity index 93% rename from src/module-vsbridge-indexer-core/Index/Indicies/Config/Data.php rename to src/module-vsbridge-indexer-core/Index/Indices/Config/Data.php index 67ff25c6..54ba11cc 100644 --- a/src/module-vsbridge-indexer-core/Index/Indicies/Config/Data.php +++ b/src/module-vsbridge-indexer-core/Index/Indices/Config/Data.php @@ -6,7 +6,7 @@ * @license See LICENSE_DIVANTE.txt for license details. */ -namespace Divante\VsbridgeIndexerCore\Index\Indicies\Config; +namespace Divante\VsbridgeIndexerCore\Index\Indices\Config; use Magento\Framework\Config\CacheInterface; use Magento\Framework\Config\Data as DataConfig; diff --git a/src/module-vsbridge-indexer-core/Index/Indicies/Config/Reader.php b/src/module-vsbridge-indexer-core/Index/Indices/Config/Reader.php similarity index 86% rename from src/module-vsbridge-indexer-core/Index/Indicies/Config/Reader.php rename to src/module-vsbridge-indexer-core/Index/Indices/Config/Reader.php index fe90bd5e..855f90b7 100644 --- a/src/module-vsbridge-indexer-core/Index/Indicies/Config/Reader.php +++ b/src/module-vsbridge-indexer-core/Index/Indices/Config/Reader.php @@ -6,7 +6,7 @@ * @license See LICENSE_DIVANTE.txt for license details. */ -namespace Divante\VsbridgeIndexerCore\Index\Indicies\Config; +namespace Divante\VsbridgeIndexerCore\Index\Indices\Config; use Magento\Framework\Config\Dom; use Magento\Framework\Config\Reader\Filesystem; @@ -18,7 +18,7 @@ */ class Reader extends Filesystem { - const FILE_NAME = 'vsbridge_indices.xml'; + const FILE_NAME = 'vsbridge.xml'; /** * List of attributes by XPath used as ids during the file merge process. @@ -26,9 +26,7 @@ class Reader extends Filesystem * @var array */ private $idAttributes = [ - '/indices/index' => 'identifier', - '/indices/index/type' => 'name', - '/indices/index/type/data_providers/data_provider' => 'name', + '/config/type' => 'identifier', ]; /** diff --git a/src/module-vsbridge-indexer-core/Index/Indicies/Config/SchemaLocator.php b/src/module-vsbridge-indexer-core/Index/Indices/Config/SchemaLocator.php similarity index 92% rename from src/module-vsbridge-indexer-core/Index/Indicies/Config/SchemaLocator.php rename to src/module-vsbridge-indexer-core/Index/Indices/Config/SchemaLocator.php index ae2724e0..0b1db2f1 100644 --- a/src/module-vsbridge-indexer-core/Index/Indicies/Config/SchemaLocator.php +++ b/src/module-vsbridge-indexer-core/Index/Indices/Config/SchemaLocator.php @@ -6,7 +6,7 @@ * @license See LICENSE_DIVANTE.txt for license details. */ -namespace Divante\VsbridgeIndexerCore\Index\Indicies\Config; +namespace Divante\VsbridgeIndexerCore\Index\Indices\Config; use Magento\Framework\Config\SchemaLocatorInterface; use Magento\Framework\Module\Dir; @@ -19,7 +19,7 @@ class SchemaLocator implements SchemaLocatorInterface /** * XML schema for config file. */ - const CONFIG_FILE_SCHEMA = 'vsbridge_indices.xsd'; + const CONFIG_FILE_SCHEMA = 'vsbridge.xsd'; /** * Path to corresponding XSD file with validation rules for merged config diff --git a/src/module-vsbridge-indexer-core/Index/Indices/ConfigES5Parser.php b/src/module-vsbridge-indexer-core/Index/Indices/ConfigES5Parser.php new file mode 100644 index 00000000..37384ef7 --- /dev/null +++ b/src/module-vsbridge-indexer-core/Index/Indices/ConfigES5Parser.php @@ -0,0 +1,63 @@ +mappingProviderProcessorFactory = $mappingProcessorFactory; + $this->typeFactory = $typeInterfaceFactory; + } + + /** + * @param array $indexConfigData + * + * @return array + */ + public function parse(array $indexConfigData): array + { + $types = []; + + foreach ($indexConfigData as $typeName => $typeConfigData) { + $mapping = $this->mappingProviderProcessorFactory->get($typeConfigData['mapping']); + $types[$typeName] = $this->typeFactory->create( + [ + 'name' => $typeName, + 'mapping' => $mapping, + ] + ); + } + + return [ + IndexSettings::DUMMY_INDEX_IDENTIFIER => ['types' => $types] + ]; + } +} diff --git a/src/module-vsbridge-indexer-core/Index/Indices/ConfigES6plusParser.php b/src/module-vsbridge-indexer-core/Index/Indices/ConfigES6plusParser.php new file mode 100644 index 00000000..82b752f6 --- /dev/null +++ b/src/module-vsbridge-indexer-core/Index/Indices/ConfigES6plusParser.php @@ -0,0 +1,63 @@ +mappingProviderProcessorFactory = $mappingProcessorFactory; + $this->typeFactory = $typeInterfaceFactory; + } + + /** + * @param array $indexConfigData + * + * @return array + */ + public function parse(array $indexConfigData): array + { + $indices = []; + + foreach ($indexConfigData as $typeName => $typeConfigData) { + $mapping = $this->mappingProviderProcessorFactory->get($typeConfigData['mapping']); + $type = $this->typeFactory->create( + [ + 'name' => $typeName, + 'mapping' => $mapping, + ] + ); + + $indices[$typeName] = ['types' => [IndexInterface::DUMMY_INDEX_TYPE => $type]]; + } + + return $indices; + } +} diff --git a/src/module-vsbridge-indexer-core/Index/Indices/ConfigParserInterface.php b/src/module-vsbridge-indexer-core/Index/Indices/ConfigParserInterface.php new file mode 100644 index 00000000..b5cb269c --- /dev/null +++ b/src/module-vsbridge-indexer-core/Index/Indices/ConfigParserInterface.php @@ -0,0 +1,16 @@ +configData = $configData; + $this->configParsers = $configParsers; + $this->objectManager = $objectManager; + $this->elasticsearchResolver = $elasticsearchResolver; + } + + /** + * @return array + */ + public function resolve(): array + { + $currentEsVersion = $this->elasticsearchResolver->getVersion(); + + if (!isset($this->configParsers[$currentEsVersion])) { + throw new ConfigParserNotExistException(__('There is no parser for: ' . $currentEsVersion)); + } + + /** @var ConfigParserInterface $configParser */ + $configParser = $this->objectManager->get($this->configParsers[$currentEsVersion]); + + return $configParser->parse($this->configData->get()); + } +} diff --git a/src/module-vsbridge-indexer-core/Index/Indicies/Config.php b/src/module-vsbridge-indexer-core/Index/Indicies/Config.php deleted file mode 100644 index 02e5c49e..00000000 --- a/src/module-vsbridge-indexer-core/Index/Indicies/Config.php +++ /dev/null @@ -1,119 +0,0 @@ - - * @copyright 2019 Divante Sp. z o.o. - * @license See LICENSE_DIVANTE.txt for license details. - */ - -namespace Divante\VsbridgeIndexerCore\Index\Indicies; - -use Divante\VsbridgeIndexerCore\Api\Index\TypeInterfaceFactory as TypeFactoryInterface; -use Divante\VsbridgeIndexerCore\Indexer\DataProviderProcessorFactory; -use Divante\VsbridgeIndexerCore\Indexer\MappingProcessorFactory; - -/** - * Class Config - */ -class Config -{ - /** - * Factory used to build mapping types. - * - * @var TypeFactoryInterface - */ - private $typeFactory; - - /** - * @var DataProviderProcessorFactory - */ - private $dataProviderFactoryProcessor; - - /** - * @var MappingProcessorFactory - */ - private $mappingProviderProcessorFactory; - - /** - * @var \Divante\VsbridgeIndexerCore\Indexer\DataProvider\TransactionKey - */ - private $transactionKey; - - /** - * Config\Data - */ - private $configData; - - /** - * Config constructor. - * - * @param Config\Data $configData - * @param \Divante\VsbridgeIndexerCore\Indexer\DataProvider\TransactionKey $transactionKey - * @param TypeFactoryInterface $typeInterfaceFactory - * @param MappingProcessorFactory $mappingProcessorFactory - * @param DataProviderProcessorFactory $dataProviderFactoryProcessor - */ - public function __construct( - Config\Data $configData, - \Divante\VsbridgeIndexerCore\Indexer\DataProvider\TransactionKey $transactionKey, - TypeFactoryInterface $typeInterfaceFactory, - MappingProcessorFactory $mappingProcessorFactory, - DataProviderProcessorFactory $dataProviderFactoryProcessor - ) { - $this->configData = $configData; - $this->transactionKey = $transactionKey; - $this->mappingProviderProcessorFactory = $mappingProcessorFactory; - $this->dataProviderFactoryProcessor = $dataProviderFactoryProcessor; - $this->typeFactory = $typeInterfaceFactory; - } - - /** - * @return array - */ - public function get() - { - $configData = $this->configData->get(); - $indicesConfig = []; - - foreach ($configData as $indexIdentifier => $indexConfig) { - $indicesConfig[$indexIdentifier] = $this->initIndexConfig($indexConfig); - } - - return $indicesConfig; - } - - /** - * @param array $indexConfigData - * - * @return array - */ - private function initIndexConfig(array $indexConfigData) - { - $types = []; - - foreach ($indexConfigData['types'] as $typeName => $typeConfigData) { - $dataProviders = ['transaction_key' => $this->transactionKey]; - - foreach ($typeConfigData['data_providers'] as $dataProviderName => $dataProviderClass) { - $dataProviders[$dataProviderName] = - $this->dataProviderFactoryProcessor->get($dataProviderClass); - } - - $mapping = null; - - if (isset($typeConfigData['mapping'][0])) { - $mapping = $this->mappingProviderProcessorFactory->get($typeConfigData['mapping'][0]); - } - - $types[$typeName] = $this->typeFactory->create( - [ - 'name' => $typeName, - 'dataProviders' => $dataProviders, - 'mapping' => $mapping, - ] - ); - } - - return ['types' => $types]; - } -} diff --git a/src/module-vsbridge-indexer-core/Index/Indicies/Config/Converter.php b/src/module-vsbridge-indexer-core/Index/Indicies/Config/Converter.php deleted file mode 100644 index 27e9621b..00000000 --- a/src/module-vsbridge-indexer-core/Index/Indicies/Config/Converter.php +++ /dev/null @@ -1,122 +0,0 @@ - - * @copyright 2019 Divante Sp. z o.o. - * @license See LICENSE_DIVANTE.txt for license details. - */ - -namespace Divante\VsbridgeIndexerCore\Index\Indicies\Config; - -use Magento\Framework\Config\ConverterInterface; - -/** - * Class Converter - */ -class Converter implements ConverterInterface -{ - /** - * - */ - const ROOT_NODE_NAME = 'indices'; - - /** - * - */ - const INDEX_NODE_TYPE = 'index'; - - /** - * - */ - const TYPE_NODE_TYPE = 'type'; - - /** - * - */ - const DATA_PROVIDERS_PATH = 'data_providers/data_provider'; - - /** - * @param \DOMDocument $source - * - * @return array - */ - public function convert($source) - { - $indices = []; - - $xpath = new \DOMXPath($source); - $indexSearchPath = sprintf("/%s/%s", self::ROOT_NODE_NAME, self::INDEX_NODE_TYPE); - - foreach ($xpath->query($indexSearchPath) as $indexNode) { - $indexIdentifier = $indexNode->getAttribute('identifier'); - $indices[$indexIdentifier] = $this->parseIndexConfig($xpath, $indexNode); - } - - return $indices; - } - - /** - * Parse index node configuration. - * - * @param \DOMXPath $xpath XPath access to the document parsed. - * @param \DOMNode $indexRootNode Index node to be parsed. - * - * @return array - */ - private function parseIndexConfig(\DOMXPath $xpath, \DOMNode $indexRootNode) - { - $indexConfig = ['types' => []]; - $typesSearchPath = sprintf('%s', self::TYPE_NODE_TYPE); - $xpath->query($typesSearchPath, $indexRootNode); - - foreach ($xpath->query($typesSearchPath, $indexRootNode) as $typeNode) { - $typeParams = $this->parseTypeConfig($xpath, $typeNode); - $indexConfig['types'][$typeNode->getAttribute('name')] = $typeParams; - } - - return $indexConfig; - } - - /** - * Parse type node configuration. - * - * @param \DOMXPath $xpath XPath access to the document parsed. - * @param \DOMNode $typeRootNode Type node to be parsed. - * - * @return array - */ - private function parseTypeConfig(\DOMXPath $xpath, \DOMNode $typeRootNode) - { - $datasources = $this->parseDataProviders($xpath, $typeRootNode); - $mapping = $typeRootNode->getAttribute('mapping'); - $mappingOptions = []; - - if ($mapping) { - $mappingOptions[] = $mapping; - } - - return [ - 'mapping' => $mappingOptions, - 'data_providers' => $datasources, - ]; - } - - /** - * Parse dataprovides from type node configuration. - * - * @param \DOMXPath $xpath XPath access to the document parsed. - * @param \DOMNode $typeRootNode Type node to be parsed. - * - * @return array - */ - private function parseDataProviders(\DOMXPath $xpath, \DOMNode $typeRootNode) - { - $datasources = []; - - foreach ($xpath->query(self::DATA_PROVIDERS_PATH, $typeRootNode) as $datasourceNode) { - $datasources[$datasourceNode->getAttribute('name')] = $datasourceNode->nodeValue; - } - - return $datasources; - } -} diff --git a/src/module-vsbridge-indexer-core/Index/Mapping/GeneralMapping.php b/src/module-vsbridge-indexer-core/Index/Mapping/GeneralMapping.php index 497e347e..24b16d3b 100644 --- a/src/module-vsbridge-indexer-core/Index/Mapping/GeneralMapping.php +++ b/src/module-vsbridge-indexer-core/Index/Mapping/GeneralMapping.php @@ -11,7 +11,7 @@ use Divante\VsbridgeIndexerCore\Api\Mapping\FieldInterface; /** - * Class GeneralMapping + * Mapping for common fields for shared fields */ class GeneralMapping { diff --git a/src/module-vsbridge-indexer-core/Indexer/MappingProcessorFactory.php b/src/module-vsbridge-indexer-core/Index/MappingFactory.php similarity index 63% rename from src/module-vsbridge-indexer-core/Indexer/MappingProcessorFactory.php rename to src/module-vsbridge-indexer-core/Index/MappingFactory.php index c796fdd3..96c724b2 100644 --- a/src/module-vsbridge-indexer-core/Indexer/MappingProcessorFactory.php +++ b/src/module-vsbridge-indexer-core/Index/MappingFactory.php @@ -6,28 +6,29 @@ * @license See LICENSE_DIVANTE.txt for license details. */ -namespace Divante\VsbridgeIndexerCore\Indexer; +namespace Divante\VsbridgeIndexerCore\Index; + +use Magento\Framework\ObjectManagerInterface; /** - * Class MappingProcessorFactory + * Class MappingFactory */ -class MappingProcessorFactory +class MappingFactory { /** * Object Manager instance * - * @var \Magento\Framework\ObjectManagerInterface + * @var ObjectManagerInterface */ private $objectManager; /** * Constructor * - * @param \Magento\Framework\ObjectManagerInterface $objectManager + * @param ObjectManagerInterface $objectManager */ - public function __construct( - \Magento\Framework\ObjectManagerInterface $objectManager - ) { + public function __construct(ObjectManagerInterface $objectManager) + { $this->objectManager = $objectManager; } diff --git a/src/module-vsbridge-indexer-core/Indexer/TransactionKey.php b/src/module-vsbridge-indexer-core/Index/TransactionKey.php similarity index 83% rename from src/module-vsbridge-indexer-core/Indexer/TransactionKey.php rename to src/module-vsbridge-indexer-core/Index/TransactionKey.php index 47e464d6..4d9f6a78 100644 --- a/src/module-vsbridge-indexer-core/Indexer/TransactionKey.php +++ b/src/module-vsbridge-indexer-core/Index/TransactionKey.php @@ -6,9 +6,9 @@ * @license See LICENSE_DIVANTE.txt for license details. */ -namespace Divante\VsbridgeIndexerCore\Indexer; +namespace Divante\VsbridgeIndexerCore\Index; -use Divante\VsbridgeIndexerCore\Api\Indexer\TransactionKeyInterface; +use Divante\VsbridgeIndexerCore\Api\Index\TransactionKeyInterface; /** * Class TransactionKey diff --git a/src/module-vsbridge-indexer-core/Index/Type.php b/src/module-vsbridge-indexer-core/Index/Type.php index eaeef737..6ab4774b 100644 --- a/src/module-vsbridge-indexer-core/Index/Type.php +++ b/src/module-vsbridge-indexer-core/Index/Type.php @@ -30,25 +30,16 @@ class Type implements TypeInterface */ private $mapping; - /** - * Type dataProviders. - * - * @var - */ - private $dataProviders; - /** * Type constructor. * * @param $name * @param MappingInterface|null $mapping - * @param array $dataProviders */ - public function __construct($name, MappingInterface $mapping = null, array $dataProviders) + public function __construct($name, MappingInterface $mapping = null) { $this->name = $name; $this->mapping = $mapping; - $this->dataProviders = $dataProviders; } /** @@ -66,24 +57,4 @@ public function getMapping() { return $this->mapping; } - - /** - * @inheritdoc - */ - public function getDataProviders() - { - return $this->dataProviders; - } - - /** - * @inheritdoc - */ - public function getDataProvider(string $name) - { - if (!isset($this->dataProviders[$name])) { - throw new \Exception("DataProvider $name does not exists."); - } - - return $this->dataProviders[$name]; - } } diff --git a/src/module-vsbridge-indexer-core/Indexer/Action/AbstractAction.php b/src/module-vsbridge-indexer-core/Indexer/Action/AbstractAction.php new file mode 100644 index 00000000..e1a2c9fd --- /dev/null +++ b/src/module-vsbridge-indexer-core/Indexer/Action/AbstractAction.php @@ -0,0 +1,93 @@ +storeManager = $storeManager; + $this->indexerFactory = $indexerHandlerFactory; + $this->action = $actionPool; + $this->typeName = $typeName; + } + + /** + * Execute action for given ids + * + * @param array $ids + * + * @return void + */ + abstract public function execute(array $ids); + + /** + * @return \Magento\Store\Api\Data\StoreInterface[] + * @throws \Magento\Framework\Exception\NoSuchEntityException + */ + public function getStores() + { + return $this->storeManager->getStores(); + } + + /** + * @param int $storeId + * @param array $ids + * + * @return \Traversable + */ + public function rebuild(int $storeId, array $ids) + { + $action = $this->action->getAction($this->typeName); + + return $action->rebuild($storeId, $ids); + } + + /** + * @return GenericIndexerHandler + */ + public function getIndexerHandler(): GenericIndexerHandler + { + return $this->indexerFactory->create(['typeName' => $this->typeName]); + } +} diff --git a/src/module-vsbridge-indexer-core/Indexer/Action/ActionFactory.php b/src/module-vsbridge-indexer-core/Indexer/Action/ActionFactory.php new file mode 100644 index 00000000..4e77e11a --- /dev/null +++ b/src/module-vsbridge-indexer-core/Indexer/Action/ActionFactory.php @@ -0,0 +1,43 @@ +actions = $actions; + $this->objectManager = $objectManager; + } + + /** + * Return Action class base on action type: full, rows + * @param string $actionType + * @param string $entityType + * + * @return AbstractAction + */ + public function create(string $actionType, string $entityType): AbstractAction + { + $actionFactoryClass = $this->actions[$actionType]; + + return $this->objectManager->create($actionFactoryClass, ['typeName' => $entityType]); + } +} diff --git a/src/module-vsbridge-indexer-core/Indexer/Action/Full.php b/src/module-vsbridge-indexer-core/Indexer/Action/Full.php new file mode 100644 index 00000000..87bd038b --- /dev/null +++ b/src/module-vsbridge-indexer-core/Indexer/Action/Full.php @@ -0,0 +1,64 @@ +esVersionResolver = $esVersionResolver; + } + + /** + * Execute full reindex + * + * @param array $ids + * + * @return void + */ + public function execute(array $ids) + { + $esVersion = $this->esVersionResolver->getVersion(); + $stores = $this->getStores(); + + if ($esVersion === ElasticsearchResolverInterface::DEFAULT_ES_VERSION) { + foreach ($stores as $store) { + $this->getIndexerHandler()->saveIndex($this->rebuild((int) $store->getId(), []), $store); + $this->getIndexerHandler()->cleanUpByTransactionKey($store); + } + } else { + foreach ($stores as $store) { + $this->getIndexerHandler()->createIndex($store); + $this->getIndexerHandler()->saveIndex($this->rebuild((int) $store->getId(), []), $store); + } + } + } +} diff --git a/src/module-vsbridge-indexer-core/Indexer/Action/Rows.php b/src/module-vsbridge-indexer-core/Indexer/Action/Rows.php new file mode 100644 index 00000000..d2e9257d --- /dev/null +++ b/src/module-vsbridge-indexer-core/Indexer/Action/Rows.php @@ -0,0 +1,27 @@ +getStores(); + + foreach ($stores as $store) { + $this->getIndexerHandler()->saveIndex($this->rebuild((int) $store->getId(), $ids), $store); + $this->getIndexerHandler()->cleanUpByTransactionKey($store, $ids); + } + } +} diff --git a/src/module-vsbridge-indexer-core/Indexer/Base.php b/src/module-vsbridge-indexer-core/Indexer/Base.php new file mode 100644 index 00000000..f99ee633 --- /dev/null +++ b/src/module-vsbridge-indexer-core/Indexer/Base.php @@ -0,0 +1,67 @@ +typeName = $typeName; + $this->actionFactory = $actionFactory; + } + + /** + * @inheritdoc + */ + public function execute($ids) + { + return $this->actionFactory->create('rows', $this->typeName)->execute($ids); + } + + /** + * @inheritdoc + */ + public function executeFull() + { + return $this->actionFactory->create('full', $this->typeName)->execute([]); + } + + /** + * @inheritdoc + */ + public function executeList(array $ids) + { + $this->execute($ids); + } + + /** + * @inheritdoc + */ + public function executeRow($id) + { + $this->execute([$id]); + } +} diff --git a/src/module-vsbridge-indexer-core/Indexer/DataFilter.php b/src/module-vsbridge-indexer-core/Indexer/DataFilter.php deleted file mode 100644 index b6ec90eb..00000000 --- a/src/module-vsbridge-indexer-core/Indexer/DataFilter.php +++ /dev/null @@ -1,66 +0,0 @@ - - * @copyright 2019 Divante Sp. z o.o. - * @license See LICENSE_DIVANTE.txt for license details. - */ - -namespace Divante\VsbridgeIndexerCore\Indexer; - -/** - * Class DataFilter - */ -class DataFilter -{ - /** - * @var array - */ - private $integerProperties = []; - - /** - * @var array - */ - private $floatProperties = []; - - /** - * DataFilter constructor. - * - * @param array $integerProperties - * @param array $floatProperties - */ - public function __construct( - array $integerProperties = [], - array $floatProperties = [] - ) { - $this->integerProperties = $integerProperties; - $this->floatProperties = $floatProperties; - } - - /** - * @param array $dtoToFilter - * @param array|null $blackList - * - * @return array - */ - public function execute(array $dtoToFilter, array $blackList = null) - { - foreach ($dtoToFilter as $key => $val) { - if ($blackList && in_array($key, $blackList)) { - unset($dtoToFilter[$key]); - } else { - if (strstr($key, 'is_') || strstr($key, 'has_')) { - $dtoToFilter[$key] = (bool)$val; - } else { - if (in_array($key, $this->integerProperties)) { - $dtoToFilter[$key] = (int)$val; - } elseif (in_array($key, $this->floatProperties)) { - $dtoToFilter[$key] = (float)$val; - } - } - } - } - - return $dtoToFilter; - } -} diff --git a/src/module-vsbridge-indexer-core/Indexer/DataProviderProcessorFactory.php b/src/module-vsbridge-indexer-core/Indexer/DataProviderProcessorFactory.php deleted file mode 100644 index 8ddb1c97..00000000 --- a/src/module-vsbridge-indexer-core/Indexer/DataProviderProcessorFactory.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright 2019 Divante Sp. z o.o. - * @license See LICENSE_DIVANTE.txt for license details. - */ - -namespace Divante\VsbridgeIndexerCore\Indexer; - -/** - * Class DataProviderProcessorFactory - */ -class DataProviderProcessorFactory -{ - /** - * Object Manager instance - * - * @var \Magento\Framework\ObjectManagerInterface - */ - private $objectManager; - - /** - * Constructor - * - * @param \Magento\Framework\ObjectManagerInterface $objectManager - */ - public function __construct( - \Magento\Framework\ObjectManagerInterface $objectManager - ) { - $this->objectManager = $objectManager; - } - - /** - * @param string $instanceName - * - * @return mixed - */ - public function get($instanceName) - { - return $this->objectManager->get($instanceName); - } -} diff --git a/src/module-vsbridge-indexer-core/Indexer/GenericIndexerHandler.php b/src/module-vsbridge-indexer-core/Indexer/GenericIndexerHandler.php index 4c9d10ea..90720ad0 100644 --- a/src/module-vsbridge-indexer-core/Indexer/GenericIndexerHandler.php +++ b/src/module-vsbridge-indexer-core/Indexer/GenericIndexerHandler.php @@ -1,26 +1,23 @@ - * @copyright 2019 Divante Sp. z o.o. - * @license See LICENSE_DIVANTE.txt for license details. - */ namespace Divante\VsbridgeIndexerCore\Indexer; use Divante\VsbridgeIndexerCore\Api\BulkLoggerInterface; use Divante\VsbridgeIndexerCore\Api\DataProviderInterface; use Divante\VsbridgeIndexerCore\Api\IndexInterface; -use Divante\VsbridgeIndexerCore\Api\Indexer\TransactionKeyInterface; +use Divante\VsbridgeIndexerCore\Api\Index\TransactionKeyInterface; use Divante\VsbridgeIndexerCore\Api\IndexOperationInterface; use Divante\VsbridgeIndexerCore\Exception\ConnectionDisabledException; use Divante\VsbridgeIndexerCore\Exception\ConnectionUnhealthyException; use Divante\VsbridgeIndexerCore\Logger\IndexerLogger; +use Divante\VsbridgeIndexerCore\Index\IndexSettings; use Divante\VsbridgeIndexerCore\Model\IndexerRegistry; use Exception; use Magento\Framework\Indexer\SaveHandler\Batch; use Magento\Store\Api\Data\StoreInterface; use Traversable; +use Divante\VsbridgeIndexerCore\Api\Index\DataProviderResolverInterface; +use Divante\VsbridgeIndexerCore\Model\ElasticsearchResolverInterface; /** * Class IndexerHandler @@ -29,6 +26,11 @@ */ class GenericIndexerHandler { + /** + * @var ElasticsearchResolverInterface + */ + private $esVersionResolver; + /** * @var Batch */ @@ -69,97 +71,45 @@ class GenericIndexerHandler */ private $bulkLogger; + /** + * @var DataProviderResolverInterface + */ + private $dataProviderResolver; + /** * GenericIndexerHandler constructor. - * + * @param DataProviderResolverInterface $dataProviderResolver + * @param ElasticsearchResolverInterface $esVersionResolver * @param BulkLoggerInterface $bulkLogger * @param IndexOperationInterface $indexOperationProvider * @param IndexerLogger $indexerLogger + * @param IndexOperationInterface $indexOperations * @param IndexerRegistry $indexerRegistry * @param Batch $batch * @param TransactionKeyInterface $transactionKey - * @param string $indexIdentifier * @param string $typeName */ public function __construct( + DataProviderResolverInterface $dataProviderResolver, + ElasticsearchResolverInterface $esVersionResolver, BulkLoggerInterface $bulkLogger, IndexOperationInterface $indexOperationProvider, IndexerLogger $indexerLogger, + IndexOperationInterface $indexOperations, IndexerRegistry $indexerRegistry, Batch $batch, TransactionKeyInterface $transactionKey, - string $indexIdentifier, string $typeName ) { + $this->esVersionResolver = $esVersionResolver; + $this->dataProviderResolver = $dataProviderResolver; $this->bulkLogger = $bulkLogger; $this->batch = $batch; - $this->indexOperations = $indexOperationProvider; + $this->indexOperations = $indexOperations; $this->typeName = $typeName; - $this->indexIdentifier = $indexIdentifier; $this->indexerLogger = $indexerLogger; $this->indexerRegistry = $indexerRegistry; - $this->transactionKey = $transactionKey->load(); - } - - /** - * Update documents in ES - * - * @param Traversable $documents - * @param StoreInterface $store - * @param array $requireDataProvides - * - * @return $this - * @throws ConnectionUnhealthyException - */ - public function updateIndex(Traversable $documents, StoreInterface $store, array $requireDataProvides) - { - try { - $index = $this->getIndex($store); - $type = $index->getType($this->typeName); - $storeId = (int)$store->getId(); - $dataProviders = []; - - foreach ($type->getDataProviders() as $name => $dataProvider) { - if (in_array($name, $requireDataProvides)) { - $dataProviders[] = $dataProvider; - } - } - - if (empty($dataProviders)) { - return $this; - } - - $batchSize = $this->indexOperations->getBatchIndexingSize(); - - foreach ($this->batch->getItems($documents, $batchSize) as $docs) { - /** @var DataProviderInterface $datasource */ - foreach ($dataProviders as $datasource) { - if (!empty($docs)) { - $docs = $datasource->addData($docs, $storeId); - } - } - - $bulkRequest = $this->indexOperations->createBulk()->updateDocuments( - $index->getName(), - $this->typeName, - $docs - ); - - $this->indexOperations->optimizeEsIndexing($storeId, $index->getName()); - $response = $this->indexOperations->executeBulk($storeId, $bulkRequest); - $this->indexOperations->cleanAfterOptimizeEsIndexing($storeId, $index->getName()); - $this->bulkLogger->log($response); - $docs = null; - } - - $this->indexOperations->refreshIndex($store->getId(), $index); - } catch (ConnectionDisabledException $exception) { - // do nothing, ES indexer disabled in configuration - } catch (ConnectionUnhealthyException $exception) { - $this->indexerLogger->error($exception->getMessage()); - $this->indexOperations->cleanAfterOptimizeEsIndexing($storeId, $index->getName()); - throw $exception; - } + $this->transactionKey = $transactionKey; } /** @@ -175,12 +125,11 @@ public function saveIndex(Traversable $documents, StoreInterface $store) { try { $index = $this->getIndex($store); - $type = $index->getType($this->typeName); $storeId = (int)$store->getId(); $batchSize = $this->indexOperations->getBatchIndexingSize(); foreach ($this->batch->getItems($documents, $batchSize) as $docs) { - foreach ($type->getDataProviders() as $dataProvider) { + foreach ($this->getDataProviders() as $dataProvider) { if (!empty($docs)) { $docs = $dataProvider->addData($docs, $storeId); } @@ -227,11 +176,11 @@ public function saveIndex(Traversable $documents, StoreInterface $store) public function cleanUpByTransactionKey(StoreInterface $store, array $docIds = null) { try { - $indexAlias = $this->indexOperations->getIndexAlias($store); + $indexAlias = $this->indexOperations->getIndexAlias($this->getIdentifier(), $store); if ($this->indexOperations->indexExists($store->getId(), $indexAlias)) { - $index = $this->indexOperations->getIndexByName($this->indexIdentifier, $store); - $transactionKeyQuery = ['must_not' => ['term' => ['tsk' => $this->transactionKey]]]; + $index = $this->indexOperations->getIndexByName($this->getIdentifier(), $store); + $transactionKeyQuery = ['must_not' => ['term' => ['tsk' => $this->transactionKey->load()]]]; $query = ['query' => ['bool' => $transactionKeyQuery]]; if ($docIds) { @@ -251,6 +200,14 @@ public function cleanUpByTransactionKey(StoreInterface $store, array $docIds = n } } + /** + * @return DataProviderInterface[] + */ + private function getDataProviders() + { + return $this->dataProviderResolver->getDataProviders($this->typeName); + } + /** * Get Index * @@ -261,14 +218,22 @@ public function cleanUpByTransactionKey(StoreInterface $store, array $docIds = n private function getIndex(StoreInterface $store) { try { - $index = $this->indexOperations->getIndexByName($this->indexIdentifier, $store); + $index = $this->indexOperations->getIndexByName($this->getIdentifier(), $store); } catch (Exception $e) { - $index = $this->indexOperations->createIndex($this->indexIdentifier, $store); + $index = $this->indexOperations->createIndex($this->getIdentifier(), $store); } return $index; } + /** + * @param StoreInterface $store + */ + public function createIndex(StoreInterface $store) + { + $this->indexOperations->createIndex($this->getIdentifier(), $store); + } + /** * Get type name * @@ -278,4 +243,18 @@ public function getTypeName() { return $this->typeName; } + + /** + * @return string + */ + private function getIdentifier(): string + { + $esVersion = $this->esVersionResolver->getVersion(); + + if ($esVersion === ElasticsearchResolverInterface::DEFAULT_ES_VERSION) { + return IndexSettings::DUMMY_INDEX_IDENTIFIER; + } + + return $this->typeName; + } } diff --git a/src/module-vsbridge-indexer-core/Indexer/RebuildActionInterface.php b/src/module-vsbridge-indexer-core/Indexer/RebuildActionInterface.php new file mode 100644 index 00000000..9701198b --- /dev/null +++ b/src/module-vsbridge-indexer-core/Indexer/RebuildActionInterface.php @@ -0,0 +1,21 @@ +actions = $actions; + $this->objectManager = $objectManager; + } + + /** + * @param string $entityType + * @return RebuildActionInterface + */ + public function getAction($entityType): ?RebuildActionInterface + { + if (isset($this->actions[$entityType])) { + return $this->objectManager->get($this->actions[$entityType]); + } + + return null; + } +} diff --git a/src/module-vsbridge-indexer-core/Indexer/StoreManager.php b/src/module-vsbridge-indexer-core/Indexer/StoreManager.php index f1f40c8b..43d81754 100644 --- a/src/module-vsbridge-indexer-core/Indexer/StoreManager.php +++ b/src/module-vsbridge-indexer-core/Indexer/StoreManager.php @@ -1,10 +1,4 @@ - * @copyright 2019 Divante Sp. z o.o. - * @license See LICENSE_DIVANTE.txt for license details. - */ namespace Divante\VsbridgeIndexerCore\Indexer; @@ -46,7 +40,20 @@ public function __construct( } /** - * @param int|null $storeId + * @param string $store + * @return bool + * @throws \Magento\Framework\Exception\NoSuchEntityException + */ + public function isStoreAllowedToReindex(string $store) + { + $storeModel = $this->storeManager->getStore($store); + $allowedStores = $this->getAllStoresAllowedToReindex(); + + return isset($allowedStores[$storeModel->getCode()]); + } + + /** + * @param int|string|null $storeId * * @return array|\Magento\Store\Api\Data\StoreInterface[] * @throws \Magento\Framework\Exception\NoSuchEntityException @@ -82,4 +89,17 @@ public function override(array $stores) { $this->loadedStores = $stores; } + + /** + * @return \Magento\Store\Api\Data\StoreInterface[] + */ + private function getAllStoresAllowedToReindex() + { + $allowedStoreIds = $this->generalSettings->getStoresToIndex(); + $storesByCode = $this->storeManager->getStores(false, true); + + return array_filter($storesByCode, function ($store) use ($allowedStoreIds) { + return in_array($store->getId(), $allowedStoreIds); + }); + } } diff --git a/src/module-vsbridge-indexer-core/Model/Adminhtml/System/Config/Source/Version.php b/src/module-vsbridge-indexer-core/Model/Adminhtml/System/Config/Source/Version.php new file mode 100644 index 00000000..54d06985 --- /dev/null +++ b/src/module-vsbridge-indexer-core/Model/Adminhtml/System/Config/Source/Version.php @@ -0,0 +1,45 @@ +engines = $engines; + } + + /** + * {@inheritdoc} + */ + public function toOptionArray() + { + $options = []; + + foreach ($this->engines as $key => $label) { + $options[] = [ + 'value' => $key, + 'label' => $label, + ]; + } + + return $options; + } +} diff --git a/src/module-vsbridge-indexer-core/Model/ElasticsearchResolver.php b/src/module-vsbridge-indexer-core/Model/ElasticsearchResolver.php new file mode 100644 index 00000000..4a01e3b4 --- /dev/null +++ b/src/module-vsbridge-indexer-core/Model/ElasticsearchResolver.php @@ -0,0 +1,39 @@ +scopeConfig = $scopeConfig; + } + + /** + * @inheridoc + * + * @return string + */ + public function getVersion(): string + { + return (string)$this->scopeConfig->getValue(self::ES_VERSION_XPATH); + } +} diff --git a/src/module-vsbridge-indexer-core/Model/ElasticsearchResolverInterface.php b/src/module-vsbridge-indexer-core/Model/ElasticsearchResolverInterface.php new file mode 100644 index 00000000..7b3ea2d1 --- /dev/null +++ b/src/module-vsbridge-indexer-core/Model/ElasticsearchResolverInterface.php @@ -0,0 +1,20 @@ +willReturn($indexMock); - $this->esIndexSettingsMock->method('getIndicesConfig')->willReturn($this->indicesXmlConfiguration); + $this->esIndexSettingsMock->method('getConfig')->willReturn($this->indicesXmlConfiguration); $this->esIndexSettingsMock->method('getIndexAlias')->willReturn($alias); $this->esIndexSettingsMock->method('createIndexName')->willReturn($name); $this->esIndexSettingsMock->method('getEsConfig')->willReturn([]); @@ -166,7 +165,7 @@ public function testCreateNewIndex() ]) ->willReturn($indexMock); - $this->esIndexSettingsMock->method('getIndicesConfig')->willReturn($this->indicesXmlConfiguration); + $this->esIndexSettingsMock->method('getConfig')->willReturn($this->indicesXmlConfiguration); $this->esIndexSettingsMock->method('getIndexAlias')->willReturn($alias); $this->esIndexSettingsMock->method('createIndexName')->willReturn($name); $this->esIndexSettingsMock->method('getEsConfig')->willReturn([]); diff --git a/src/module-vsbridge-indexer-core/Test/Unit/Index/IndexSettingsTest.php b/src/module-vsbridge-indexer-core/Test/Unit/Index/IndexSettingsTest.php index 8fa116c8..a2983cf2 100644 --- a/src/module-vsbridge-indexer-core/Test/Unit/Index/IndexSettingsTest.php +++ b/src/module-vsbridge-indexer-core/Test/Unit/Index/IndexSettingsTest.php @@ -2,9 +2,11 @@ declare(strict_types=1); +namespace Divante\VsbridgeIndexerCore\Test\Unit\Index; + use Divante\VsbridgeIndexerCore\Config\IndicesSettings; use Divante\VsbridgeIndexerCore\Index\IndexSettings; -use Divante\VsbridgeIndexerCore\Index\Indicies\Config; +use Divante\VsbridgeIndexerCore\Index\Indices\ConfigResolver; use Magento\Store\Model\Store; use Magento\Store\Model\StoreManagerInterface; use PHPUnit\Framework\TestCase; @@ -23,7 +25,7 @@ class IndexSettingsTest extends TestCase /** * @var IndicesSettings|PHPUnit_Framework_MockObject_MockObject */ - private $configurationSettings; + private $configResolver; /** * @var Store|PHPUnit_Framework_MockObject_MockObject @@ -45,8 +47,7 @@ class IndexSettingsTest extends TestCase */ protected function setUp() { - $this->storeManagerMock = $this->getMockBuilder( - StoreManagerInterface::class) + $this->storeManagerMock = $this->getMockBuilder(StoreManagerInterface::class) ->disableOriginalConstructor() ->setMethods([]) ->getMockForAbstractClass(); @@ -56,11 +57,11 @@ protected function setUp() ->getMock(); $this->indicesSettingsMock = $this->createMock(IndicesSettings::class); - $this->configurationSettings = $this->createMock(Config::class); + $this->configResolver = $this->createMock(ConfigResolver::class); $this->esIndexSettings = new IndexSettings( $this->storeManagerMock, - $this->configurationSettings, + $this->configResolver, $this->indicesSettingsMock, new DateTimeFactory() ); @@ -71,7 +72,7 @@ protected function setUp() * * @dataProvider provideStores */ - public function testGetIndexAlias(string $storeCode) + public function testGetIndexAlias(string $identifier, string $storeCode) { $indexPrefix = 'vuestorefront'; $this->indicesSettingsMock->method('addIdentifierToDefaultStoreView')->willReturn(true); @@ -79,11 +80,12 @@ public function testGetIndexAlias(string $storeCode) $this->indicesSettingsMock->method('getIndexIdentifier')->willReturn('code'); $this->storeMock->method('getCode')->willReturn($storeCode); + $indexPrefix .= $identifier === IndexSettings::DUMMY_INDEX_IDENTIFIER ? '' : '_' . $identifier; $expectedAlias = strtolower(sprintf('%s_%s', $indexPrefix, $storeCode)); $this->assertEquals( $expectedAlias, - $this->esIndexSettings->getIndexAlias($this->storeMock) + $this->esIndexSettings->getIndexAlias($identifier, $this->storeMock) ); } @@ -93,9 +95,12 @@ public function testGetIndexAlias(string $storeCode) public function provideStores() { return [ - ['de_code'], - ['De_code'], - ['DE_CODE'], + ['vue_storefront_catalog', 'de_code'], + ['vue_storefront_catalog', 'De_code'], + ['vue_storefront_catalog', 'DE_CODE'], + ['product', 'de_code'], + ['product', 'de_code'], + ['product', 'DE_CODE'], ]; } } diff --git a/src/module-vsbridge-indexer-core/Test/Unit/Index/Indices/ConfigES5ParserTest.php b/src/module-vsbridge-indexer-core/Test/Unit/Index/Indices/ConfigES5ParserTest.php new file mode 100644 index 00000000..64cd2a06 --- /dev/null +++ b/src/module-vsbridge-indexer-core/Test/Unit/Index/Indices/ConfigES5ParserTest.php @@ -0,0 +1,106 @@ + ['mapping' => null], + 'cms' => ['mapping' => null], + ]; + + protected function setUp() + { + $this->mappingProviderFactoryMock = $this->getMockBuilder(MappingFactory::class) + ->disableOriginalConstructor() + ->getMock(); + $this->configDataMock = $this->getMockBuilder(Data::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->typeFactoryMock = $this->getMockBuilder(TypeFactoryInterface::class) + ->disableOriginalConstructor() + ->setMethods(['create']) + ->getMock(); + + $this->esConfigParser = new ConfigES5Parser( + $this->typeFactoryMock, + $this->mappingProviderFactoryMock + ); + + parent::setUp(); // TODO: Change the autogenerated stub + } + + /** + * Test parsing config for ES5 + */ + public function testGetConfigForEs5() + { + $mappingMock = $this->getMockBuilder(MappingInterface::class) + ->getMock(); + $this->mappingProviderFactoryMock + ->method('get') + ->willReturn($mappingMock); + + $returnMapValue = []; + foreach (array_keys($this->mockupXmlParseData) as $entity) { + $returnMapValue[] = [ + [ + 'name' => $entity, + 'mapping' => $mappingMock, + ], + $this->createType($entity, $mappingMock) + ]; + } + + $this->typeFactoryMock + ->method('create') + ->will($this->returnValueMap($returnMapValue)); + + $expectedConfig = [ + 'vue_storefront_catalog' => [ + 'types' => [ + 'taxrule' => $this->createType('taxrule', $mappingMock), + 'cms' => $this->createType('cms', $mappingMock) + ] + ] + ]; + + $es5config = $this->esConfigParser->parse($this->mockupXmlParseData); + $this->assertEquals($expectedConfig, $es5config); + } + + /** + * @param string $typeName + * @param $mapping + * @return Type + */ + private function createType(string $typeName, $mapping): Type + { + return new Type($typeName, $mapping); + } +} diff --git a/src/module-vsbridge-indexer-core/Test/Unit/Index/Indices/ConfigES6plusParserTest.php b/src/module-vsbridge-indexer-core/Test/Unit/Index/Indices/ConfigES6plusParserTest.php new file mode 100644 index 00000000..02346b79 --- /dev/null +++ b/src/module-vsbridge-indexer-core/Test/Unit/Index/Indices/ConfigES6plusParserTest.php @@ -0,0 +1,102 @@ + ['mapping' => null], + 'cms' => ['mapping' => null], + ]; + + protected function setUp() + { + $this->mappingProviderFactoryMock = $this->getMockBuilder(MappingFactory::class) + ->disableOriginalConstructor() + ->getMock(); + $this->configDataMock = $this->getMockBuilder(Data::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->typeFactoryMock = $this->getMockBuilder(TypeFactoryInterface::class) + ->disableOriginalConstructor() + ->setMethods(['create']) + ->getMock(); + + $this->esConfigParser = new ConfigES6plusParser( + $this->typeFactoryMock, + $this->mappingProviderFactoryMock + ); + + parent::setUp(); // TODO: Change the autogenerated stub + } + + /** + * Test parsing config for ES5 + */ + public function testGetConfigForEs5() + { + $mappingMock = $this->getMockBuilder(MappingInterface::class) + ->getMock(); + $this->mappingProviderFactoryMock + ->method('get') + ->willReturn($mappingMock); + + $returnMapValue = []; + foreach (array_keys($this->mockupXmlParseData) as $entity) { + $returnMapValue[] = [ + [ + 'name' => $entity, + 'mapping' => $mappingMock, + ], + $this->createType($entity, $mappingMock) + ]; + } + + $this->typeFactoryMock + ->method('create') + ->will($this->returnValueMap($returnMapValue)); + + $expectedConfig = [ + 'taxrule' => ['types' => ['taxrule' => $this->createType('taxrule', $mappingMock)]], + 'cms' => ['types' => ['cms' => $this->createType('cms', $mappingMock)]] + ]; + + $es5config = $this->esConfigParser->parse($this->mockupXmlParseData); + $this->assertEquals($expectedConfig, $es5config); + } + + /** + * @param string $typeName + * @param $mapping + * @return Type + */ + private function createType(string $typeName, $mapping): Type + { + return new Type($typeName, $mapping); + } +} diff --git a/src/module-vsbridge-indexer-core/etc/adminhtml/system.xml b/src/module-vsbridge-indexer-core/etc/adminhtml/system.xml index 4f33affd..525547dc 100644 --- a/src/module-vsbridge-indexer-core/etc/adminhtml/system.xml +++ b/src/module-vsbridge-indexer-core/etc/adminhtml/system.xml @@ -19,6 +19,10 @@ Enable to run indexes with Elasticsearch. Magento\Config\Model\Config\Source\Yesno + + + Divante\VsbridgeIndexerCore\Model\Adminhtml\System\Config\Source\Version + For every store view separated index is created in Elastic diff --git a/src/module-vsbridge-indexer-core/etc/config.xml b/src/module-vsbridge-indexer-core/etc/config.xml index 41230cef..b89e316c 100644 --- a/src/module-vsbridge-indexer-core/etc/config.xml +++ b/src/module-vsbridge-indexer-core/etc/config.xml @@ -26,6 +26,7 @@ 1 0 + elasticsearch5 0 diff --git a/src/module-vsbridge-indexer-core/etc/di.xml b/src/module-vsbridge-indexer-core/etc/di.xml index 34af8fd7..ebd9a8e5 100644 --- a/src/module-vsbridge-indexer-core/etc/di.xml +++ b/src/module-vsbridge-indexer-core/etc/di.xml @@ -8,21 +8,52 @@ */ --> - + - + - + + + + + + Divante\VsbridgeIndexerCore\Indexer\Action\Full + Divante\VsbridgeIndexerCore\Indexer\Action\Rows + + + + + + + + Elasticsearch5 + Elasticsearch6+ + + + + + + + + Divante\VsbridgeIndexerCore\Index\Indices\ConfigES5Parser + Divante\VsbridgeIndexerCore\Index\Indices\ConfigES6plusParser + + + + + + vsbridgeIndexerLogger @@ -32,7 +63,8 @@ - + + Divante\VsbridgeIndexerCore\Logger\IndexerLogger diff --git a/src/module-vsbridge-indexer-core/etc/vsbridge.xsd b/src/module-vsbridge-indexer-core/etc/vsbridge.xsd new file mode 100644 index 00000000..5e0f6dcc --- /dev/null +++ b/src/module-vsbridge-indexer-core/etc/vsbridge.xsd @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/src/module-vsbridge-indexer-core/etc/vsbridge_indices.xsd b/src/module-vsbridge-indexer-core/etc/vsbridge_indices.xsd deleted file mode 100644 index 17803ace..00000000 --- a/src/module-vsbridge-indexer-core/etc/vsbridge_indices.xsd +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/module-vsbridge-indexer-review/Model/Indexer/Action/Review.php b/src/module-vsbridge-indexer-review/Model/Indexer/Action/Review.php index 5646d3fb..b0072838 100644 --- a/src/module-vsbridge-indexer-review/Model/Indexer/Action/Review.php +++ b/src/module-vsbridge-indexer-review/Model/Indexer/Action/Review.php @@ -12,11 +12,12 @@ namespace Divante\VsbridgeIndexerReview\Model\Indexer\Action; use Divante\VsbridgeIndexerReview\Model\ResourceModel\Review as ResourceModel; +use Divante\VsbridgeIndexerCore\Indexer\RebuildActionInterface; /** * Class Review */ -class Review +class Review implements RebuildActionInterface { /** * @var ResourceModel @@ -39,7 +40,7 @@ public function __construct(ResourceModel $resource) * * @return \Traversable */ - public function rebuild(int $storeId = 1, array $reviewIds = []) + public function rebuild(int $storeId, array $reviewIds): \Traversable { $lastReviewId = 0; diff --git a/src/module-vsbridge-indexer-review/Model/Indexer/Review.php b/src/module-vsbridge-indexer-review/Model/Indexer/Review.php deleted file mode 100644 index 09d43c24..00000000 --- a/src/module-vsbridge-indexer-review/Model/Indexer/Review.php +++ /dev/null @@ -1,94 +0,0 @@ - - * @copyright 2019 Divante Sp. z o.o. - * @license See LICENSE_DIVANTE.txt for license details. - */ - -namespace Divante\VsbridgeIndexerReview\Model\Indexer; - -use Divante\VsbridgeIndexerCore\Indexer\GenericIndexerHandler; -use Divante\VsbridgeIndexerCore\Indexer\StoreManager; -use Divante\VsbridgeIndexerReview\Model\Indexer\Action\Review as Action; - -/** - * Class Review - */ -class Review implements \Magento\Framework\Indexer\ActionInterface, \Magento\Framework\Mview\ActionInterface -{ - /** - * @var Action - */ - private $action; - - /** - * @var GenericIndexerHandler - */ - private $indexHandler; - - /** - * @var StoreManager - */ - private $storeManager; - - /** - * Review constructor. - * - * @param GenericIndexerHandler $indexerHandler - * @param StoreManager $storeManager - * @param Action $action - */ - public function __construct( - GenericIndexerHandler $indexerHandler, - StoreManager $storeManager, - Action $action - ) { - $this->action = $action; - $this->storeManager = $storeManager; - $this->indexHandler = $indexerHandler; - } - - /** - * @inheritdoc - */ - public function execute($ids) - { - $stores = $this->storeManager->getStores(); - - foreach ($stores as $store) { - $this->indexHandler->saveIndex($this->action->rebuild((int)$store->getId(), $ids), $store); - $this->indexHandler->cleanUpByTransactionKey($store, $ids); - } - } - - /** - * @inheritdoc - */ - public function executeFull() - { - $stores = $this->storeManager->getStores(); - - foreach ($stores as $store) { - $this->indexHandler->saveIndex($this->action->rebuild((int)$store->getId()), $store); - $this->indexHandler->cleanUpByTransactionKey($store); - } - } - - /** - * @inheritdoc - */ - public function executeList(array $ids) - { - $this->execute($ids); - } - - /** - * @inheritdoc - */ - public function executeRow($id) - { - $this->execute([$id]); - } -} diff --git a/src/module-vsbridge-indexer-review/etc/di.xml b/src/module-vsbridge-indexer-review/etc/di.xml index 06796ed6..292f65e7 100644 --- a/src/module-vsbridge-indexer-review/etc/di.xml +++ b/src/module-vsbridge-indexer-review/etc/di.xml @@ -1,16 +1,27 @@ - + - vue_storefront_catalog review - + - Divante\VsbridgeIndexerReview\Indexer\ReviewIndexerHandlerVirtual + + Divante\VsbridgeIndexerReview\Model\Indexer\Action\Review + + + + + + + + + Divante\VsbridgeIndexerReview\Model\Indexer\DataProvider\Ratings + + diff --git a/src/module-vsbridge-indexer-review/etc/vsbridge.xml b/src/module-vsbridge-indexer-review/etc/vsbridge.xml new file mode 100644 index 00000000..700926a6 --- /dev/null +++ b/src/module-vsbridge-indexer-review/etc/vsbridge.xml @@ -0,0 +1,4 @@ + + + diff --git a/src/module-vsbridge-indexer-review/etc/vsbridge_indices.xml b/src/module-vsbridge-indexer-review/etc/vsbridge_indices.xml deleted file mode 100644 index de65ca1f..00000000 --- a/src/module-vsbridge-indexer-review/etc/vsbridge_indices.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - Divante\VsbridgeIndexerReview\Model\Indexer\DataProvider\Ratings - - - - diff --git a/src/module-vsbridge-indexer-tax/Model/Indexer/Action/TaxRule.php b/src/module-vsbridge-indexer-tax/Model/Indexer/Action/TaxRule.php index 80e9fd40..7247d59e 100644 --- a/src/module-vsbridge-indexer-tax/Model/Indexer/Action/TaxRule.php +++ b/src/module-vsbridge-indexer-tax/Model/Indexer/Action/TaxRule.php @@ -1,19 +1,15 @@ - * @copyright 2019 Divante Sp. z o.o. - * @license See LICENSE_DIVANTE.txt for license details. - */ namespace Divante\VsbridgeIndexerTax\Model\Indexer\Action; use Divante\VsbridgeIndexerTax\ResourceModel\Rules as RulesResourceModel; +use Divante\VsbridgeIndexerCore\Indexer\RebuildActionInterface; + /** * Class TaxRule */ -class TaxRule +class TaxRule implements RebuildActionInterface { /** * @var RulesResourceModel @@ -29,11 +25,12 @@ public function __construct(RulesResourceModel $resource) } /** + * @param int $storeId * @param array $taxRuleIds * * @return \Traversable */ - public function rebuild(array $taxRuleIds = []) + public function rebuild(int $storeId, array $taxRuleIds): \Traversable { $lastTaxRuleId = 0; diff --git a/src/module-vsbridge-indexer-tax/Model/Indexer/TaxRules.php b/src/module-vsbridge-indexer-tax/Model/Indexer/TaxRules.php deleted file mode 100644 index 2159fa30..00000000 --- a/src/module-vsbridge-indexer-tax/Model/Indexer/TaxRules.php +++ /dev/null @@ -1,93 +0,0 @@ - - * @copyright 2019 Divante Sp. z o.o. - * @license See LICENSE_DIVANTE.txt for license details. - */ - -namespace Divante\VsbridgeIndexerTax\Model\Indexer; - -use Divante\VsbridgeIndexerCore\Indexer\GenericIndexerHandler; -use Divante\VsbridgeIndexerCore\Indexer\StoreManager; -use Divante\VsbridgeIndexerTax\Model\Indexer\Action\TaxRule; - -/** - * Class TaxRules - */ -class TaxRules implements \Magento\Framework\Indexer\ActionInterface, \Magento\Framework\Mview\ActionInterface -{ - /** - * @var TaxRule - */ - private $action; - - /** - * @var GenericIndexerHandler - */ - private $indexHandler; - - /** - * @var StoreManager - */ - private $storeManager; - - /** - * TaxRules constructor. - * - * @param GenericIndexerHandler $indexerHandler - * @param StoreManager $storeManager - * @param TaxRule $action - */ - public function __construct( - GenericIndexerHandler $indexerHandler, - StoreManager $storeManager, - TaxRule $action - ) { - $this->action = $action; - $this->storeManager = $storeManager; - $this->indexHandler = $indexerHandler; - } - - /** - * @inheritdoc - */ - public function execute($ids) - { - $stores = $this->storeManager->getStores(); - - foreach ($stores as $store) { - $this->indexHandler->saveIndex($this->action->rebuild($ids), $store); - $this->indexHandler->cleanUpByTransactionKey($store, $ids); - } - } - - /** - * @inheritdoc - */ - public function executeFull() - { - $stores = $this->storeManager->getStores(); - - foreach ($stores as $store) { - $this->indexHandler->saveIndex($this->action->rebuild(), $store); - $this->indexHandler->cleanUpByTransactionKey($store); - } - } - - /** - * @inheritdoc - */ - public function executeList(array $ids) - { - $this->execute($ids); - } - - /** - * @inheritdoc - */ - public function executeRow($id) - { - $this->execute([$id]); - } -} diff --git a/src/module-vsbridge-indexer-tax/etc/di.xml b/src/module-vsbridge-indexer-tax/etc/di.xml index 00236e11..f1107a94 100644 --- a/src/module-vsbridge-indexer-tax/etc/di.xml +++ b/src/module-vsbridge-indexer-tax/etc/di.xml @@ -1,16 +1,28 @@ - + - vue_storefront_catalog taxrule - + - Divante\VsbridgeIndexerTax\Indexer\TaxRuleIndexerHandlerVirtual + + + Divante\VsbridgeIndexerTax\Model\Indexer\DataProvider\TaxClasses + Divante\VsbridgeIndexerTax\Model\Indexer\DataProvider\TaxRates + + + + + + + + + Divante\VsbridgeIndexerTax\Model\Indexer\Action\TaxRule + diff --git a/src/module-vsbridge-indexer-tax/etc/vsbridge.xml b/src/module-vsbridge-indexer-tax/etc/vsbridge.xml new file mode 100644 index 00000000..9c94a60c --- /dev/null +++ b/src/module-vsbridge-indexer-tax/etc/vsbridge.xml @@ -0,0 +1,4 @@ + + + diff --git a/src/module-vsbridge-indexer-tax/etc/vsbridge_indices.xml b/src/module-vsbridge-indexer-tax/etc/vsbridge_indices.xml deleted file mode 100644 index e83597e8..00000000 --- a/src/module-vsbridge-indexer-tax/etc/vsbridge_indices.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - Divante\VsbridgeIndexerTax\Model\Indexer\DataProvider\TaxClasses - Divante\VsbridgeIndexerTax\Model\Indexer\DataProvider\TaxRates - - - -