From 7ddfeee2229a05981df0c577ea83bc2ab5ae46af Mon Sep 17 00:00:00 2001 From: Vadym Honcharuk Date: Mon, 15 May 2023 16:39:01 +0300 Subject: [PATCH 1/9] WIP: Feature #2911, allow to export/import attributes configuration from admin --- .../Attribute/ExportProductAttributeCsv.php | 161 ++++++++++++ .../Model/Import/ProductAttribute.php | 235 ++++++++++++++++++ .../Model/Source/Import/Behavior/Custom.php | 36 +++ .../ProductAttributeGridColumnObserver.php | 73 ++++++ .../ProductAttributeGridExportObserver.php | 46 ++++ .../etc/adminhtml/events.xml | 28 +++ .../etc/adminhtml/routes.xml | 3 + .../etc/import.xml | 26 ++ .../etc/module.xml | 1 + .../adminhtml/web/css/source/_module.less | 10 + 10 files changed, 619 insertions(+) create mode 100644 src/module-elasticsuite-catalog/Controller/Adminhtml/Product/Attribute/ExportProductAttributeCsv.php create mode 100644 src/module-elasticsuite-catalog/Model/Import/ProductAttribute.php create mode 100644 src/module-elasticsuite-catalog/Model/Source/Import/Behavior/Custom.php create mode 100644 src/module-elasticsuite-catalog/Observer/Grid/ProductAttributeGridColumnObserver.php create mode 100644 src/module-elasticsuite-catalog/Observer/Grid/ProductAttributeGridExportObserver.php create mode 100644 src/module-elasticsuite-catalog/etc/adminhtml/events.xml create mode 100644 src/module-elasticsuite-catalog/etc/import.xml diff --git a/src/module-elasticsuite-catalog/Controller/Adminhtml/Product/Attribute/ExportProductAttributeCsv.php b/src/module-elasticsuite-catalog/Controller/Adminhtml/Product/Attribute/ExportProductAttributeCsv.php new file mode 100644 index 000000000..659555aa9 --- /dev/null +++ b/src/module-elasticsuite-catalog/Controller/Adminhtml/Product/Attribute/ExportProductAttributeCsv.php @@ -0,0 +1,161 @@ + + * @copyright 2023 Smile + * @license Open Software License ("OSL") v. 3.0 + */ +namespace Smile\ElasticsuiteCatalog\Controller\Adminhtml\Product\Attribute; + +use Magento\Backend\App\Action; +use Magento\Backend\App\Action\Context; +use Magento\Backend\Model\View\Result\Redirect; +use Magento\Framework\App\Filesystem\DirectoryList; +use Magento\Framework\App\Response\Http\FileFactory; +use Magento\Framework\App\ResponseInterface; +use Magento\Framework\Controller\ResultInterface; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Framework\Filesystem; +use Magento\Framework\View\Result\PageFactory; +use Magento\Catalog\Model\ResourceModel\Product\Attribute\CollectionFactory; +use Smile\ElasticsuiteCatalog\Model\Import\ProductAttribute as ProductAttributeImport; + +/** + * Product attribute export to CSV controller. + * + * @category Smile + * @package Smile\ElasticsuiteCatalog + * @author Vadym Honcharuk + */ +class ExportProductAttributeCsv extends Action +{ + /** + * @var PageFactory + */ + protected $resultPageFactory; + + /** + * @var FileFactory + */ + protected $fileFactory; + + /** + * @var CollectionFactory + */ + protected $attributeCollectionFactory; + + /** + * @var Filesystem + */ + protected $filesystem; + + /** + * @var array + */ + private $columns; + + /** + * Constructor. + * + * @param Context $context Application context. + * @param PageFactory $resultPageFactory Result Page factory. + * @param FileFactory $fileFactory File Factory. + * @param Filesystem $filesystem File System. + * @param CollectionFactory $attributeCollectionFactory Attribute Collection Factory. + * @param ProductAttributeImport $productAttributeImport Product Attribute Import Model. + */ + public function __construct( + Context $context, + PageFactory $resultPageFactory, + FileFactory $fileFactory, + Filesystem $filesystem, + CollectionFactory $attributeCollectionFactory, + ProductAttributeImport $productAttributeImport + ) { + parent::__construct($context); + $this->resultPageFactory = $resultPageFactory; + $this->fileFactory = $fileFactory; + $this->filesystem = $filesystem; + $this->attributeCollectionFactory = $attributeCollectionFactory; + $this->columns = $productAttributeImport->getValidColumnNames(); + } + + /** + * Execute. + * + * @return Redirect|ResponseInterface|ResultInterface|void + * @throws LocalizedException + * @throws NoSuchEntityException + */ + public function execute() + { + // Prepare product attributes grid collection. + $attributeCollectionFactory = $this->attributeCollectionFactory->create(); + $attributeCollection = $attributeCollectionFactory->addVisibleFilter() + ->setOrder('attribute_code', 'ASC'); + + $content = []; + + // Add header row. + $header = []; + foreach ($this->columns as $column) { + $header[] = $column; + } + $content[] = $header; + + // Add content row. + foreach ($attributeCollection as $attribute) { + $row = [ + $attribute->getAttributeCode(), + $attribute->getDefaultFrontendLabel(), + $attribute->getIsSearchable(), + $attribute->getSearchWeight(), + $attribute->getIsUsedInSpellcheck(), + $attribute->getIsDisplayedInAutocomplete(), + $attribute->getIsFilterable(), + $attribute->getIsFilterableInSearch(), + $attribute->getIsUsedForPromoRules(), + $attribute->getUsedForSortBy(), + $attribute->getIsDisplayRelNofollow(), + $attribute->getFacetMaxSize(), + $attribute->getFacetSortOrder(), + $attribute->getFacetMinCoverageRate(), + $attribute->getFacetBooleanLogic(), + $attribute->getPosition(), + $attribute->getDefaultAnalyzer(), + $attribute->getNormsDisabled(), + $attribute->getIsSpannable(), + $attribute->getIncludeZeroFalseValues(), + ]; + $content[] = $row; + } + + // Prepare and send the CSV file to the browser. + $date = date('Ymd_His'); + $fileName = 'product_attributes-' . $date . '.csv'; + $directory = $this->filesystem->getDirectoryWrite(DirectoryList::VAR_DIR); + $stream = $directory->openFile($fileName, 'w+'); + foreach ($content as $line) { + $stream->writeCsv($line); + } + $stream->close(); + + $this->fileFactory->create( + $fileName, + [ + 'type' => 'filename', + 'value' => $fileName, + 'rm' => true, + ], + DirectoryList::VAR_DIR, + 'application/csv' + ); + } +} diff --git a/src/module-elasticsuite-catalog/Model/Import/ProductAttribute.php b/src/module-elasticsuite-catalog/Model/Import/ProductAttribute.php new file mode 100644 index 000000000..185ad9e09 --- /dev/null +++ b/src/module-elasticsuite-catalog/Model/Import/ProductAttribute.php @@ -0,0 +1,235 @@ + + * @copyright 2023 Smile + * @license Open Software License ("OSL") v. 3.0 + */ +namespace Smile\ElasticsuiteCatalog\Model\Import; + +use Magento\Catalog\Model\ResourceModel\Eav\Attribute; +use Magento\Eav\Model\Config; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\Json\Helper\Data as JsonHelper; +use Magento\ImportExport\Helper\Data as ImportHelper; +use Magento\ImportExport\Model\Import\Entity\AbstractEntity; +use Magento\ImportExport\Model\Import\ErrorProcessing\ProcessingErrorAggregatorInterface; +use Magento\ImportExport\Model\ResourceModel\Helper; +use Magento\ImportExport\Model\ResourceModel\Import\Data; + +/** + * Product attribute import model. + * + * @category Smile + * @package Smile\ElasticsuiteCatalog + * @author Vadym Honcharuk + */ +class ProductAttribute extends AbstractEntity +{ + /** + * Entity type code. + */ + const ENTITY_TYPE_CODE = 'catalog_product'; + + /** + * Permanent entity columns. + * + * @var array + */ + protected $_permanentAttributes = [ + 'attribute_code', + 'attribute_label' + ]; + + /** + * Valid column names. + * + * @var array + */ + protected $validColumnNames = [ + 'attribute_code', + 'attribute_label', + 'is_searchable', + 'search_weight', + 'is_used_in_spellcheck', + 'is_displayed_in_autocomplete', + 'is_filterable', + 'is_filterable_in_search', + 'is_used_for_promo_rules', + 'used_for_sort_by', + 'is_display_rel_nofollow', + 'facet_max_size', + 'facet_sort_order', + 'facet_min_coverage_rate', + 'facet_boolean_logic', + 'position', + 'default_analyzer', + 'norms_disabled', + 'is_spannable', + 'include_zero_false_values', + ]; + + /** + * @var Config + */ + private $_eavConfig; + + /** + * Import constructor. + * + * @param JsonHelper $jsonHelper Json Helper. + * @param ImportHelper $importExportData Import Helper. + * @param Data $importData Import Data. + * @param Config $eavConfig EAV Config. + * @param Helper $resourceHelper Resource Helper. + * @param ProcessingErrorAggregatorInterface $errorAggregator Error Aggregator. + */ + public function __construct( + JsonHelper $jsonHelper, + ImportHelper $importExportData, + Data $importData, + Config $eavConfig, + Helper $resourceHelper, + ProcessingErrorAggregatorInterface $errorAggregator + ) { + $this->jsonHelper = $jsonHelper; + $this->_importExportData = $importExportData; + $this->_dataSourceModel = $importData; + $this->_eavConfig = $eavConfig; + $this->_resourceHelper = $resourceHelper; + $this->errorAggregator = $errorAggregator; + } + + /** + * Entity type code getter. + * + * @return string + */ + public function getEntityTypeCode(): string + { + return self::ENTITY_TYPE_CODE; + } + + /** + * Get available columns. + * + * @return array + */ + public function getValidColumnNames(): array + { + return $this->validColumnNames; + } + + /** + * Validate data row. + * + * @param array $rowData Data. + * @param int $rowNum Row number. + * + * @return bool + * @throws LocalizedException + */ + public function validateRow(array $rowData, $rowNum) + { + $errors = []; + + // Validate if attribute exists. + $attributeCode = isset($rowData['attribute_code']) ? trim($rowData['attribute_code']) : ''; + if (!$attributeCode) { + $errors[] = __('Attribute code is required.'); + } else { + $attribute = $this->_eavConfig->getAttribute(self::ENTITY_TYPE_CODE, $attributeCode); + if (!$attribute->getId()) { + $errors[] = __('Attribute with code %1 does not exist.', $attributeCode); + } + } + + // Check if all the required columns are present. + foreach ($this->validColumnNames as $columnName) { + if (!isset($rowData[$columnName])) { + $errors[] = __('Column %1 is missing.', $columnName); + } + } + + if (!empty($errors)) { + foreach ($errors as $error) { + $this->addRowError($error, $rowNum); + } + return false; + } + + return true; + } + + /** + * Import data rows. + * + * @return bool + * @throws LocalizedException + */ + protected function _importData() + { + // Add import logic. + while ($bunch = $this->_dataSourceModel->getNextBunch()) { + foreach ($bunch as $rowData) { + $attributeCode = isset($rowData['attribute_code']) ? trim($rowData['attribute_code']) : ''; + $attribute = $this->_eavConfig->getAttribute(self::ENTITY_TYPE_CODE, $attributeCode); + $this->updateAttributeData($attribute, $rowData); + } + } + + return true; + } + + /** + * Update attribute data with new values from CSV. + * + * @param Attribute $attribute + * @param array $rowData + * @return bool + */ + private function updateAttributeData($attribute, $rowData) + { + $dataChanged = false; + + foreach ($rowData as $key => $value) { + // Skip permanent attributes. + if (in_array($key, $this->_permanentAttributes)) { + continue; + } + + // Skip empty values. + if (!isset($value) || $value === '') { + continue; + } + + // Update attribute data if new value is different from current value. + if ($attribute->getData($key) != $value) { + $attribute->setData($key, $value); + $dataChanged = true; + } + } + + // Check if attribute data has changed. + if ($dataChanged) { + try { + $attribute->save(); + } catch (\Exception $e) { + $this->_errors[] = __( + 'Row with attribute_code "%1" cannot be updated. Error: %2', + $attribute->getAttributeCode(), + $e->getMessage() + ); + return false; + } + } + + return true; + } +} diff --git a/src/module-elasticsuite-catalog/Model/Source/Import/Behavior/Custom.php b/src/module-elasticsuite-catalog/Model/Source/Import/Behavior/Custom.php new file mode 100644 index 000000000..b1c87d8e2 --- /dev/null +++ b/src/module-elasticsuite-catalog/Model/Source/Import/Behavior/Custom.php @@ -0,0 +1,36 @@ + __('Update') + ]; + } + + /** + * @inheritdoc + */ + public function getCode() + { + return 'custom'; + } +} diff --git a/src/module-elasticsuite-catalog/Observer/Grid/ProductAttributeGridColumnObserver.php b/src/module-elasticsuite-catalog/Observer/Grid/ProductAttributeGridColumnObserver.php new file mode 100644 index 000000000..15f202771 --- /dev/null +++ b/src/module-elasticsuite-catalog/Observer/Grid/ProductAttributeGridColumnObserver.php @@ -0,0 +1,73 @@ + + * @copyright 2023 Smile + * @license Open Software License ("OSL") v. 3.0 + */ +namespace Smile\ElasticsuiteCatalog\Observer\Grid; + +use Magento\Framework\Event\Observer; +use Magento\Framework\Event\ObserverInterface; + +/** + * This observer class observes the "product_attribute_grid_build" event. + * + * And adds two columns "Search Weight" and "Is filterable in search" to the product attribute grid. + * + * @category Smile + * @package Smile\ElasticsuiteCatalog + * @author Vadym Honcharuk + */ +class ProductAttributeGridColumnObserver implements ObserverInterface +{ + /** + * Execute. + * + * @param Observer $observer + * @return void + */ + public function execute(Observer $observer) + { + /** @var \Magento\Catalog\Block\Adminhtml\Product\Attribute\Grid $grid */ + $grid = $observer->getGrid(); + + // Add "Search Weight" column after "Searchable" column. + $grid->addColumnAfter( + 'search_weight', + [ + 'header' => __('Search Weight'), + 'index' => 'search_weight', + 'type' => 'text', + 'align' => 'center', + 'sortable' => true, + 'escape' => true + ], + 'is_searchable' + ); + + // Add "Is filterable in search" column after "Use in layered navigation" column. + $grid->addColumnAfter( + 'is_filterable_in_search', + [ + 'header' => __('Is Filterable in Search'), + 'index' => 'is_filterable_in_search', + 'type' => 'options', + 'options' => ['1' => __('Yes'), '0' => __('No')], + 'align' => 'center', + 'sortable' => true, + 'escape' => true + ], + 'is_filterable' + ); + + // Sort columns by predefined order. + $grid->sortColumnsByOrder(); + } +} diff --git a/src/module-elasticsuite-catalog/Observer/Grid/ProductAttributeGridExportObserver.php b/src/module-elasticsuite-catalog/Observer/Grid/ProductAttributeGridExportObserver.php new file mode 100644 index 000000000..55e894322 --- /dev/null +++ b/src/module-elasticsuite-catalog/Observer/Grid/ProductAttributeGridExportObserver.php @@ -0,0 +1,46 @@ + + * @copyright 2023 Smile + * @license Open Software License ("OSL") v. 3.0 + */ +namespace Smile\ElasticsuiteCatalog\Observer\Grid; + +use Magento\Framework\Event\Observer; +use Magento\Framework\Event\ObserverInterface; + +/** + * This observer class observes the "backend_block_widget_grid_prepare_grid_before" event. + * + * And adds a button for exporting product attributes to a CSV file on the product attribute grid. + * + * @category Smile + * @package Smile\ElasticsuiteCatalog + * @author Vadym Honcharuk + */ +class ProductAttributeGridExportObserver implements ObserverInterface +{ + /** + * Execute. + * + * @param Observer $observer + * @return void + * @throws \Magento\Framework\Exception\LocalizedException + */ + public function execute(Observer $observer) + { + /** @var \Magento\Catalog\Block\Adminhtml\Product\Attribute\Grid $grid */ + $grid = $observer->getGrid(); + + if ($grid instanceof \Magento\Catalog\Block\Adminhtml\Product\Attribute\Grid) { + $grid->addExportType('*/*/exportProductAttributeCsv', __('CSV')); + } + } +} diff --git a/src/module-elasticsuite-catalog/etc/adminhtml/events.xml b/src/module-elasticsuite-catalog/etc/adminhtml/events.xml new file mode 100644 index 000000000..c9443046a --- /dev/null +++ b/src/module-elasticsuite-catalog/etc/adminhtml/events.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + diff --git a/src/module-elasticsuite-catalog/etc/adminhtml/routes.xml b/src/module-elasticsuite-catalog/etc/adminhtml/routes.xml index c3c799094..28ec34268 100644 --- a/src/module-elasticsuite-catalog/etc/adminhtml/routes.xml +++ b/src/module-elasticsuite-catalog/etc/adminhtml/routes.xml @@ -20,5 +20,8 @@ + + + diff --git a/src/module-elasticsuite-catalog/etc/import.xml b/src/module-elasticsuite-catalog/etc/import.xml new file mode 100644 index 000000000..880fd5202 --- /dev/null +++ b/src/module-elasticsuite-catalog/etc/import.xml @@ -0,0 +1,26 @@ + + + + + + diff --git a/src/module-elasticsuite-catalog/etc/module.xml b/src/module-elasticsuite-catalog/etc/module.xml index 452af9a2b..f6eb5e3c3 100644 --- a/src/module-elasticsuite-catalog/etc/module.xml +++ b/src/module-elasticsuite-catalog/etc/module.xml @@ -28,6 +28,7 @@ + diff --git a/src/module-elasticsuite-catalog/view/adminhtml/web/css/source/_module.less b/src/module-elasticsuite-catalog/view/adminhtml/web/css/source/_module.less index e38fe8ae7..a445f5472 100644 --- a/src/module-elasticsuite-catalog/view/adminhtml/web/css/source/_module.less +++ b/src/module-elasticsuite-catalog/view/adminhtml/web/css/source/_module.less @@ -299,3 +299,13 @@ } } } + +#attributeGrid_table { + .col-search_weight { + width: 115px; + } + + .col-is_filterable_in_search { + width: 162px; + } +} From 482ee4ef447e99fc0f1205708ac1a17782b98eae Mon Sep 17 00:00:00 2001 From: Vadym Honcharuk Date: Mon, 15 May 2023 17:25:25 +0300 Subject: [PATCH 2/9] WIP: Feature #2911, PHPCS warnings --- .../Model/Import/ProductAttribute.php | 10 ++++++---- .../Model/Source/Import/Behavior/Custom.php | 14 ++++++++++++++ .../Grid/ProductAttributeGridColumnObserver.php | 6 +++--- .../Grid/ProductAttributeGridExportObserver.php | 2 +- 4 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/module-elasticsuite-catalog/Model/Import/ProductAttribute.php b/src/module-elasticsuite-catalog/Model/Import/ProductAttribute.php index 185ad9e09..ac6ec1877 100644 --- a/src/module-elasticsuite-catalog/Model/Import/ProductAttribute.php +++ b/src/module-elasticsuite-catalog/Model/Import/ProductAttribute.php @@ -44,7 +44,7 @@ class ProductAttribute extends AbstractEntity */ protected $_permanentAttributes = [ 'attribute_code', - 'attribute_label' + 'attribute_label', ]; /** @@ -130,7 +130,7 @@ public function getValidColumnNames(): array * Validate data row. * * @param array $rowData Data. - * @param int $rowNum Row number. + * @param int $rowNum Row number. * * @return bool * @throws LocalizedException @@ -161,6 +161,7 @@ public function validateRow(array $rowData, $rowNum) foreach ($errors as $error) { $this->addRowError($error, $rowNum); } + return false; } @@ -190,8 +191,8 @@ protected function _importData() /** * Update attribute data with new values from CSV. * - * @param Attribute $attribute - * @param array $rowData + * @param Attribute $attribute Attribute. + * @param array $rowData Row Data. * @return bool */ private function updateAttributeData($attribute, $rowData) @@ -226,6 +227,7 @@ private function updateAttributeData($attribute, $rowData) $attribute->getAttributeCode(), $e->getMessage() ); + return false; } } diff --git a/src/module-elasticsuite-catalog/Model/Source/Import/Behavior/Custom.php b/src/module-elasticsuite-catalog/Model/Source/Import/Behavior/Custom.php index b1c87d8e2..f3f7e658c 100644 --- a/src/module-elasticsuite-catalog/Model/Source/Import/Behavior/Custom.php +++ b/src/module-elasticsuite-catalog/Model/Source/Import/Behavior/Custom.php @@ -3,6 +3,18 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +/** + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Smile ElasticSuite to newer + * versions in the future. + * + * @category Smile + * @package Smile\ElasticsuiteCatalog + * @author Vadym Honcharuk + * @copyright 2023 Smile + * @license Open Software License ("OSL") v. 3.0 + */ namespace Smile\ElasticsuiteCatalog\Model\Source\Import\Behavior; use Magento\ImportExport\Model\Import; @@ -11,6 +23,8 @@ /** * Custom import behavior source model used for defining the behavior during the product attributes import. * + * @SuppressWarnings(PHPMD) + * * @api * @since 100.0.2 */ diff --git a/src/module-elasticsuite-catalog/Observer/Grid/ProductAttributeGridColumnObserver.php b/src/module-elasticsuite-catalog/Observer/Grid/ProductAttributeGridColumnObserver.php index 15f202771..0a1e88b80 100644 --- a/src/module-elasticsuite-catalog/Observer/Grid/ProductAttributeGridColumnObserver.php +++ b/src/module-elasticsuite-catalog/Observer/Grid/ProductAttributeGridColumnObserver.php @@ -30,7 +30,7 @@ class ProductAttributeGridColumnObserver implements ObserverInterface /** * Execute. * - * @param Observer $observer + * @param Observer $observer Observer. * @return void */ public function execute(Observer $observer) @@ -47,7 +47,7 @@ public function execute(Observer $observer) 'type' => 'text', 'align' => 'center', 'sortable' => true, - 'escape' => true + 'escape' => true, ], 'is_searchable' ); @@ -62,7 +62,7 @@ public function execute(Observer $observer) 'options' => ['1' => __('Yes'), '0' => __('No')], 'align' => 'center', 'sortable' => true, - 'escape' => true + 'escape' => true, ], 'is_filterable' ); diff --git a/src/module-elasticsuite-catalog/Observer/Grid/ProductAttributeGridExportObserver.php b/src/module-elasticsuite-catalog/Observer/Grid/ProductAttributeGridExportObserver.php index 55e894322..80059e90f 100644 --- a/src/module-elasticsuite-catalog/Observer/Grid/ProductAttributeGridExportObserver.php +++ b/src/module-elasticsuite-catalog/Observer/Grid/ProductAttributeGridExportObserver.php @@ -30,7 +30,7 @@ class ProductAttributeGridExportObserver implements ObserverInterface /** * Execute. * - * @param Observer $observer + * @param Observer $observer Observer. * @return void * @throws \Magento\Framework\Exception\LocalizedException */ From b791457083430cd1d5cb0428c1790e518dd9aa56 Mon Sep 17 00:00:00 2001 From: Vadym Honcharuk Date: Mon, 15 May 2023 17:35:11 +0300 Subject: [PATCH 3/9] WIP: Feature #2911, PHPCS warnings --- .../Model/Source/Import/Behavior/Custom.php | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/module-elasticsuite-catalog/Model/Source/Import/Behavior/Custom.php b/src/module-elasticsuite-catalog/Model/Source/Import/Behavior/Custom.php index f3f7e658c..3442df444 100644 --- a/src/module-elasticsuite-catalog/Model/Source/Import/Behavior/Custom.php +++ b/src/module-elasticsuite-catalog/Model/Source/Import/Behavior/Custom.php @@ -25,23 +25,31 @@ * * @SuppressWarnings(PHPMD) * + * @category Smile + * @package Smile\ElasticsuiteCatalog + * @author Vadym Honcharuk + * * @api * @since 100.0.2 */ class Custom extends AbstractBehavior { /** - * @inheritdoc + * Get array of possible values. + * + * @return array */ public function toArray() { return [ - Import::BEHAVIOR_APPEND => __('Update') + Import::BEHAVIOR_APPEND => __('Update'), ]; } /** - * @inheritdoc + * Get current behaviour group code. + * + * @return string */ public function getCode() { From 64f7548a7d80d56ca289085fb41dca276d144a4e Mon Sep 17 00:00:00 2001 From: Vadym Honcharuk Date: Mon, 15 May 2023 17:44:35 +0300 Subject: [PATCH 4/9] WIP: Feature #2911, PHPCS warnings --- .../Model/Source/Import/Behavior/Custom.php | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/module-elasticsuite-catalog/Model/Source/Import/Behavior/Custom.php b/src/module-elasticsuite-catalog/Model/Source/Import/Behavior/Custom.php index 3442df444..26b65da2e 100644 --- a/src/module-elasticsuite-catalog/Model/Source/Import/Behavior/Custom.php +++ b/src/module-elasticsuite-catalog/Model/Source/Import/Behavior/Custom.php @@ -1,8 +1,4 @@ - * - * @api - * @since 100.0.2 */ class Custom extends AbstractBehavior { From bfcc445435bb37ee68fa4c5f422a1df8492e4ab3 Mon Sep 17 00:00:00 2001 From: Vadym Honcharuk Date: Mon, 15 May 2023 17:52:41 +0300 Subject: [PATCH 5/9] WIP: Feature #2911, PHPMD warnings --- .../Model/Import/ProductAttribute.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/module-elasticsuite-catalog/Model/Import/ProductAttribute.php b/src/module-elasticsuite-catalog/Model/Import/ProductAttribute.php index ac6ec1877..46b553e60 100644 --- a/src/module-elasticsuite-catalog/Model/Import/ProductAttribute.php +++ b/src/module-elasticsuite-catalog/Model/Import/ProductAttribute.php @@ -26,6 +26,10 @@ /** * Product attribute import model. * + * @SuppressWarnings(PHPMD.CamelCaseMethodName) + * @SuppressWarnings(PHPMD.CamelCasePropertyName) + * @SuppressWarnings(PHPMD.ElseExpression) + * * @category Smile * @package Smile\ElasticsuiteCatalog * @author Vadym Honcharuk From 78fd127bd5e0008e71fdf44636c657e721e70c19 Mon Sep 17 00:00:00 2001 From: Vadym Honcharuk Date: Mon, 15 May 2023 18:57:12 +0300 Subject: [PATCH 6/9] WIP: Feature #2911, add import statistic --- .../Model/Import/ProductAttribute.php | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/module-elasticsuite-catalog/Model/Import/ProductAttribute.php b/src/module-elasticsuite-catalog/Model/Import/ProductAttribute.php index 46b553e60..06ac37393 100644 --- a/src/module-elasticsuite-catalog/Model/Import/ProductAttribute.php +++ b/src/module-elasticsuite-catalog/Model/Import/ProductAttribute.php @@ -79,6 +79,20 @@ class ProductAttribute extends AbstractEntity 'include_zero_false_values', ]; + /** + * Count if updated items. + * + * @var int + */ + protected $countItemsUpdated = 0; + + /** + * Need to log in import history. + * + * @var bool + */ + protected $logInHistory = true; + /** * @var Config */ @@ -185,7 +199,10 @@ protected function _importData() foreach ($bunch as $rowData) { $attributeCode = isset($rowData['attribute_code']) ? trim($rowData['attribute_code']) : ''; $attribute = $this->_eavConfig->getAttribute(self::ENTITY_TYPE_CODE, $attributeCode); - $this->updateAttributeData($attribute, $rowData); + $result = $this->updateAttributeData($attribute, $rowData); + if ($result) { + $this->countItemsUpdated++; + } } } From 78e18491057262702671ad7f5c42757e218c6381 Mon Sep 17 00:00:00 2001 From: Vadym Honcharuk Date: Mon, 15 May 2023 19:04:00 +0300 Subject: [PATCH 7/9] WIP: Feature #2911, PHPCS warnings --- .../Model/Import/ProductAttribute.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/module-elasticsuite-catalog/Model/Import/ProductAttribute.php b/src/module-elasticsuite-catalog/Model/Import/ProductAttribute.php index 06ac37393..c8358b16e 100644 --- a/src/module-elasticsuite-catalog/Model/Import/ProductAttribute.php +++ b/src/module-elasticsuite-catalog/Model/Import/ProductAttribute.php @@ -82,14 +82,14 @@ class ProductAttribute extends AbstractEntity /** * Count if updated items. * - * @var int + * @var integer */ protected $countItemsUpdated = 0; /** * Need to log in import history. * - * @var bool + * @var boolean */ protected $logInHistory = true; From eb1515b7961066285792d9344ee67445fa58c9d8 Mon Sep 17 00:00:00 2001 From: Vadym Honcharuk Date: Tue, 16 May 2023 18:23:53 +0300 Subject: [PATCH 8/9] Feature #2911, add import sample file, refactoring --- .../Product/Attribute/ExportProductAttributeCsv.php | 2 +- .../Files/Sample/elasticsuite_product_attribute.csv | 3 +++ .../Model/Import/ProductAttribute.php | 6 +++--- .../Model/Source/Import/Behavior/Custom.php | 2 +- src/module-elasticsuite-catalog/etc/di.xml | 8 ++++++++ src/module-elasticsuite-catalog/etc/import.xml | 4 ++-- 6 files changed, 18 insertions(+), 7 deletions(-) create mode 100644 src/module-elasticsuite-catalog/Files/Sample/elasticsuite_product_attribute.csv diff --git a/src/module-elasticsuite-catalog/Controller/Adminhtml/Product/Attribute/ExportProductAttributeCsv.php b/src/module-elasticsuite-catalog/Controller/Adminhtml/Product/Attribute/ExportProductAttributeCsv.php index 659555aa9..07309bcdf 100644 --- a/src/module-elasticsuite-catalog/Controller/Adminhtml/Product/Attribute/ExportProductAttributeCsv.php +++ b/src/module-elasticsuite-catalog/Controller/Adminhtml/Product/Attribute/ExportProductAttributeCsv.php @@ -139,7 +139,7 @@ public function execute() // Prepare and send the CSV file to the browser. $date = date('Ymd_His'); - $fileName = 'product_attributes-' . $date . '.csv'; + $fileName = 'elasticsuite_product_attribute-' . $date . '.csv'; $directory = $this->filesystem->getDirectoryWrite(DirectoryList::VAR_DIR); $stream = $directory->openFile($fileName, 'w+'); foreach ($content as $line) { diff --git a/src/module-elasticsuite-catalog/Files/Sample/elasticsuite_product_attribute.csv b/src/module-elasticsuite-catalog/Files/Sample/elasticsuite_product_attribute.csv new file mode 100644 index 000000000..e1f80b48a --- /dev/null +++ b/src/module-elasticsuite-catalog/Files/Sample/elasticsuite_product_attribute.csv @@ -0,0 +1,3 @@ +attribute_code,attribute_label,is_searchable,search_weight,is_used_in_spellcheck,is_displayed_in_autocomplete,is_filterable,is_filterable_in_search,is_used_for_promo_rules,used_for_sort_by,is_display_rel_nofollow,facet_max_size,facet_sort_order,facet_min_coverage_rate,facet_boolean_logic,position,default_analyzer,norms_disabled,is_spannable,include_zero_false_values +activity,Activity,0,1,1,0,1,0,1,0,0,10,_count,90,1,0,standard,0,0,0 +allow_open_amount,Open Amount,0,1,1,0,0,0,0,0,0,10,_count,90,0,0,standard,0,0,0 diff --git a/src/module-elasticsuite-catalog/Model/Import/ProductAttribute.php b/src/module-elasticsuite-catalog/Model/Import/ProductAttribute.php index c8358b16e..678692734 100644 --- a/src/module-elasticsuite-catalog/Model/Import/ProductAttribute.php +++ b/src/module-elasticsuite-catalog/Model/Import/ProductAttribute.php @@ -39,7 +39,7 @@ class ProductAttribute extends AbstractEntity /** * Entity type code. */ - const ENTITY_TYPE_CODE = 'catalog_product'; + const ENTITY_TYPE_CODE = 'elasticsuite_product_attribute'; /** * Permanent entity columns. @@ -162,7 +162,7 @@ public function validateRow(array $rowData, $rowNum) if (!$attributeCode) { $errors[] = __('Attribute code is required.'); } else { - $attribute = $this->_eavConfig->getAttribute(self::ENTITY_TYPE_CODE, $attributeCode); + $attribute = $this->_eavConfig->getAttribute('catalog_product', $attributeCode); if (!$attribute->getId()) { $errors[] = __('Attribute with code %1 does not exist.', $attributeCode); } @@ -198,7 +198,7 @@ protected function _importData() while ($bunch = $this->_dataSourceModel->getNextBunch()) { foreach ($bunch as $rowData) { $attributeCode = isset($rowData['attribute_code']) ? trim($rowData['attribute_code']) : ''; - $attribute = $this->_eavConfig->getAttribute(self::ENTITY_TYPE_CODE, $attributeCode); + $attribute = $this->_eavConfig->getAttribute('catalog_product', $attributeCode); $result = $this->updateAttributeData($attribute, $rowData); if ($result) { $this->countItemsUpdated++; diff --git a/src/module-elasticsuite-catalog/Model/Source/Import/Behavior/Custom.php b/src/module-elasticsuite-catalog/Model/Source/Import/Behavior/Custom.php index 26b65da2e..f25c6c930 100644 --- a/src/module-elasticsuite-catalog/Model/Source/Import/Behavior/Custom.php +++ b/src/module-elasticsuite-catalog/Model/Source/Import/Behavior/Custom.php @@ -44,6 +44,6 @@ public function toArray() */ public function getCode() { - return 'custom'; + return 'elasticsuite_product_attribute_import_custom_behavior'; } } diff --git a/src/module-elasticsuite-catalog/etc/di.xml b/src/module-elasticsuite-catalog/etc/di.xml index 815774e8e..1b544d855 100644 --- a/src/module-elasticsuite-catalog/etc/di.xml +++ b/src/module-elasticsuite-catalog/etc/di.xml @@ -410,4 +410,12 @@ + + + + + Smile_ElasticsuiteCatalog + + + diff --git a/src/module-elasticsuite-catalog/etc/import.xml b/src/module-elasticsuite-catalog/etc/import.xml index 880fd5202..a46396390 100644 --- a/src/module-elasticsuite-catalog/etc/import.xml +++ b/src/module-elasticsuite-catalog/etc/import.xml @@ -16,11 +16,11 @@ --> - - + From 8b13743ffd0f4eb4f1871b38957c0670bbf050ea Mon Sep 17 00:00:00 2001 From: Vincent ENJALBERT Date: Fri, 19 May 2023 17:19:29 +0200 Subject: [PATCH 9/9] Fix filter rendering --- .../Block/Navigation/FilterRenderer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/module-elasticsuite-catalog/Block/Navigation/FilterRenderer.php b/src/module-elasticsuite-catalog/Block/Navigation/FilterRenderer.php index d8d323a16..02ae9e22a 100644 --- a/src/module-elasticsuite-catalog/Block/Navigation/FilterRenderer.php +++ b/src/module-elasticsuite-catalog/Block/Navigation/FilterRenderer.php @@ -47,7 +47,7 @@ public function _toHtml() $html = ''; foreach ($this->getChildNames() as $childName) { - if ($html === '') { + if (trim((string) $html) === '') { $renderer = $this->getChildBlock($childName); $html = $renderer->render($this->getFilter()); }