4

how to get matching products based on rule conditions i need to filter product grid according to rule condition in my custom module I have used it as a filter

enter image description here

Array
(
    [conditions] => Array
        (
            [1] => Array
                (
                    [type] => Magento\CatalogRule\Model\Rule\Condition\Combine
                    [aggregator] => all
                    [value] => 1
                    [new_child] => 
                )

            [1--1] => Array
                (
                    [type] => Magento\CatalogRule\Model\Rule\Condition\Product
                    [attribute] => attribute_set_id
                    [operator] => ==
                    [value] => 15
                )

            [1--2] => Array
                (
                    [type] => Magento\CatalogRule\Model\Rule\Condition\Product
                    [attribute] => price
                    [operator] => <
                    [value] => 2000
                )

        )

)

I have this array of rule conditions and I need products based on conditions

8

finally I found the solution.

/*Controller code */

    $modelRule = $this->_objectManager->create('NameSpace\ModuleName\Model\Rule');
                $data = $this->prepareData($data);
                $modelRule->loadPost($data);
    $productIds = $modelRule->getListProductIds();


    protected function prepareData($data)
        {
            if (isset($data['rule']['conditions'])) {
                $data['conditions'] = $data['rule']['conditions'];
            }
            unset($data['rule']);
            return $data;
        }

