Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 10 additions & 8 deletions Model/AutoRelatedProductAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ public function __construct(
}
}

public function execute()
public function execute(array $ids = [])
{
$productIdsToCleanCache = [];
$oldProductToRuleData = [];
Expand All @@ -144,6 +144,10 @@ public function execute()
$ruleCollection = $this->ruleCollectionFactory->create()
->addFieldToFilter('status', 1);

if (!empty($ids) && is_array($ids)) {
$ruleCollection->addFieldToFilter('id', ['in' => $ids]);
}

if ($ruleCollection) {
$oldProductToRuleCollection = $this->connection->fetchAll($this->connection->select()->from($tableNameArpIndex));

Expand Down Expand Up @@ -202,16 +206,10 @@ public function execute()

/**
* @param $rule
* @param null $params
* @return array
* @throws LocalizedException
*/
/**
* @param $rule
* @param null $params
* @return array
*/
public function getListProductIds($rule)
public function getListProductIds($rule, $productId = null)
{
$this->productIds = [];
$conditions = $rule->getConditions();
Expand Down Expand Up @@ -246,6 +244,10 @@ public function getListProductIds($rule)
$productCollection->setStoreId($storeId);
}

if ($productId) {
$productCollection->addFieldToFilter('entity_id', $productId);
}

$conditions = $rule->getConditions();

$conditions->collectValidatedAttributes($productCollection);
Expand Down
189 changes: 189 additions & 0 deletions Model/Indexer/Rule.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
<?php
/**
* Copyright © Magefan ([email protected]). All rights reserved.
* Please visit Magefan.com for license details (https://magefan.com/end-user-license-agreement).
*/

declare(strict_types=1);

namespace Magefan\AutoRelatedProduct\Model\Indexer;

use Magefan\AutoRelatedProduct\Api\RelatedCollectionInterface;
use Magefan\AutoRelatedProduct\Model\AutoRelatedProductAction;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\CatalogRule\Model\RuleFactory;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\App\ResourceConnection;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\Indexer\CacheContext;
use Magento\Framework\Indexer\IndexerRegistry;
use Magento\Framework\Indexer\IndexMutexInterface;

class Rule implements \Magento\Framework\Indexer\ActionInterface, \Magento\Framework\Mview\ActionInterface
{
const INDEXER_ID = 'magefan_autorelatedproduct_indexer';

/**
* @var IndexerRegistry
*/
protected $indexerRegistry;

/**
* @var IndexMutexInterface
*/
private $indexMutex;

private $autoRelatedProductAction;

/**
* @var CacheContext
* @since 100.0.11
*/
protected $cacheContext;

/**
* @var RelatedCollectionInterface
*/
private $relatedCollection;

/**
* @var RuleFactory
*/
private $ruleFactory;

/**
* @var ProductRepositoryInterface
*/
private $productRepository;

/**
* @var ResourceConnection
*/
private $resourceConnection;

/**
* @param IndexerRegistry $indexerRegistry
* @param AutoRelatedProductAction $autoRelatedProductAction
* @param RelatedCollectionInterface $relatedCollection
* @param RuleFactory $ruleFactory
* @param ProductRepositoryInterface $productRepository
* @param ResourceConnection $resourceConnection
* @param IndexMutexInterface|null $indexMutex
*/
public function __construct(
IndexerRegistry $indexerRegistry,
AutoRelatedProductAction $autoRelatedProductAction,
RelatedCollectionInterface $relatedCollection,
RuleFactory $ruleFactory,
ProductRepositoryInterface $productRepository,
ResourceConnection $resourceConnection,
?IndexMutexInterface $indexMutex = null
)
{
$this->indexerRegistry = $indexerRegistry;
$this->autoRelatedProductAction = $autoRelatedProductAction;
$this->relatedCollection = $relatedCollection;
$this->ruleFactory = $ruleFactory;
$this->productRepository = $productRepository;
$this->resourceConnection = $resourceConnection;
$this->indexMutex = $indexMutex ?? ObjectManager::getInstance()->get(IndexMutexInterface::class);
}

/**
* @param $ids
* @return void
* @throws NoSuchEntityException
*/
public function execute($ids)
{
$this->executeAction($ids);
}

/**
* @return void
*/
public function executeFull()
{
$this->executeAction([]);
}

/**
* @param array $ids
* @return void
* @throws NoSuchEntityException
*/
public function executeList(array $ids)
{
$this->executeAction($ids);
}

/**
* @param $id
* @return void
* @throws NoSuchEntityException
*/
public function executeRow($id)
{
$this->getIndexRuleByProduct($id);
}

/**
* @param $ids
* @return $this
*/
protected function executeAction($ids)
{
$ids = array_unique($ids);
$indexer = $this->indexerRegistry->get(static::INDEXER_ID);

if ($indexer->isScheduled()) {
$this->indexMutex->execute(
static::INDEXER_ID,
function () use ($ids) {
$this->autoRelatedProductAction->execute($ids);
}
);
} else {
$this->autoRelatedProductAction->execute($ids);
}

return $this;
}

/**
* @param $id
* @return void
* @throws \Magento\Framework\Exception\LocalizedException
*/
public function getIndexRuleByProduct($id)
{
$autoRelatedProductRules = $this->relatedCollection->addFieldToFilter('status', 1);

foreach ($autoRelatedProductRules as $autoRelatedProductRule) {

$rule = $this->ruleFactory->create();
$rule->setData('conditions_serialized', $autoRelatedProductRule->getConditions());
$rule->setData('store_ids', $autoRelatedProductRule->getStoreIds());
$relatedProductId = $this->autoRelatedProductAction->getListProductIds($rule, $id);

$connection = $this->resourceConnection->getConnection();
$tableNameArpIndex = $this->resourceConnection->getTableName('magefan_autorp_index');

$oldIndexRule = $connection->select()->from($tableNameArpIndex)->where(
'rule_id = ?' , $autoRelatedProductRule->getId());
$oldRelatedIds = explode(',', $connection->fetchRow($oldIndexRule)['related_ids']);

if (in_array($relatedProductId[0],$oldRelatedIds)){
continue;
}

$relatedIds = array_merge($oldRelatedIds,$relatedProductId);
$relatedIds = array_unique($relatedIds);
$connection->update(
$tableNameArpIndex,
['related_ids' => implode(',', $relatedIds)],
['rule_id = ?' => $autoRelatedProductRule->getId()]
);
}
}
}
39 changes: 39 additions & 0 deletions Observer/Product/SaveAfter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php
/**
* Copyright © Magefan ([email protected]). All rights reserved.
* Please visit Magefan.com for license details (https://magefan.com/end-user-license-agreement).
*/

declare(strict_types=1);

namespace Magefan\AutoRelatedProduct\Observer\Product;

use Magento\Framework\Event\Observer;
use Magefan\AutoRelatedProduct\Model\Indexer\Rule;
class SaveAfter implements \Magento\Framework\Event\ObserverInterface
{
/**
* @var \Magefan\AutoRelatedProduct\Model\Indexer\Rule
*/
private $ruleIndexer;

/**
* @param \Magefan\AutoRelatedProduct\Model\Indexer\Rule $ruleIndexer
*/
public function __construct(
Rule $ruleIndexer
)
{
$this->ruleIndexer = $ruleIndexer;
}

/**
* @param Observer $observer
* @return void
*/
public function execute(Observer $observer)
{
$productId = $observer->getEvent()->getProduct()->getId();
$this->ruleIndexer->executeRow($productId);
}
}
12 changes: 12 additions & 0 deletions etc/adminhtml/events.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" ?>
<!--
/**
* Copyright © Magefan ([email protected]). All rights reserved.
* Please visit Magefan.com for license details (https://magefan.com/end-user-license-agreement).
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
<event name="catalog_product_save_after">
<observer instance="Magefan\AutoRelatedProduct\Observer\Product\SaveAfter" name="magefan_autorelatedproduct_observer_catalog_product_save_after"/>
</event>
</config>
7 changes: 7 additions & 0 deletions etc/indexer.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Indexer/etc/indexer.xsd">
<indexer id="magefan_autorelatedproduct_indexer" view_id="magefan_autorelatedproduct_indexer" class="Magefan\AutoRelatedProduct\Model\Indexer\Rule" shared_index="catalogrule">
<title translate="true">AutoRelatedProduct Indexer</title>
<description translate="true">Magefan AutoRelatedProductRule/Product indexer</description>
</indexer>
</config>
8 changes: 8 additions & 0 deletions etc/mview.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Mview/etc/mview.xsd">
<view id="magefan_autorelatedproduct_indexer" class="Magefan\AutoRelatedProduct\Model\Indexer\Rule" group="indexer">
<subscriptions>
<table name="magefan_autorp_rule" entity_column="id" />
</subscriptions>
</view>
</config>