magento2-connector-community
magento2-connector-community copied to clipboard
Categories matched by rule are not handled at all
Environment and configuration
- 100.4.16 - but haven't found fixes or handling for given issue in changelog
Steps to reproduce
- Configure categories matched rule (by attribute for example)
- Have corresponding categories in akeneo (empty)
- Import products
- Check if products are correctly assigned to categories
Expected result
- Products are assigned according to rules
Actual result
- Categories that matches products by rules are wiped out or products count is lower (if we exclude some families from import)
Issue was solved by out team with following plugin:
use Akeneo\Connector\Job\Product;
use Exception;
use Magento\Catalog\Model\Category;
use Magento\Catalog\Model\ResourceModel\Category as CategoryResource;
use Magento\Catalog\Model\ResourceModel\Category\CollectionFactory as CategoryCollectionFactory;
use Magento\VisualMerchandiser\Model\Category\Builder;
use Magento\VisualMerchandiser\Model\ResourceModel\Rules\Collection as RulesCollection;
use Magento\VisualMerchandiser\Model\ResourceModel\Rules\CollectionFactory as RulesCollectionFactory;
class RebuildDynamicCategories
{
private CategoryResource $categoryResource;
private CategoryCollectionFactory $categoryCollectionFactory;
private Builder $builder;
private RulesCollectionFactory $rulesCollectionFactory;
public function __construct(
CategoryResource $categoryResource,
CategoryCollectionFactory $categoryCollectionFactory,
Builder $builder,
RulesCollectionFactory $rulesCollectionFactory
) {
$this->categoryResource = $categoryResource;
$this->categoryCollectionFactory = $categoryCollectionFactory;
$this->builder = $builder;
$this->rulesCollectionFactory = $rulesCollectionFactory;
}
public function afterSetCategories(Product $subject, $result)
{
$this->rebuildDynamicCategories($subject);
return $result;
}
private function rebuildDynamicCategories(Product $productImport): void
{
$rulesCollection = $this->rulesCollectionFactory->create();
/** @var $rulesCollection RulesCollection */
$rulesCollection->addFieldToFilter('is_active', ['eq' => 1]);
$categoriesIds = $rulesCollection->getColumnValues('category_id');
$categoryCollection = $this->categoryCollectionFactory->create();
$categoryCollection->addAttributeToSelect('*')
->addFieldToFilter($this->categoryResource->getEntityIdField(), ['in' => $categoriesIds]);
foreach ($categoryCollection as $category) {
$this->builder->rebuildCategory($category);
$this->saveRebuiltCategory($productImport, $category);
}
}
private function saveRebuiltCategory(Product $productImport, Category $category): void
{
try {
$this->categoryResource->save($category);
} catch (Exception $exception) {
$productImport->setAdditionalMessage(
__(
'Dynamic category %1 (ID: %2) couldn\'t be rebuilt correctly',
$category->getName(),
$category->getId()
)
);
}
}
}
@bartoszkubicki we have the same issue. Could you team make a pull request so this could hopefully end up in a future release?
@magentix I can see a proposal of my fix for the given issue has been added. Unfortunately, I can see you have removed two dependencies from the constructor method and you are pulling them from the object manager. This is a clear antipattern and I have no idea why you did that. Please fix it or remove my name from that class. I don't want to be linked with such poor-quality code.
@bartoszkubicki
We must be compatible with all Magento versions, the use of VisualMerchandiser classes in the constructor breaks all Magento OpenSource / OpenMage and Adobe Commerce without the module.
Note that the plugin was removed in 104.0.7 (the product sort order is not persisted with this technique).
https://github.com/akeneo/magento2-connector-community/commit/34f65b7aecb2b22c66bbc6c67d5a02542c7ccf3e