How to validate product due to Custom Condition Rules in Magento 2

Why do you need to read this blog?

Are you struggling to find a precisely and super-easy way to validate products by custom condition rule data?

Checkout my blog. It properly is your answer.

In Magento 2, we can have Custom Condition Rules like this:

custom condition rules

You can see ‘condition tree’ like these in Catalog Price Rule or Cart Price Rules or Widget.

According to the above conditions we have this data:

As array form:

condition rule's data

Or as string form:


What is the right way?

After seeing this, you know it would be a pain to use these data to validate products without Magento method support right?

We can solve this by converting array form to object to give you the ability to work with them.

protected function getWidgetRule($conditions)
    $rule = $this->_ruleFactory->create();
    if(is_array($conditions)) $rule->loadPost($conditions);
    return $rule;

In the function above, parameter $conditions is condition data in array form and the output is an \Magento\CatalogWidget\Model\Rule object containing condition data.

public function getValidatedProduct($rule){
    $validatedProducts = array();
    $conditionData = @unserialize($rule->getData('display_place'));
    $widgetRule = $this->getWidgetRule($conditionData);

    /** @var \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $this->productCollectionFactory
    $collection = $this->productCollectionFactory->create();

    $conditions = $widgetRule->getConditions();

    /**  @var \Magento\Rule\Model\Condition\Sql\Builder $sqlBuilder: $this->sqlBuilder
    $this->sqlBuilder->attachConditionToCollection($collection, $conditions);

        foreach ($collection as $product)
    return $products;

As you can see, I converted condition data from array form to object $widgetRule using getWidgetRule method.

And use attachConditionToCollection method of \Magento\Rule\Model\Condition\Sql\Builder to validate products.

At the loop, parameter $collection had already contained all the validated products and I used the loop to return an array of validated product’ ids.

Very simple, isn’t it?