I've created my own custom rules which I'll be using later on for applying discounts on Catalog. It's extension of the catalog price rules. What I've done is actually replicated the functionality for creating custom rules from here.
However, I've override the class \Magento\Rule\Model\Condition\Combine
by my own Combine
Class for adding unique custom options to the rules, here is the code for that:
<?php
namespace RLTSquare\Rules\Model\Rule\Condition;
class Combine extends \Magento\Rule\Model\Condition\Combine
{
/**
* @var \RLTSquare\Rules\Model\Rule\Condition\ProductFactory
*/
protected $_productFactory;
/**
* @param \Magento\Rule\Model\Condition\Context $context
* @param \RLTSquare\Rules\Model\Rule\Condition\ProductFactory $conditionFactory
* @param array $data
*/
public function __construct(
\Magento\Rule\Model\Condition\Context $context,
\RLTSquare\Rules\Model\Rule\Condition\ProductFactory $conditionFactory,
array $data = []
)
{
$this->_productFactory = $conditionFactory;
parent::__construct($context, $data);
$this->setType(\RLTSquare\Rules\Model\Rule\Condition\Combine::class);
}
/**
* @return array
*/
public function getNewChildSelectOptions()
{
$productAttributes = $this->_productFactory->create()->loadAttributeOptions()->getAttributeOption();
$attributes = [];
foreach ($productAttributes as $code => $label) {
$attributes[] = [
'value' => 'RLTSquare\Rules\Model\Rule\Condition\Product|' . $code,
'label' => $label,
];
}
//populating unique options
$customOptions = $this->_productFactory->create()->getOptionNameList();
$options = [];
foreach ($customOptions as $option){
$options[] = [
'value' => 'RLTSquare\Rules\Model\Rule\Condition\Product|' . $option,
'label' => $option
];
}
$conditions = parent::getNewChildSelectOptions();
$conditions = array_merge_recursive(
$conditions,
[
[
'value' => \RLTSquare\Rules\Model\Rule\Condition\Combine::class,
'label' => __('Conditions Combination'),
],
['label' => __('Product Attribute'), 'value' => $attributes],
['label' => __('Custom Option'), 'value' => $options],
]
);
return $conditions;
}
}
The getOptionNameList()
method is in some other class that's not necessarily needed however, here is the chunk of code for that function:
public function getOptionNameList()
{
$storeId = $this->storeManager->getStore()->getId();
$collection = $this->optionCollectionFactory->create()->addFieldToSelect('*');
$collection->addTitleToResult($storeId);
$options = [];
foreach ($collection as $option){
$options[$option->getTitle()] = $option->getTitle();
}
return $options;
}
So the custom options are appearing like this:
Upon selecting product attribute and condition combination everything goes fine, and drop down like below appears:
The class which generates the new condition html has been extended from is here:
<?php
namespace RLTSquare\Rules\Controller\Adminhtml\Custom\Rule;
class NewConditionHtml extends \RLTSquare\Rules\Controller\Adminhtml\Custom\Rule
{
/**
* New condition html action
*
* @return void
*/
public function execute()
{
$id = $this->getRequest()->getParam('id');
$typeArr = explode('|', str_replace('-', '/', $this->getRequest()->getParam('type')));
$type = $typeArr[0];
$model = $this->_objectManager->create($type);
$model->setId($id);
$model->setType($type);
$model->setRule($this->ruleFactory->create());
$model->setPrefix('conditions');
if (!empty($typeArr[1])) {
$model->setAttribute($typeArr[1]);
}
if ($model instanceof \Magento\Rule\Model\Condition\AbstractCondition) {
$model->setJsFormObject($this->getRequest()->getParam('form'));
$html = $model->asHtmlRecursive();
} else {
$html = '';
}
$this->getResponse()->setBody($html);
}
}
The html is generated through this class Magento\Rule\Model\Condition\AbstractCondition
. I'm unable to know how can I get custom options value same like we get for custom attributes?
Best Answer
Ok, so I created my own class which extend
Magento\Rule\Model\Condition\AbstractCondition
, in the respective methods, I overrode methodgetValueSelectOptions()
to get respective values from Magento tables.just for adding
getValueElementType()
, this method represent that the custom options values will be always a drop down.