Follow Below Steps:
Step-1: Create registration.php at app/code/VendoreName/AddConditionFiled
<?php
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'VendoreName_AddConditionFiled',
__DIR__
);
Step-2: Create module.xml at app/code/VendoreName/AddConditionFiled/etc
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="VendoreName_AddConditionFiled" setup_version="1.0.1">
<sequence>
<module name="Magento_Checkout"></module>
<module name="Magento_Catalog"></module>
</sequence>
</module>
</config>
Step-3: Create InstallSchema.php at app/code/VendoreName/AddConditionFiled/Setup
<?php
namespace VendoreName\AddConditionFiled\Setup;
use Magento\Framework\DB\Ddl\Table;
use Magento\Framework\Setup\InstallSchemaInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\SchemaSetupInterface;
class InstallSchema implements InstallSchemaInterface
{
public function install(SchemaSetupInterface $setup, ModuleContextInterface $context)
{
$installer = $setup;
$installer->startSetup();
if (!$installer->tableExists('VendoreName_custom_condition')) {
$tableName = $installer->getTable('VendoreName_custom_condition');
$table = $installer->getConnection()
->newTable($tableName)
->addColumn(
'rule_id',
Table::TYPE_INTEGER,
10,
[
'identity' => true,
'nullable' => false,
'primary' => true,
],
'Rule ID'
)
->addColumn(
'rule_status',
Table::TYPE_INTEGER,
null,
[
'nullable' => true,
'default' => null,
],
'Rule Status'
)
->addColumn(
'rule_name',
Table::TYPE_TEXT,
255,
[
'nullable' => true,
'default' => null,
],
'Rule Name'
)
->addColumn(
'conditions_serialized',
Table::TYPE_TEXT,
'2M',
[],
'Conditions Serialized'
)
->addColumn(
'actions_serialized',
Table::TYPE_TEXT,
'2M',
[],
'Actions Serialized'
)
->addColumn(
'create_date',
\Magento\Framework\DB\Ddl\Table::TYPE_TIMESTAMP,
null,
[
'nullable' => false,
'default' => \Magento\Framework\DB\Ddl\Table::TIMESTAMP_INIT,
],
'Create Date Time'
)
->setComment('VendoreName Demo For Condition Field')
->setOption('type', 'InnoDB')
->setOption('charset', 'utf8');
$installer->getConnection()->createTable($table);
}
$installer->endSetup();
}
}
Here conditions_serialized and actions_serialized are used to store condition field value. So you must be add into you table. After creating table we add resource model and collection. Our Model name is CustomCondition.
Step-4: Create CustomCondition.php at app/code/VendoreName/AddConditionFiled/Model
<?php
namespace VendoreName\AddConditionFiled\Model;
use VendoreName\AddConditionFiled\Model\ResourceModel\CustomCondition as CustomConditionResourceModel;
use Magento\Quote\Model\Quote\Address;
use Magento\Rule\Model\AbstractModel;
class CustomCondition extends AbstractModel
{
protected $_eventPrefix = 'VendoreName_addconditionfiled';
protected $_eventObject = 'rule';
protected $condCombineFactory;
protected $condProdCombineF;
protected $validatedAddresses = [];
protected $_selectProductIds;
protected $_displayProductIds;
public function __construct(
\Magento\Framework\Model\Context $context,
\Magento\Framework\Registry $registry,
\Magento\Framework\Data\FormFactory $formFactory,
\Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
\Magento\CatalogRule\Model\Rule\Condition\CombineFactory $condCombineFactory,
\Magento\SalesRule\Model\Rule\Condition\Product\CombineFactory $condProdCombineF,
\Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
\Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
array $data = []
) {
$this->condCombineFactory = $condCombineFactory;
$this->condProdCombineF = $condProdCombineF;
parent::__construct($context, $registry, $formFactory, $localeDate, $resource, $resourceCollection, $data);
}
protected function _construct()
{
parent::_construct();
$this->_init(CustomConditionResourceModel::class);
$this->setIdFieldName('rule_id');
}
public function getConditionsInstance()
{
return $this->condCombineFactory->create();
}
public function getActionsInstance()
{
return $this->condCombineFactory->create();
}
public function hasIsValidForAddress($address)
{
$addressId = $this->_getAddressId($address);
return isset($this->validatedAddresses[$addressId]) ? true : false;
}
public function setIsValidForAddress($address, $validationResult)
{
$addressId = $this->_getAddressId($address);
$this->validatedAddresses[$addressId] = $validationResult;
return $this;
}
public function getIsValidForAddress($address)
{
$addressId = $this->_getAddressId($address);
return isset($this->validatedAddresses[$addressId]) ? $this->validatedAddresses[$addressId] : false;
}
private function _getAddressId($address)
{
if ($address instanceof Address) {
return $address->getId();
}
return $address;
}
public function getConditionsFieldSetId($formName = '')
{
return $formName . 'rule_conditions_fieldset_' . $this->getId();
}
public function getActionFieldSetId($formName = '')
{
return $formName . 'rule_actions_fieldset_' . $this->getId();
}
public function getMatchProductIds()
{
$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->_selectProductIds = [];
$this->setCollectedAttributes([]);
$this->getConditions()->collectValidatedAttributes($productCollection);
\Magento\Framework\App\ObjectManager::getInstance()->create(
'\Magento\Framework\Model\ResourceModel\Iterator'
)->walk(
$productCollection->getSelect(),
[[$this, 'callbackValidateProductCondition']],
[
'attributes' => $this->getCollectedAttributes(),
'product' => $productFactory->create(),
]
);
return $this->_selectProductIds;
}
public function callbackValidateProductCondition($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->_selectProductIds[] = $product->getId();
}
}
}
protected function _getWebsitesMap()
{
$map = [];
$websites = \Magento\Framework\App\ObjectManager::getInstance()->create(
'\Magento\Store\Model\StoreManagerInterface'
)->getWebsites();
foreach ($websites as $website) {
if ($website->getDefaultStore() === null) {
continue;
}
$map[$website->getId()] = $website->getDefaultStore()->getId();
}
return $map;
}
}
Step-5: Create CustomCondition.php at app/code/VendoreName/AddConditionFiled/Model/ResourceModel
<?php
namespace VendoreName\AddConditionFiled\Model\ResourceModel;
use Magento\Framework\Model\ResourceModel\Db\AbstractDb;
class CustomCondition extends AbstractDb
{
protected function _construct()
{
$this->_init('VendoreName_custom_condition', 'rule_id');
}
}
Step-6: Create Collection.php at app/code/VendoreName/AddConditionFiled/Model/ResourceModel/CustomCondition
<?php
namespace VendoreName\AddConditionFiled\Model\ResourceModel\CustomCondition;
use VendoreName\AddConditionFiled\Model\CustomCondition as CustomConditionModel;
use VendoreName\AddConditionFiled\Model\ResourceModel\CustomCondition as CustomConditionResourceModel;
use Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection;
class Collection extends AbstractCollection
{
protected function _construct()
{
$this->_init(
CustomConditionModel::class,
CustomConditionResourceModel::class
);
}
}
Step-7: Create Collection.php at app/code/VendoreName/AddConditionFiled/Model/ResourceModel/CustomCondition/Grid
<?php
namespace VendoreName\AddConditionFiled\Model\ResourceModel\CustomCondition\Grid;
use VendoreName\AddConditionFiled\Model\ResourceModel\CustomCondition\Collection as CustomConditionCollection;
use Magento\Framework\View\Element\UiComponent\DataProvider\Document as CustomConditionModel;
class Collection extends CustomConditionCollection implements \Magento\Framework\Api\Search\SearchResultInterface
{
protected $aggregations;
public function __construct(
\Magento\Framework\Data\Collection\EntityFactoryInterface $entityFactory,
\Psr\Log\LoggerInterface $logger,
\Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
\Magento\Framework\Event\ManagerInterface $eventManager,
$mainTable,
$eventPrefix,
$eventObject,
$resourceModel,
$model = CustomConditionModel::class,
$connection = null,
\Magento\Framework\Model\ResourceModel\Db\AbstractDb $resource = null
) {
parent::__construct($entityFactory, $logger, $fetchStrategy, $eventManager, $connection, $resource);
$this->_eventPrefix = $eventPrefix;
$this->_eventObject = $eventObject;
$this->_init($model, $resourceModel);
$this->setMainTable($mainTable);
}
public function getAggregations()
{
return $this->aggregations;
}
public function setAggregations($aggregations)
{
$this->aggregations = $aggregations;
}
public function getAllIds($limit = null, $offset = null)
{
return $this->getConnection()->fetchCol($this->_getAllIdsSelect($limit, $offset), $this->_bindParams);
}
public function getSearchCriteria()
{
return null;
}
public function setSearchCriteria(\Magento\Framework\Api\SearchCriteriaInterface $searchCriteria = null)
{
return $this;
}
public function getTotalCount()
{
return $this->getSize();
}
public function setTotalCount($totalCount)
{
return $this;
}
public function setItems(array $items = null)
{
return $this;
}
}
Step-8: Create di.xml at app/code/VendoreName/AddConditionFiled/etc
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
<virtualType name="VendoreNameAddConditionFiledFilterPool"
type="Magento\Framework\View\Element\UiComponent\DataProvider\FilterPool">
<arguments>
<argument name="appliers" xsi:type="array">
<item name="regular" xsi:type="object">Magento\Framework\View\Element\UiComponent\DataProvider\RegularFilter</item>
<item name="fulltext" xsi:type="object">Magento\Framework\View\Element\UiComponent\DataProvider\FulltextFilter</item>
</argument>
</arguments>
</virtualType>
<virtualType name="VendoreNameAddConditionFiledFilterPool"
type="Magento\Framework\View\Element\UiComponent\DataProvider\DataProvider">
<arguments>
<argument name="collection" xsi:type="object" shared="false">VendoreName\AddConditionFiled\Model\ResourceModel\CustomCondition\Collection</argument>
<argument name="filterPool" xsi:type="object" shared="false">VendoreNameAddConditionFiledFilterPool</argument>
</arguments>
</virtualType>
<type name="VendoreName\AddConditionFiled\Model\ResourceModel\CustomCondition\Grid\Collection">
<arguments>
<argument name="mainTable" xsi:type="string">VendoreName_custom_condition</argument>
<argument name="eventPrefix" xsi:type="string">VendoreName_custom_condition_grid_collection</argument>
<argument name="eventObject" xsi:type="string">VendoreName_custom_condition_grid_collection</argument>
<argument name="resourceModel" xsi:type="string">VendoreName\AddConditionFiled\Model\ResourceModel\CustomCondition</argument>
</arguments>
</type>
<type name="Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory">
<arguments>
<argument name="collections" xsi:type="array">
<item name="custom_condition_listing_data_source" xsi:type="string">VendoreName\AddConditionFiled\Model\ResourceModel\CustomCondition\Grid\Collection</item>
</argument>
</arguments>
</type>
</config>
Step-9: Create routes.xml at app/code/VendoreName/AddConditionFiled/etc/adminhtml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/App/etc/routes.xsd">
<router id="admin">
<route id="addconditionfiled" frontName="addconditionfiled">
<module name="VendoreName_AddConditionFiled" before="Magento_Backend"/>
</route>
</router>
</config>
Step-10: Create Index.php at app/code/VendoreName/AddConditionFiled/Controller/Adminhtml/Index
<?php
namespace VendoreName\AddConditionFiled\Controller\Adminhtml\Index;
class Index extends \Magento\Backend\App\Action
{
protected $resultPageFactory;
public function __construct(
\Magento\Backend\App\Action\Context $context,
\Magento\Framework\View\Result\PageFactory $resultPageFactory
) {
parent::__construct($context);
$this->resultPageFactory = $resultPageFactory;
}
public function execute()
{
$resultPage = $this->resultPageFactory->create();
$resultPage->getConfig()->getTitle()->prepend(__('Add Rules'));
return $resultPage;
}
}
Step-11: Create menu.xml at app/code/VendoreName/AddConditionFiled/etc/adminhtml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Magento/Backend/etc/menu.xsd">
<menu>
<add id="VendoreName_AddConditionFiled::VendoreName_addconditionfiled"
title="VendoreName - Add Condition Field"
translate="title"
module="VendoreName_AddConditionFiled"
sortOrder="10"
parent="Magento_Backend::marketing"
resource="VendoreName_AddConditionFiled::VendoreName_addconditionfiled" />
<add id="VendoreName_AddConditionFiled::menu"
title="Add Rules"
module="VendoreName_AddConditionFiled"
sortOrder="100"
parent="VendoreName_AddConditionFiled::VendoreName_addconditionfiled"
action="addconditionfiled/index/index"
resource="VendoreName_AddConditionFiled::menu"/>
</menu>
</config>