NameSpace\ModuleName\Model\Rule.php

    namespace NameSpace\ModuleName\Model;

    class Rule extends \Magento\CatalogRule\Model\Rule {
        /**
         * Prefix of model events names
         *
         * @var string
         */
        protected $_eventPrefix = 'catalogrule_rule';

        /**
         * Parameter name in event
         *
         * In observe method you can use $observer->getEvent()->getRule() in this case
         *
         * @var string
         */
        protected $_eventObject = 'rule';

        /**
         * Store matched product Ids
         *
         * @var array
         */
        protected $_productIds;

        /**
         * Limitation for products collection
         *
         * @var int|array|null
         */
        protected $_productsFilter = null;

        /**
         * Store current date at "Y-m-d H:i:s" format
         *
         * @var string
         */
        protected $_now;

        /**
         * Cached data of prices calculated by price rules
         *
         * @var array
         */
        protected static $_priceRulesData = [];

        /**
         * Catalog rule data
         *
         * @var \Magento\CatalogRule\Helper\Data
         */
        protected $_catalogRuleData;

        /**
         * @var \Magento\Framework\App\Cache\TypeListInterface
         */
        protected $_cacheTypesList;

        /**
         * @var array
         */
        protected $_relatedCacheTypes;

        /**
         * @var \Magento\Framework\Stdlib\DateTime
         */
        protected $dateTime;

        /**
         * @var \Magento\Framework\Model\ResourceModel\Iterator
         */
        protected $_resourceIterator;

        /**
         * @var \Magento\Customer\Model\Session
         */
        protected $_customerSession;

        /**
         * @var \Magento\CatalogRule\Model\Rule\Condition\CombineFactory
         */
        protected $_combineFactory;

        /**
         * @var \Magento\CatalogRule\Model\Rule\Action\CollectionFactory
         */
        protected $_actionCollectionFactory;

        /**
         * @var \Magento\Catalog\Model\ProductFactory
         */
        protected $_productFactory;

        /**
         * @var \Magento\Store\Model\StoreManagerInterface
         */
        protected $_storeManager;

        /**
         * @var \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory
         */
        protected $_productCollectionFactory;

        /**
         * @var \Magento\CatalogRule\Model\Indexer\Rule\RuleProductProcessor;
         */
        protected $_ruleProductProcessor;

        /**
         * @var Data\Condition\Converter
         */
        protected $ruleConditionConverter;

        /**
         * Rule constructor.
         * @param \Magento\Framework\Model\Context $context
         * @param \Magento\Framework\Registry $registry
         * @param \Magento\Framework\Data\FormFactory $formFactory
         * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
         * @param \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory
         * @param \Magento\Store\Model\StoreManagerInterface $storeManager
         * @param Rule\Condition\CombineFactory $combineFactory
         * @param Rule\Action\CollectionFactory $actionCollectionFactory
         * @param \Magento\Catalog\Model\ProductFactory $productFactory
         * @param \Magento\Framework\Model\ResourceModel\Iterator $resourceIterator
         * @param \Magento\Customer\Model\Session $customerSession
         * @param \Magento\CatalogRule\Helper\Data $catalogRuleData
         * @param \Magento\Framework\App\Cache\TypeListInterface $cacheTypesList
         * @param \Magento\Framework\Stdlib\DateTime $dateTime
         * @param Indexer\Rule\RuleProductProcessor $ruleProductProcessor
         * @param \Magento\Framework\Model\ResourceModel\AbstractResource|null $resource
         * @param \Magento\Framework\Data\Collection\AbstractDb|null $resourceCollection
         * @param array $relatedCacheTypes
         * @param array $data
         *
         * @SuppressWarnings(PHPMD.ExcessiveParameterList)
         */

        public function __construct(
        \Magento\Framework\Model\Context $context,
        \Magento\Framework\Registry $registry,
        \Magento\Framework\Data\FormFactory $formFactory,
        \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
        \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory,
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        \Magento\CatalogRule\Model\Rule\Condition\CombineFactory $combineFactory,
        \Magento\CatalogRule\Model\Rule\Action\CollectionFactory $actionCollectionFactory,
        \Magento\Catalog\Model\ProductFactory $productFactory,
        \Magento\Framework\Model\ResourceModel\Iterator $resourceIterator,
        \Magento\Customer\Model\Session $customerSession,
        \Magento\CatalogRule\Helper\Data $catalogRuleData,
        \Magento\Framework\App\Cache\TypeListInterface $cacheTypesList,
        \Magento\Framework\Stdlib\DateTime $dateTime,
        \Magento\CatalogRule\Model\Indexer\Rule\RuleProductProcessor $ruleProductProcessor,
        \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
        \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
        array $relatedCacheTypes = [],
        array $data = []
        ) {

            parent::__construct(
                    $context,
                    $registry,
                    $formFactory,
                    $localeDate,
                    $productCollectionFactory,
                    $storeManager,
                    $combineFactory,
                    $actionCollectionFactory,
                    $productFactory,
                    $resourceIterator,
                    $customerSession,
                    $catalogRuleData,
                    $cacheTypesList,
                    $dateTime,
                    $ruleProductProcessor,
                    $resource,
                    $resourceCollection,
                    $relatedCacheTypes,
                    $data
            );
        }
        /**
         * Init resource model and id field
         *
         * @return void
         */
        protected function _construct()
        {
            parent::_construct();
            $this->_init('Magento\CatalogRule\Model\ResourceModel\Rule');
            $this->setIdFieldName('rule_id');
        }
        /**
         * Getter for rule conditions collection
         *
         * @return \Magento\Rule\Model\Condition\Combine
         */
        public function getConditionsInstance()
        {
            return $this->_combineFactory->create();
        }

        /**
         * Getter for rule actions collection
         *
         * @return \Magento\CatalogRule\Model\Rule\Action\Collection
         */
        public function getActionsInstance()
        {
            return $this->_actionCollectionFactory->create();
        }

        public function toArray(array $arrAttributes = array()) {
        return parent::toArray($arrAttributes);
        }

        public function getListProductIds()
        {    
         $productCollection = \Magento\Framework\App\ObjectManager::getInstance()->create(
             '\Magento\Catalog\Model\ResourceModel\Product\Collection'
         );
         $productFactory = \Magento\Framework\App\ObjectManager::getInstance()->create(
             '\Magento\Catalog\Model\ProductFactory'
         );
         $this->_productIds = [];
         $this->setCollectedAttributes([]);
         $this->getConditions()->collectValidatedAttributes($productCollection);
         \Magento\Framework\App\ObjectManager::getInstance()->create(
             '\Magento\Framework\Model\ResourceModel\Iterator'
         )->walk(
             $productCollection->getSelect(),
             [[$this, 'callbackValidateProduct']],
             [
                 'attributes' => $this->getCollectedAttributes(),
                 'product' => $productFactory->create()
             ]
         );
        return $this->_productIds;
        }
        /**
        * Callback function for product matching
        *
        * @param array $args
        * @return void
        */
        public function callbackValidateProduct($args)
        {
         $product = clone $args['product'];
         $product->setData($args['row']);
         $websites = $this->_getWebsitesMap();
         foreach ($websites as $websiteId => $defaultStoreId) {
             $product->setStoreId($defaultStoreId);
             if ($this->getConditions()->validate($product)) {
                 $this->_productIds[] = $product->getId();
             }
         }
        }
        /**
        * Prepare website map
        *
        * @return array
        */
        protected function _getWebsitesMap()
        {
         $map = [];
         $websites = \Magento\Framework\App\ObjectManager::getInstance()->create(
             '\Magento\Store\Model\StoreManagerInterface'
         )->getWebsites();
         foreach ($websites as $website) {
             // Continue if website has no store to be able to create catalog rule for website without store
             if ($website->getDefaultStore() === null) {
                 continue;
             }
             $map[$website->getId()] = $website->getDefaultStore()->getId();
         }
         return $map;
        }

    }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.