diff --git a/CHANGELOG.MD b/CHANGELOG.MD
index 67bf0418..5f914947 100644
--- a/CHANGELOG.MD
+++ b/CHANGELOG.MD
@@ -2,7 +2,15 @@
## Unreleased
+### Fixes
+- Fix `vsbridge:reindex` command, fix initialize right areacode, loading di.xml files for adminhtml areacode. ([#127](https://github.com/DivanteLtd/magento2-vsbridge-indexer/pull/127))
+- Fix `vsbridge:reindex --all` command, data will be reindex store by store. ([#130](https://github.com/DivanteLtd/magento2-vsbridge-indexer/pull/130))
+### Changed/Improved
+- Rework abstract mapper to allow configure static type map in di.xml ([#125](https://github.com/DivanteLtd/magento2-vsbridge-indexer/pull/125))
+- Minor refactoring for product resource model ([#126](https://github.com/DivanteLtd/magento2-vsbridge-indexer/pull/126/)).
+- Vsbridge Category Indexer - Save Mode: reindex subcategories if url_key has change in category ([#122](https://github.com/DivanteLtd/magento2-vsbridge-indexer/issues/122)).
+- Sort configurable options by option sort order. ([#129](https://github.com/DivanteLtd/magento2-vsbridge-indexer/pull/129))
## [1.3.0] (2019.09.18)
diff --git a/README.md b/README.md
index f972b6c0..dcd8dd01 100644
--- a/README.md
+++ b/README.md
@@ -19,20 +19,13 @@ Sign up for a demo at https://vuestorefront.io/ (Vue Storefront integrated with
- Install with composer
```json
-composer config repositories.divante vcs https://github.com/DivanteLtd/magento2-vsbridge-indexer
-composer require divante/magento2-vsbridge-indexer:dev-master
+composer require divante/magento2-vsbridge-indexer
```
## Installation/Getting Started - MSI support
-- Install with composer changes from develop branch
+- Install second module which will support MSI
```json
-composer config repositories.divante vcs https://github.com/DivanteLtd/magento2-vsbridge-indexer
-composer require divante/magento2-vsbridge-indexer:dev-develop
-```
-- Install also second module which will support MSI
-```json
-composer config repositories.divante-msi vcs https://github.com/DivanteLtd/magento2-vsbridge-indexer-msi
-composer require divante/magento2-vsbridge-indexer-msi:dev-develop
+composer require divante/magento2-vsbridge-indexer-msi:0.1.0
```
Not fully supported, few fields are exported to ES.
From inventory indexer:
@@ -256,6 +249,7 @@ php bin/magento indexer:reindex vsbridge_product_indexer
php bin/magento indexer:reindex vsbridge_category_indexer
php bin/magento indexer:reindex vsbridge_cms_block_indexer
php bin/magento indexer:reindex vsbridge_cms_page_indexer
+php bin/magento indexer:reindex vsbridge_review_indexer
```
@@ -283,6 +277,7 @@ Note: If a docker with ElasticSearch is disabled, Indexer will display error: "N
- save/delete the static block
- save/delete the static page
- save/delete the attribute (deleting the attribute causes displaying “invalid” status for vsbridge products indexer).
+- save/delete the review
#### Update on Schedule Mode
diff --git a/composer.json b/composer.json
index 34d95205..4e48a900 100644
--- a/composer.json
+++ b/composer.json
@@ -6,7 +6,7 @@
"name": "Agata",
"email": "afirlejczyk@divante.pl"
}],
- "version": "1.3.0",
+ "version": "1.4.0",
"keywords": [
"magento",
"magento2",
diff --git a/src/module-vsbridge-indexer-catalog/Index/Mapping/AbstractMapping.php b/src/module-vsbridge-indexer-catalog/Index/Mapping/AbstractMapping.php
index 8ccf2470..50b5e8af 100644
--- a/src/module-vsbridge-indexer-catalog/Index/Mapping/AbstractMapping.php
+++ b/src/module-vsbridge-indexer-catalog/Index/Mapping/AbstractMapping.php
@@ -13,16 +13,17 @@ abstract class AbstractMapping
/**
* @var array
*/
- private $staticFieldMapping = [
- 'status' => FieldInterface::TYPE_INTEGER,
- 'visibility' => FieldInterface::TYPE_INTEGER,
- 'position' => FieldInterface::TYPE_LONG,
- 'level' => FieldInterface::TYPE_INTEGER,
- 'category_ids' => FieldInterface::TYPE_LONG,
- 'sku' => FieldInterface::TYPE_KEYWORD,
- 'url_path' => FieldInterface::TYPE_KEYWORD,
- 'url_key' => FieldInterface::TYPE_KEYWORD,
- ];
+ private $staticFieldMapping;
+
+ /**
+ * AbstractMapping constructor.
+ *
+ * @param array $staticFieldMapping
+ */
+ public function __construct(array $staticFieldMapping)
+ {
+ $this->staticFieldMapping = $staticFieldMapping;
+ }
/**
* @var array
diff --git a/src/module-vsbridge-indexer-catalog/Index/Mapping/Category.php b/src/module-vsbridge-indexer-catalog/Index/Mapping/Category.php
index a028495d..82b73730 100644
--- a/src/module-vsbridge-indexer-catalog/Index/Mapping/Category.php
+++ b/src/module-vsbridge-indexer-catalog/Index/Mapping/Category.php
@@ -20,7 +20,6 @@
*/
class Category extends AbstractMapping implements MappingInterface
{
-
/**
* @var array
*/
@@ -61,17 +60,20 @@ class Category extends AbstractMapping implements MappingInterface
* @param GeneralMapping $generalMapping
* @param CategoryChildAttributes $categoryChildAttributes
* @param AttributeDataProvider $resourceModel
+ * @param array $staticFieldMapping
*/
public function __construct(
EventManager $eventManager,
GeneralMapping $generalMapping,
CategoryChildAttributes $categoryChildAttributes,
- AttributeDataProvider $resourceModel
+ AttributeDataProvider $resourceModel,
+ array $staticFieldMapping
) {
$this->eventManager = $eventManager;
$this->generalMapping = $generalMapping;
$this->resourceModel = $resourceModel;
$this->childAttributes = $categoryChildAttributes;
+ parent::__construct($staticFieldMapping);
}
/**
diff --git a/src/module-vsbridge-indexer-catalog/Index/Mapping/Product.php b/src/module-vsbridge-indexer-catalog/Index/Mapping/Product.php
index 7de16585..06f9e2fc 100644
--- a/src/module-vsbridge-indexer-catalog/Index/Mapping/Product.php
+++ b/src/module-vsbridge-indexer-catalog/Index/Mapping/Product.php
@@ -14,7 +14,6 @@
*/
class Product extends AbstractMapping implements MappingInterface
{
-
/**
* @var EventManager
*/
@@ -52,12 +51,14 @@ public function __construct(
EventManager $eventManager,
GeneralMapping $generalMapping,
ConfigurableAttributes $configurableAttributes,
- AttributeDataProvider $resourceModel
+ AttributeDataProvider $resourceModel,
+ array $staticFieldMapping
) {
$this->eventManager = $eventManager;
$this->generalMapping = $generalMapping;
$this->resourceModel = $resourceModel;
$this->configurableAttributes = $configurableAttributes;
+ parent::__construct($staticFieldMapping);
}
/**
diff --git a/src/module-vsbridge-indexer-catalog/Model/Attribute/LoadOptionById.php b/src/module-vsbridge-indexer-catalog/Model/Attribute/LoadOptionById.php
new file mode 100644
index 00000000..1e90b3d8
--- /dev/null
+++ b/src/module-vsbridge-indexer-catalog/Model/Attribute/LoadOptionById.php
@@ -0,0 +1,54 @@
+
+ * @copyright 2019 Divante Sp. z o.o.
+ * @license See LICENSE_DIVANTE.txt for license details.
+ */
+
+namespace Divante\VsbridgeIndexerCatalog\Model\Attribute;
+
+/**
+ * Class LoadOptionById
+ */
+class LoadOptionById
+{
+
+ /**
+ * @var LoadOptions
+ */
+ private $loadOptions;
+
+ /**
+ * LoadOptionById constructor.
+ *
+ * @param LoadOptions $loadOptions
+ */
+ public function __construct(LoadOptions $loadOptions)
+ {
+ $this->loadOptions = $loadOptions;
+ }
+
+ /**
+ * @param string $attributeCode
+ * @param int $optionId
+ * @param int $storeId
+ *
+ * @return array
+ */
+ public function execute(string $attributeCode, int $optionId, int $storeId): array
+ {
+ $options = $this->loadOptions->execute($attributeCode, $storeId);
+
+ foreach ($options as $option) {
+ if ($optionId === (int)$option['value']) {
+ return $option;
+ }
+ }
+
+ return [];
+ }
+}
diff --git a/src/module-vsbridge-indexer-catalog/Model/Attribute/LoadOptionLabelById.php b/src/module-vsbridge-indexer-catalog/Model/Attribute/LoadOptionLabelById.php
deleted file mode 100644
index 1787f4d1..00000000
--- a/src/module-vsbridge-indexer-catalog/Model/Attribute/LoadOptionLabelById.php
+++ /dev/null
@@ -1,79 +0,0 @@
-
- * @copyright 2019 Divante Sp. z o.o.
- * @license See LICENSE_DIVANTE.txt for license details.
- */
-
-namespace Divante\VsbridgeIndexerCatalog\Model\Attribute;
-
-use Divante\VsbridgeIndexerCatalog\Model\ResourceModel\Product\AttributeDataProvider;
-use Magento\Catalog\Model\ResourceModel\Eav\Attribute;
-
-/**
- * Class LoadOptionLabelById
- */
-class LoadOptionLabelById
-{
- /**
- * @var AttributeDataProvider
- */
- private $attributeDataProvider;
-
- /**
- * @var array
- */
- private $optionsByAttribute = [];
-
- /**
- * LoadLabelByOptionId constructor.
- *
- * @param AttributeDataProvider $attributeDataProvider
- */
- public function __construct(AttributeDataProvider $attributeDataProvider)
- {
- $this->attributeDataProvider = $attributeDataProvider;
- }
-
- /**
- * @param string $attributeCode
- * @param int $optionId
- * @param int $storeId
- *
- * @return string
- */
- public function execute(string $attributeCode, int $optionId, int $storeId): string
- {
- $attributeModel = $this->attributeDataProvider->getAttributeByCode($attributeCode);
- $attributeModel->setStoreId($storeId);
- $options = $this->loadOptions($attributeModel);
-
- foreach ($options as $option) {
- if ($optionId === (int)$option['value']) {
- return $option['label'];
- }
- }
-
- return '';
- }
-
- /**
- * @param Attribute $attribute
- *
- * @return mixed
- */
- private function loadOptions(Attribute $attribute)
- {
- $key = $attribute->getId() . '_' . $attribute->getStoreId();
-
- if (!isset($this->optionsByAttribute[$key])) {
- $this->optionsByAttribute[$key] = $attribute->getOptions();
- }
-
- return $this->optionsByAttribute[$key];
- }
-}
diff --git a/src/module-vsbridge-indexer-catalog/Model/Attribute/LoadOptions.php b/src/module-vsbridge-indexer-catalog/Model/Attribute/LoadOptions.php
new file mode 100644
index 00000000..f7350907
--- /dev/null
+++ b/src/module-vsbridge-indexer-catalog/Model/Attribute/LoadOptions.php
@@ -0,0 +1,119 @@
+
+ * @copyright 2019 Divante Sp. z o.o.
+ * @license See LICENSE_DIVANTE.txt for license details.
+ */
+
+namespace Divante\VsbridgeIndexerCatalog\Model\Attribute;
+
+use Divante\VsbridgeIndexerCatalog\Model\ResourceModel\Product\AttributeDataProvider;
+use Magento\Catalog\Model\ResourceModel\Eav\Attribute;
+use Magento\Eav\Model\ResourceModel\Entity\Attribute\Option\Collection as OptionCollection;
+use Magento\Eav\Model\ResourceModel\Entity\Attribute\Option\CollectionFactory;
+
+use Magento\Eav\Model\Entity\Attribute\Source\Table as SourceTable;
+
+/**
+ * Class LoadOptionLabelById
+ */
+class LoadOptions
+{
+ /**
+ * @var AttributeDataProvider
+ */
+ private $attributeDataProvider;
+
+ /**
+ * @var CollectionFactory
+ */
+ private $collectionFactory;
+
+ /**
+ * @var OptionCollectionToArray
+ */
+ private $optionCollectionToArray;
+
+ /**
+ * @var array
+ */
+ private $optionsByAttribute = [];
+
+ /**
+ * LoadOptions constructor.
+ *
+ * @param CollectionFactory $collectionFactory
+ * @param OptionCollectionToArray $optionCollectionToArray
+ * @param AttributeDataProvider $attributeDataProvider
+ */
+ public function __construct(
+ CollectionFactory $collectionFactory,
+ OptionCollectionToArray $optionCollectionToArray,
+ AttributeDataProvider $attributeDataProvider
+ ) {
+ $this->collectionFactory = $collectionFactory;
+ $this->attributeDataProvider = $attributeDataProvider;
+ $this->optionCollectionToArray = $optionCollectionToArray;
+ }
+
+ /**
+ * @param string $attributeCode
+ * @param int $storeId
+ *
+ * @return string
+ */
+ public function execute(string $attributeCode, int $storeId): array
+ {
+ $attributeModel = $this->attributeDataProvider->getAttributeByCode($attributeCode);
+ $attributeModel->setStoreId($storeId);
+
+ return $this->loadOptions($attributeModel);
+ }
+
+ /**
+ * @param Attribute $attribute
+ *
+ * @return array
+ */
+ private function loadOptions(Attribute $attribute): array
+ {
+ $key = $attribute->getId() . '_' . $attribute->getStoreId();
+
+ if (!isset($this->optionsByAttribute[$key])) {
+ $source = $attribute->getSource();
+
+ if (SourceTable::class !== get_class($source) &&
+ $source instanceof \Magento\Eav\Model\Entity\Attribute\Source\AbstractSource
+ ) {
+ $options = $source->getAllOptions();
+ } else {
+ $attributeId = $attribute->getAttributeId();
+ $storeId = $attribute->getStoreId();
+
+ /** @var OptionCollection $options */
+ $options = $this->collectionFactory->create();
+ $options->setOrder('sort_order', 'asc');
+ $options->setAttributeFilter($attributeId)->setStoreFilter($storeId);
+ $options = $this->toOptionArray($options);
+ }
+
+ $this->optionsByAttribute[$key] = $options;
+ }
+
+ return $this->optionsByAttribute[$key];
+ }
+
+ /**
+ * @param OptionCollection $collection
+ *
+ * @return array
+ */
+ private function toOptionArray(OptionCollection $collection): array
+ {
+ return $this->optionCollectionToArray->execute($collection);
+ }
+}
diff --git a/src/module-vsbridge-indexer-catalog/Model/Attribute/OptionCollectionToArray.php b/src/module-vsbridge-indexer-catalog/Model/Attribute/OptionCollectionToArray.php
new file mode 100644
index 00000000..35b6a95c
--- /dev/null
+++ b/src/module-vsbridge-indexer-catalog/Model/Attribute/OptionCollectionToArray.php
@@ -0,0 +1,58 @@
+
+ * @copyright 2019 Divante Sp. z o.o.
+ * @license See LICENSE_DIVANTE.txt for license details.
+ */
+
+namespace Divante\VsbridgeIndexerCatalog\Model\Attribute;
+
+use Magento\Eav\Model\ResourceModel\Entity\Attribute\Option\Collection as OptionCollection;
+
+/**
+ * Class OptionCollectionToArray
+ */
+class OptionCollectionToArray
+{
+
+ /**
+ * @param OptionCollection $collection
+ *
+ * @return array
+ */
+ public function execute(OptionCollection $collection): array
+ {
+ $res = [];
+ $additional['value'] = 'option_id';
+ $additional['label'] = 'value';
+ $additional['sort_order'] = 'sort_order';
+
+ foreach ($collection as $item) {
+ $data = [];
+
+ foreach ($additional as $code => $field) {
+ $value = $item->getData($field);
+
+ if ('sort_order' === $field) {
+ $value = (int)$value;
+ }
+
+ if ('option_id' === $field) {
+ $value = (string)$value;
+ }
+
+ $data[$code] = $value;
+ }
+
+ if ($data) {
+ $res[] = $data;
+ }
+ }
+
+ return $res;
+ }
+}
diff --git a/src/module-vsbridge-indexer-catalog/Model/Attribute/SortValues.php b/src/module-vsbridge-indexer-catalog/Model/Attribute/SortValues.php
new file mode 100644
index 00000000..a0c7392d
--- /dev/null
+++ b/src/module-vsbridge-indexer-catalog/Model/Attribute/SortValues.php
@@ -0,0 +1,48 @@
+
+ * @copyright 2019 Divante Sp. z o.o.
+ * @license See LICENSE_DIVANTE.txt for license details.
+ */
+
+namespace Divante\VsbridgeIndexerCatalog\Model\Attribute;
+
+/**
+ * Class SortValues
+ */
+class SortValues
+{
+ /**
+ * @param array $options
+ *
+ * @return array
+ */
+ public function execute(array $options)
+ {
+ usort($options, [$this, 'sortOptions']);
+
+ return $options;
+ }
+
+ /**
+ * @param array $a
+ * @param array $b
+ *
+ * @return int
+ */
+ public function sortOptions($a, $b)
+ {
+ $aSizePos = $a['sort_order'] ?? 0;
+ $bSizePos = $b['sort_order'] ?? 0;
+
+ if ($aSizePos === $bSizePos) {
+ return 0;
+ }
+
+ return ($aSizePos > $bSizePos) ? 1 : -1;
+ }
+}
diff --git a/src/module-vsbridge-indexer-catalog/Model/ConfigurableProcessor/GetConfigurableOptions.php b/src/module-vsbridge-indexer-catalog/Model/ConfigurableProcessor/GetConfigurableOptions.php
new file mode 100644
index 00000000..d9bcc41d
--- /dev/null
+++ b/src/module-vsbridge-indexer-catalog/Model/ConfigurableProcessor/GetConfigurableOptions.php
@@ -0,0 +1,72 @@
+
+ * @copyright 2019 Divante Sp. z o.o.
+ * @license See LICENSE_DIVANTE.txt for license details.
+ */
+
+namespace Divante\VsbridgeIndexerCatalog\Model\ConfigurableProcessor;
+
+use Divante\VsbridgeIndexerCatalog\Model\Attribute\LoadOptionById;
+use Divante\VsbridgeIndexerCatalog\Model\Attribute\SortValues;
+
+/**
+ * Class GetConfigurableOptions
+ */
+class GetConfigurableOptions
+{
+ /**
+ * @var LoadOptionById
+ */
+ private $loadOptionById;
+
+ /**
+ * @var SortValues
+ */
+ private $sortValues;
+
+ /**
+ * GetConfigurableOptions constructor.
+ *
+ * @param LoadOptionById $loadOptions
+ * @param SortValues $sortValues
+ */
+ public function __construct(LoadOptionById $loadOptions, SortValues $sortValues)
+ {
+ $this->loadOptionById = $loadOptions;
+ $this->sortValues = $sortValues;
+ }
+
+ /**
+ * @param string $attributeCode
+ * @param int $storeId
+ * @param array $configurableChildren
+ *
+ * @return array
+ */
+ public function execute(string $attributeCode, int $storeId, array $configurableChildren): array
+ {
+ $values = [];
+
+ foreach ($configurableChildren as $child) {
+ if (isset($child[$attributeCode])) {
+ $value = $child[$attributeCode];
+
+ if (isset($value)) {
+ $values[] = (int) $value;
+ }
+ }
+ }
+
+ $values = array_values(array_unique($values));
+ $options = [];
+
+ foreach ($values as $value) {
+ $option = $this->loadOptionById->execute($attributeCode, $value, $storeId);
+ $options[] = $option;
+ }
+
+ return $this->sortValues->execute($options);
+ }
+}
diff --git a/src/module-vsbridge-indexer-catalog/Model/Indexer/DataProvider/Attribute/Options.php b/src/module-vsbridge-indexer-catalog/Model/Indexer/DataProvider/Attribute/Options.php
index f520cd51..93222694 100644
--- a/src/module-vsbridge-indexer-catalog/Model/Indexer/DataProvider/Attribute/Options.php
+++ b/src/module-vsbridge-indexer-catalog/Model/Indexer/DataProvider/Attribute/Options.php
@@ -9,12 +9,8 @@
namespace Divante\VsbridgeIndexerCatalog\Model\Indexer\DataProvider\Attribute;
use Divante\VsbridgeIndexerCore\Api\DataProviderInterface;
-use Magento\Eav\Model\Entity\AttributeFactory;
-use Magento\Eav\Model\Entity\Attribute\Source\Table as SourceTable;
+use Divante\VsbridgeIndexerCatalog\Model\Attribute\LoadOptions;
use Magento\Eav\Model\ResourceModel\Entity\Attribute as EntityResource;
-use Magento\Eav\Model\ResourceModel\Entity\Attribute\Option\Collection as OptionCollection;
-use Magento\Eav\Model\ResourceModel\Entity\Attribute\Option\CollectionFactory;
-use Magento\Framework\Validator\UniversalFactory;
/**
* Class Options
@@ -23,19 +19,9 @@ class Options implements DataProviderInterface
{
/**
- * @var UniversalFactory
+ * @var LoadOptions
*/
- private $universalFactory;
-
- /**
- * @var CollectionFactory
- */
- private $collectionFactory;
-
- /**
- * @var AttributeFactory
- */
- private $attributeFactory;
+ private $loadOptions;
/**
* @var EntityResource
@@ -45,20 +31,14 @@ class Options implements DataProviderInterface
/**
* Options constructor.
*
- * @param CollectionFactory $collectionFactory
- * @param AttributeFactory $attributeFactory
- * @param UniversalFactory $universalFactory
+ * @param LoadOptions $loadOptions
* @param EntityResource $entityResource
*/
public function __construct(
- CollectionFactory $collectionFactory,
- AttributeFactory $attributeFactory,
- UniversalFactory $universalFactory,
+ LoadOptions $loadOptions,
EntityResource $entityResource
) {
- $this->attributeFactory = $attributeFactory;
- $this->collectionFactory = $collectionFactory;
- $this->universalFactory = $universalFactory;
+ $this->loadOptions = $loadOptions;
$this->entityAttributeResource = $entityResource;
}
@@ -93,73 +73,9 @@ public function addData(array $indexData, $storeId)
*/
public function getAttributeOptions(array $attributeData, $storeId)
{
- $values = [];
- $source = (string)$attributeData['source_model'];
- $attributeId = $attributeData['attribute_id'];
-
- if ('' !== $source && SourceTable::class !== $source) {
- $sourceModel = $this->universalFactory->create($source);
-
- if (false !== $sourceModel) {
- if ($sourceModel instanceof \Magento\Eav\Model\Entity\Attribute\Source\AbstractSource) {
- ///** @var Attribute $attribute */
- $attribute = $this->attributeFactory->create($attributeData);
- $attribute->setStoreId($storeId);
- $sourceModel->setAttribute($attribute);
- }
-
- $values = $sourceModel->getAllOptions(false);
- }
- } else {
- /** @var OptionCollection $options */
- $options = $this->collectionFactory->create();
- $options->setOrder('sort_order', 'asc');
- $options->setAttributeFilter($attributeId)->setStoreFilter($storeId);
- $values = $this->toOptionArray($options);
- }
-
- return $values;
+ return $this->loadOptions->execute($attributeData['attribute_code'], $storeId);
}
-
- /**
- * @param OptionCollection $collection
- *
- * @param array $additional
- *
- * @return array
- */
- public function toOptionArray(OptionCollection $collection, array $additional = [])
- {
- $res = [];
- $additional['value'] = 'option_id';
- $additional['label'] = 'value';
- $additional['sort_order'] = 'sort_order';
-
- foreach ($collection as $item) {
- $data = [];
-
- foreach ($additional as $code => $field) {
- $value = $item->getData($field);
-
- if ($field === 'sort_order') {
- $value = (int)$value;
- }
-
- if ($field === 'option_id') {
- $value = (string)$value;
- }
-
- $data[$code] = $value;
- }
-
- if ($data) {
- $res[] = $data;
- }
- }
-
- return $res;
- }
-
+
/**
* @param array $attributeData
*
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 99417139..c9d22614 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
@@ -8,7 +8,7 @@
namespace Divante\VsbridgeIndexerCatalog\Model\Indexer\DataProvider\Product;
-use Divante\VsbridgeIndexerCatalog\Model\Attribute\LoadOptionLabelById;
+use Divante\VsbridgeIndexerCatalog\Model\ConfigurableProcessor\GetConfigurableOptions;
use Divante\VsbridgeIndexerCatalog\Model\Attributes\ConfigurableAttributes;
use Divante\VsbridgeIndexerCatalog\Model\InventoryProcessor;
use Divante\VsbridgeIndexerCatalog\Model\ResourceModel\Product\AttributeDataProvider;
@@ -77,9 +77,9 @@ class ConfigurableData implements DataProviderInterface
private $tierPriceProcessor;
/**
- * @var LoadOptionLabelById
+ * @var GetConfigurableOptions
*/
- private $loadOptionLabelById;
+ private $configurableProcessor;
/**
* ConfigurableData constructor.
@@ -88,7 +88,7 @@ class ConfigurableData implements DataProviderInterface
* @param ConfigurableResource $configurableResource
* @param AttributeDataProvider $attributeResource
* @param LoadInventoryInterface $loadInventory
- * @param LoadOptionLabelById $loadOptionLabelById
+ * @param GetConfigurableOptions $configurableProcessor
* @param ConfigurableAttributes $configurableAttributes
* @param TierPriceProcessor $tierPriceProcessor
* @param InventoryProcessor $inventoryProcessor
@@ -98,7 +98,7 @@ public function __construct(
ConfigurableResource $configurableResource,
AttributeDataProvider $attributeResource,
LoadInventoryInterface $loadInventory,
- LoadOptionLabelById $loadOptionLabelById,
+ GetConfigurableOptions $configurableProcessor,
ConfigurableAttributes $configurableAttributes,
TierPriceProcessor $tierPriceProcessor,
InventoryProcessor $inventoryProcessor
@@ -109,7 +109,7 @@ public function __construct(
$this->loadInventory = $loadInventory;
$this->inventoryProcessor = $inventoryProcessor;
$this->tierPriceProcessor = $tierPriceProcessor;
- $this->loadOptionLabelById = $loadOptionLabelById;
+ $this->configurableProcessor = $configurableProcessor;
$this->configurableAttributes = $configurableAttributes;
}
@@ -140,7 +140,7 @@ public function addData(array $indexData, $storeId)
* Skip exporting configurable products without options
*/
if (!empty($productDTO['configurable_options'])) {
- $productsList[$productId] = $this->prepareConfigurableProduct($productDTO);;
+ $productsList[$productId] = $this->prepareConfigurableProduct($productDTO);
}
}
@@ -220,7 +220,7 @@ private function getRequiredChildrenAttributes()
/**
* Apply attributes to product variants + extra options for products necessary for vsf
* @param array $productDTO
- * @param $storeId
+ * @param int $storeId
*
* @return array
* @throws \Exception
@@ -231,6 +231,8 @@ private function applyConfigurableOptions(array $productDTO, $storeId)
$productAttributeOptions =
$this->configurableResource->getProductConfigurableAttributes($productDTO);
+ $productDTO['configurable_children'] = $configurableChildren;
+
foreach ($productAttributeOptions as $productAttribute) {
$attributeCode = $productAttribute['attribute_code'];
@@ -238,26 +240,19 @@ private function applyConfigurableOptions(array $productDTO, $storeId)
$productDTO[$attributeCode . '_options'] = [];
}
- $values = [];
-
- foreach ($configurableChildren as $child) {
- if (isset($child[$attributeCode])) {
- $value = $child[$attributeCode];
-
- if (isset($value)) {
- $values[] = (int) $value;
- }
- }
- }
+ $options = $this->configurableProcessor->execute(
+ $attributeCode,
+ $storeId,
+ $configurableChildren
+ );
- $productDTO['configurable_children'] = $configurableChildren;
- $values = array_values(array_unique($values));
+ $values = [];
- foreach ($values as $value) {
- $label = $this->loadOptionLabelById->execute($attributeCode, $value, $storeId);
+ foreach ($options as $option) {
+ $values[] = (int)$option['value'];
$productAttribute['values'][] = [
- 'value_index' => $value,
- 'label' => $label,
+ 'value_index' => $option['value'],
+ 'label' => $option['label'],
];
}
diff --git a/src/module-vsbridge-indexer-catalog/Model/ResourceModel/AbstractEavAttributes.php b/src/module-vsbridge-indexer-catalog/Model/ResourceModel/AbstractEavAttributes.php
index ddb521c2..b06b8b15 100644
--- a/src/module-vsbridge-indexer-catalog/Model/ResourceModel/AbstractEavAttributes.php
+++ b/src/module-vsbridge-indexer-catalog/Model/ResourceModel/AbstractEavAttributes.php
@@ -175,6 +175,7 @@ private function prepareValues(array $values)
* @param mixed $value
*
* @return mixed
+ * @SuppressWarnings("unused")
*/
private function parseValue($value)
{
diff --git a/src/module-vsbridge-indexer-catalog/Model/ResourceModel/Category.php b/src/module-vsbridge-indexer-catalog/Model/ResourceModel/Category.php
index 022e7747..6780233b 100644
--- a/src/module-vsbridge-indexer-catalog/Model/ResourceModel/Category.php
+++ b/src/module-vsbridge-indexer-catalog/Model/ResourceModel/Category.php
@@ -170,6 +170,28 @@ public function getParentIds(array $categoryIds)
return array_unique($parentIds);
}
+ /**
+ * @param int $categoryId
+ *
+ * @return int[]
+ * @throws \Exception
+ */
+ public function getAllSubCategories(int $categoryId): array
+ {
+ $metaData = $this->categoryMetaData->get();
+ $entityField = $metaData->getIdentifierField();
+ $connection = $this->getConnection();
+ $select = $connection->select()->from(
+ ['entity' => $metaData->getEntityTable()],
+ [$entityField]
+ );
+
+ $catIdExpr = $connection->quote("%/{$categoryId}/%");
+ $select->where("path like {$catIdExpr}");
+
+ return $connection->fetchCol($select);
+ }
+
/**
* @return \Magento\Framework\DB\Adapter\AdapterInterface
*/
diff --git a/src/module-vsbridge-indexer-catalog/Model/ResourceModel/Product.php b/src/module-vsbridge-indexer-catalog/Model/ResourceModel/Product.php
index c1721a5c..000fcd5c 100644
--- a/src/module-vsbridge-indexer-catalog/Model/ResourceModel/Product.php
+++ b/src/module-vsbridge-indexer-catalog/Model/ResourceModel/Product.php
@@ -9,13 +9,13 @@
namespace Divante\VsbridgeIndexerCatalog\Model\ResourceModel;
use Divante\VsbridgeIndexerCatalog\Api\Data\CatalogConfigurationInterface;
+use Divante\VsbridgeIndexerCatalog\Model\ProductMetaData;
use Divante\VsbridgeIndexerCatalog\Model\ResourceModel\Product\AttributeDataProvider;
use Magento\Catalog\Model\Product\Attribute\Source\Status;
use Magento\Framework\App\ResourceConnection;
use Magento\Framework\DB\Helper as DbHelper;
use Magento\Framework\DB\Select;
use Magento\Store\Model\StoreManagerInterface;
-use Divante\VsbridgeIndexerCatalog\Model\ProductMetaData;
/**
* Class Product
@@ -97,11 +97,8 @@ public function __construct(
*/
public function getProducts($storeId = 1, array $productIds = [], $fromId = 0, $limit = 1000)
{
- $select = $this->getConnection()->select()
- ->from(
- ['entity' => $this->productMetaData->get()->getEntityTable()],
- $this->getRequiredColumns()
- );
+ $select = $this->prepareBaseProductSelect($this->getRequiredColumns(), $storeId);
+ $select = $this->addProductTypeFilter($select, $storeId);
if (!empty($productIds)) {
$select->where('entity.entity_id IN (?)', $productIds);
@@ -110,16 +107,34 @@ public function getProducts($storeId = 1, array $productIds = [], $fromId = 0, $
$select->limit($limit);
$select->where('entity.entity_id > ?', $fromId);
$select->order('entity.entity_id ASC');
+
+ return $this->getConnection()->fetchAll($select);
+ }
+
+ /**
+ * @param array $requiredColumns
+ * @param int $storeId
+ *
+ * @return Select
+ * @throws \Magento\Framework\Exception\LocalizedException
+ * @throws \Magento\Framework\Exception\NoSuchEntityException
+ */
+ public function prepareBaseProductSelect(array $requiredColumns, int $storeId)
+ {
+ $select = $this->getConnection()->select()
+ ->from(
+ ['entity' => $this->productMetaData->get()->getEntityTable()],
+ $requiredColumns
+ );
+
$select = $this->addStatusFilter($select, $storeId);
$select = $this->addWebsiteFilter($select, $storeId);
- $select = $this->addProductTypeFilter($select, $storeId);
- return $this->getConnection()->fetchAll($select);
+ return $select;
}
/**
* @return array
- * @throws \Exception
*/
private function getRequiredColumns()
{
@@ -162,10 +177,7 @@ public function loadChildrenProducts(array $parentIds, $storeId)
$columns[] = $linkField;
}
- $select = $this->getConnection()->select()->from(
- ['entity' => $this->productMetaData->get()->getEntityTable()],
- $columns
- );
+ $select = $this->prepareBaseProductSelect($columns, $storeId);
$select->join(
['link_table' => $this->resourceConnection->getTableName('catalog_product_super_link')],
@@ -173,13 +185,10 @@ public function loadChildrenProducts(array $parentIds, $storeId)
[]
);
- $select = $this->addStatusFilter($select, $storeId);
-
$select->where('link_table.parent_id IN (?)', $parentIds);
$select->group('entity_id');
$this->dbHelper->addGroupConcatColumn($select, 'parent_ids', 'parent_id');
- $select = $this->addWebsiteFilter($select, $storeId);
return $this->getConnection()->fetchAll($select);
}
@@ -256,29 +265,6 @@ public function getRelationsByChild(array $childrenIds)
return $this->getConnection()->fetchCol($select);
}
- /**
- * @param int $storeId
- * @param array $productIds
- *
- * @return array
- *
- * @throws \Magento\Framework\Exception\LocalizedException
- * @throws \Magento\Framework\Exception\NoSuchEntityException
- */
- public function getEnableProductIds($storeId, array $productIds)
- {
- $select = $this->getConnection()->select()
- ->from(['e' => $this->resourceConnection->getTableName('catalog_product_entity')]);
- $select->where('e.entity_id IN (?)', $productIds);
- $select->order('e.entity_id ASC');
- $select = $this->addStatusFilter($select, $storeId);
- $select = $this->addWebsiteFilter($select, $storeId);
- $select->reset(Select::COLUMNS);
- $select->columns(['entity_id']);
-
- return $this->getConnection()->fetchCol($select);
- }
-
/**
* @param \Magento\Framework\DB\Select $select
* @param int $storeId
diff --git a/src/module-vsbridge-indexer-catalog/Plugin/Indexer/Category/Save/UpdateCategoryDataPlugin.php b/src/module-vsbridge-indexer-catalog/Plugin/Indexer/Category/Save/UpdateCategoryDataPlugin.php
index 6493ac48..1de8e6d7 100644
--- a/src/module-vsbridge-indexer-catalog/Plugin/Indexer/Category/Save/UpdateCategoryDataPlugin.php
+++ b/src/module-vsbridge-indexer-catalog/Plugin/Indexer/Category/Save/UpdateCategoryDataPlugin.php
@@ -9,6 +9,8 @@
namespace Divante\VsbridgeIndexerCatalog\Plugin\Indexer\Category\Save;
use Divante\VsbridgeIndexerCatalog\Model\Indexer\CategoryProcessor;
+use Divante\VsbridgeIndexerCatalog\Model\ResourceModel\Category as CategoryResourceModel;
+
use Magento\Catalog\Model\Category;
/**
@@ -16,19 +18,28 @@
*/
class UpdateCategoryDataPlugin
{
+ /**
+ * @var CategoryResourceModel
+ */
+ private $resourceModel;
+
/**
* @var CategoryProcessor
*/
private $categoryProcessor;
/**
- * UpdateProductData constructor.
+ * UpdateCategoryDataPlugin constructor.
*
+ * @param CategoryResourceModel $resourceModel
* @param CategoryProcessor $processor
*/
- public function __construct(CategoryProcessor $processor)
- {
+ public function __construct(
+ CategoryResourceModel $resourceModel,
+ CategoryProcessor $processor
+ ) {
$this->categoryProcessor = $processor;
+ $this->resourceModel = $resourceModel;
}
/**
@@ -40,6 +51,17 @@ public function __construct(CategoryProcessor $processor)
*/
public function afterReindex(Category $category)
{
- $this->categoryProcessor->reindexRow($category->getId());
+ $categoryIds = [];
+ $originalUrlKey = $category->getOrigData('url_key');
+ $urlKey = $category->getData('url_key');
+ $categoryId = (int) $category->getId();
+
+ if (!$category->isObjectNew() && $originalUrlKey !== $urlKey) {
+ $categoryIds = $this->resourceModel->getAllSubCategories($categoryId);
+ }
+
+ $categoryIds[] = $categoryId;
+
+ $this->categoryProcessor->reindexList($categoryIds);
}
}
diff --git a/src/module-vsbridge-indexer-catalog/etc/di.xml b/src/module-vsbridge-indexer-catalog/etc/di.xml
index b67f5743..adb17d3b 100644
--- a/src/module-vsbridge-indexer-catalog/etc/di.xml
+++ b/src/module-vsbridge-indexer-catalog/etc/di.xml
@@ -137,4 +137,18 @@
+
+
+
+ - Divante\VsbridgeIndexerCore\Api\Mapping\FieldInterface::TYPE_INTEGER
+ - Divante\VsbridgeIndexerCore\Api\Mapping\FieldInterface::TYPE_INTEGER
+ - Divante\VsbridgeIndexerCore\Api\Mapping\FieldInterface::TYPE_LONG
+ - Divante\VsbridgeIndexerCore\Api\Mapping\FieldInterface::TYPE_INTEGER
+ - Divante\VsbridgeIndexerCore\Api\Mapping\FieldInterface::TYPE_LONG
+ - Divante\VsbridgeIndexerCore\Api\Mapping\FieldInterface::TYPE_KEYWORD
+ - Divante\VsbridgeIndexerCore\Api\Mapping\FieldInterface::TYPE_KEYWORD
+ - Divante\VsbridgeIndexerCore\Api\Mapping\FieldInterface::TYPE_KEYWORD
+
+
+
diff --git a/src/module-vsbridge-indexer-core/Console/Command/RebuildEsIndexCommand.php b/src/module-vsbridge-indexer-core/Console/Command/RebuildEsIndexCommand.php
index 4b9e5553..78a56c2a 100644
--- a/src/module-vsbridge-indexer-core/Console/Command/RebuildEsIndexCommand.php
+++ b/src/module-vsbridge-indexer-core/Console/Command/RebuildEsIndexCommand.php
@@ -11,21 +11,21 @@
use Divante\VsbridgeIndexerCatalog\Model\Indexer\ProductCategoryProcessor;
use Divante\VsbridgeIndexerCore\Indexer\StoreManager;
use Divante\VsbridgeIndexerCore\Index\IndexOperations;
-use Magento\Backend\App\Area\FrontNameResolver;
-use Magento\Framework\Indexer\IndexerInterface;
+use Magento\Framework\App\ObjectManagerFactory;
use Magento\Framework\Console\Cli;
use Magento\Framework\Exception\LocalizedException;
-use Magento\Framework\Indexer\IndexerRegistry;
+use Magento\Framework\Indexer\IndexerInterface;
+use Magento\Indexer\Console\Command\AbstractIndexerCommand;
use Magento\Store\Api\Data\StoreInterface;
use Symfony\Component\Console\Input\InputOption;
-use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
+use Magento\Store\Model\StoreManagerInterface as StoreManagerInterface;
/**
* Class IndexerReindexCommand
*/
-class RebuildEsIndexCommand extends Command
+class RebuildEsIndexCommand extends AbstractIndexerCommand
{
const INPUT_STORE = 'store';
const INPUT_ALL_STORES = 'all';
@@ -33,11 +33,6 @@ class RebuildEsIndexCommand extends Command
const INDEX_IDENTIFIER = 'vue_storefront_catalog';
- /**
- * @var \Magento\Indexer\Model\Indexer\CollectionFactory
- */
- private $collectionFactory;
-
/**
* @var IndexOperations
*/
@@ -46,40 +41,21 @@ class RebuildEsIndexCommand extends Command
/**
* @var StoreManager
*/
- private $storeManager;
-
- /**
- * @var IndexerRegistry
- */
- private $indexerRegistry;
+ private $indexerStoreManager;
/**
- * @var \Magento\Framework\App\State
+ * @var StoreManagerInterface
*/
- private $state;
+ private $storeManager;
/**
- * Construct
+ * RebuildEsIndexCommand constructor.
*
- * @param \Magento\Framework\Indexer\IndexerRegistry $indexerRegistry
- * @param IndexOperations\Proxy $indexOperations
- * @param StoreManager\Proxy $storeManager
- * @param \Magento\Framework\App\State\Proxy $state
- * @param \Magento\Indexer\Model\Indexer\CollectionFactory\Proxy $collectionFactory
+ * @param ObjectManagerFactory $objectManagerFactory
*/
- public function __construct(
- IndexerRegistry $indexerRegistry,
- IndexOperations $indexOperations,
- StoreManager $storeManager,
- \Magento\Framework\App\State $state,
- \Magento\Indexer\Model\Indexer\CollectionFactory $collectionFactory
- ) {
- $this->indexerRegistry = $indexerRegistry;
- $this->collectionFactory = $collectionFactory;
- $this->indexOperations = $indexOperations;
- $this->storeManager = $storeManager;
- $this->state = $state;
- parent::__construct();
+ public function __construct(ObjectManagerFactory $objectManagerFactory)
+ {
+ parent::__construct($objectManagerFactory);
}
/**
@@ -120,33 +96,28 @@ 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);
$deleteIndex = $input->getOption(self::INPUT_DELETE_INDEX);
if ($storeId) {
- $stores = $this->storeManager->getStores($storeId);
+ $store = $this->getStoreManager()->getStore($storeId);
+ $output->writeln("Reindexing all VS indexes for store " . $store->getName() . "...");
- if (!empty($stores)) {
- /** @var \Magento\Store\Api\Data\StoreInterface $store */
- $store = $stores[0];
- $output->writeln("Reindexing all VS indexes for store " . $store->getName() . "...");
+ $returnValue = $this->reindexStore($store, $deleteIndex, $output);
- $this->setAreaCode();
- $returnValue = $this->reindexStore($store, $deleteIndex, $output);
+ $output->writeln("Reindexing has completed!");
- $output->writeln("Reindexing has completed!");
+ return $returnValue;
- return $returnValue;
- }
} elseif ($allStores) {
$output->writeln("Reindexing all stores...");
- $this->setAreaCode();
$returnValues = [];
/** @var \Magento\Store\Api\Data\StoreInterface $store */
- foreach ($this->storeManager->getStores() as $store) {
+ foreach ($this->getStoreManager()->getStores() as $store) {
$output->writeln("Reindexing store " . $store->getName() . "...");
$returnValues[] = $this->reindexStore($store, $deleteIndex, $output);
}
@@ -161,6 +132,42 @@ protected function execute(InputInterface $input, OutputInterface $output)
}
}
+ /**
+ * @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 IndexOperations
+ */
+ private function getIndexOperations()
+ {
+ if (null === $this->indexOperations) {
+ $this->indexOperations = $this->getObjectManager()->get(IndexOperations::class);
+ }
+
+ return $this->indexOperations;
+ }
+
/**
* Reindex each vsbridge index for the specified store
*
@@ -172,10 +179,12 @@ protected function execute(InputInterface $input, OutputInterface $output)
*/
private function reindexStore(StoreInterface $store, bool $deleteIndex, OutputInterface $output)
{
+ $this->getIndexerStoreManager()->setLoadedStores([$store]);
+
if ($deleteIndex) {
$output->writeln("Deleting and recreating the index first...");
- $this->indexOperations->deleteIndex(self::INDEX_IDENTIFIER, $store);
- $this->indexOperations->createIndex(self::INDEX_IDENTIFIER, $store);
+ $this->getIndexOperations()->deleteIndex(self::INDEX_IDENTIFIER, $store);
+ $this->getIndexOperations()->createIndex(self::INDEX_IDENTIFIER, $store);
}
$returnValue = Cli::RETURN_FAILURE;
@@ -202,24 +211,14 @@ private function reindexStore(StoreInterface $store, bool $deleteIndex, OutputIn
return $returnValue;
}
- /**
- * @return void
- */
- private function setAreaCode()
- {
- try {
- $this->state->setAreaCode(FrontNameResolver::AREA_CODE);
- } catch (\Exception $e) {
- }
- }
-
/**
* @return IndexerInterface[]
*/
- protected function getIndexers()
+ private function getIndexers()
{
/** @var IndexerInterface[] */
- $indexers = $this->collectionFactory->create()->getItems();
+ $indexers = $this->getAllIndexers();
+
unset($indexers[ProductCategoryProcessor::INDEXER_ID]);
$vsbridgeIndexers = [];
@@ -231,4 +230,12 @@ protected function getIndexers()
return $vsbridgeIndexers;
}
+
+ /**
+ * Initiliaze object manager
+ */
+ private function initObjectManager()
+ {
+ $this->getObjectManager();
+ }
}
diff --git a/src/module-vsbridge-indexer-core/Indexer/StoreManager.php b/src/module-vsbridge-indexer-core/Indexer/StoreManager.php
index 9a1e281f..3a397983 100644
--- a/src/module-vsbridge-indexer-core/Indexer/StoreManager.php
+++ b/src/module-vsbridge-indexer-core/Indexer/StoreManager.php
@@ -52,7 +52,6 @@ public function __construct(
* @return array|\Magento\Store\Api\Data\StoreInterface[]
* @throws \Magento\Framework\Exception\NoSuchEntityException
*/
-
public function getStores($storeId = null)
{
if (null === $this->loadedStores) {
@@ -80,4 +79,12 @@ public function getStores($storeId = null)
return $this->loadedStores;
}
+
+ /**
+ * @param array $stores
+ */
+ public function setLoadedStores(array $stores)
+ {
+ $this->loadedStores = $stores;
+ }
}
diff --git a/src/module-vsbridge-indexer-core/etc/di.xml b/src/module-vsbridge-indexer-core/etc/di.xml
index 9a079c59..8f3dd332 100644
--- a/src/module-vsbridge-indexer-core/etc/di.xml
+++ b/src/module-vsbridge-indexer-core/etc/di.xml
@@ -67,14 +67,4 @@
-
-
-
-
- Divante\VsbridgeIndexerCore\Index\IndexOperations\Proxy
- Divante\VsbridgeIndexerCore\Indexer\StoreManager\Proxy
- Magento\Framework\App\State\Proxy
- Magento\Indexer\Model\Indexer\CollectionFactory\Proxy
-
-
diff --git a/src/module-vsbridge-indexer-tax/ResourceModel/Rates.php b/src/module-vsbridge-indexer-tax/ResourceModel/Rates.php
index 6e9839a1..be077a73 100644
--- a/src/module-vsbridge-indexer-tax/ResourceModel/Rates.php
+++ b/src/module-vsbridge-indexer-tax/ResourceModel/Rates.php
@@ -50,7 +50,7 @@ public function loadTaxRates(array $ruleIds)
->where('tax_calculation_rule_id IN (?)', $ruleIds);
$select->distinct(true);
- return $this->getConnection()->fetchAssoc($select);
+ return $this->getConnection()->fetchAll($select);
}
/**