In Add condition field like Catalog Price Rule in custom Ui component Form Magento 2 [Part-2] section we will perform CRUD operation and also we learn how to check how many products match. If you don’t know about the previous part-1 section please click here.
In previous section we create admin grid and form. In custom_condition_form.xml form file at app/code/Dolphin/AddConditionFiled/view/adminhtml/ui_component uncomment below code:
<?xml version="1.0" encoding="UTF-8"?> <form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd"> <argument name="data" xsi:type="array"> <item name="js_config" xsi:type="array"> <item name="provider" xsi:type="string">custom_condition_form.custom_condition_listing_data_source</item> <item name="deps" xsi:type="string">custom_condition_form.custom_condition_listing_data_source</item> </item> <item name="label" xsi:type="string" translate="true">General Information</item> <item name="config" xsi:type="array"> <item name="dataScope" xsi:type="string">data</item> <item name="namespace" xsi:type="string">custom_condition_form</item> </item> <item name="spinner" xsi:type="string">general_information</item> <item name="buttons" xsi:type="array"> <item name="back" xsi:type="string">Dolphin\AddConditionFiled\Block\Adminhtml\Edit\Button\Back</item> <item name="delete" xsi:type="string">Dolphin\AddConditionFiled\Block\Adminhtml\Edit\Button\Delete</item> <item name="reset" xsi:type="string">Dolphin\AddConditionFiled\Block\Adminhtml\Edit\Button\Reset</item> <item name="save" xsi:type="string">Dolphin\AddConditionFiled\Block\Adminhtml\Edit\Button\Save</item> </item> <item name="template" xsi:type="string">templates/form/collapsible</item> </argument> ............................................................................................................
Now we are create form buttons for perform different operations.
Step-1: Create Generic.php at app/code/Dolphin/AddConditionFiled/Block/Adminhtml/Edit/Button
<?php namespace Dolphin\AddConditionFiled\Block\Adminhtml\Edit\Button; use Magento\Backend\Block\Widget\Context; use Magento\Cms\Api\PageRepositoryInterface; class Generic { protected $context; protected $pageRepository; public function __construct( Context $context, PageRepositoryInterface $pageRepository ) { $this->context = $context; $this->pageRepository = $pageRepository; } public function getUrl($route = '', $params = []) { return $this->context->getUrlBuilder()->getUrl($route, $params); } }
Step-2: Create Back.php at app/code/Dolphin/AddConditionFiled/Block/Adminhtml/Edit/Button
<?php namespace Dolphin\AddConditionFiled\Block\Adminhtml\Edit\Button; use Magento\Framework\View\Element\UiComponent\Control\ButtonProviderInterface; class Back extends Generic implements ButtonProviderInterface { public function getButtonData() { return [ 'label' => __('Back'), 'on_click' => sprintf("location.href = '%s';", $this->getBackUrl()), 'class' => 'back', 'sort_order' => 10, ]; } public function getBackUrl() { return $this->getUrl('*/*/'); } }
Step-3: Create Reset.php at app/code/Dolphin/AddConditionFiled/Block/Adminhtml/Edit/Button
<?php namespace Dolphin\AddConditionFiled\Block\Adminhtml\Edit\Button; use Magento\Framework\View\Element\UiComponent\Control\ButtonProviderInterface; class Reset implements ButtonProviderInterface { public function getButtonData() { return [ 'label' => __('Reset'), 'class' => 'reset', 'on_click' => 'location.reload();', 'sort_order' => 30, ]; } }
Step-4: Create Delete.php at app/code/Dolphin/AddConditionFiled/Block/Adminhtml/Edit/Button
<?php namespace Dolphin\AddConditionFiled\Block\Adminhtml\Edit\Button; use Magento\Backend\Block\Widget\Context; use Magento\Framework\View\Element\UiComponent\Control\ButtonProviderInterface; class Delete extends Generic implements ButtonProviderInterface { protected $context; public function __construct( Context $context ) { $this->context = $context; } public function getButtonData() { $data = []; $rule_id = $this->context->getRequest()->getParam('rule_id'); if ($rule_id) { $data = [ 'label' => __('Delete'), 'class' => 'delete', 'on_click' => 'deleteConfirm(\'' . __( 'Are you sure you want to delete this?' ) . '\', \'' . $this->getDeleteUrl() . '\')', 'sort_order' => 20, ]; } return $data; } public function getDeleteUrl() { $rule_id = $this->context->getRequest()->getParam('rule_id'); return $this->getUrl('*/*/delete', ['rule_id' => $rule_id]); } }
Step-5: Create Save.php at app/code/Dolphin/AddConditionFiled/Block/Adminhtml/Edit/Button
<?php namespace Dolphin\AddConditionFiled\Block\Adminhtml\Edit\Button; use Magento\Framework\View\Element\UiComponent\Control\ButtonProviderInterface; use Magento\Ui\Component\Control\Container; class Save extends Generic implements ButtonProviderInterface { public function getButtonData() { return [ 'label' => __('Save'), 'class' => 'save primary', 'data_attribute' => [ 'mage-init' => [ 'buttonAdapter' => [ 'actions' => [ [ 'targetName' => 'custom_condition_form.custom_condition_form', 'actionName' => 'save', 'params' => [ false, ], ], ], ], ], ], 'class_name' => Container::SPLIT_BUTTON, 'options' => $this->getOptions(), ]; } protected function getOptions() { $options[] = [ 'id_hard' => 'save_and_new', 'label' => __('Save & New'), 'data_attribute' => [ 'mage-init' => [ 'buttonAdapter' => [ 'actions' => [ [ 'targetName' => 'custom_condition_form.custom_condition_form', 'actionName' => 'save', 'params' => [ true, [ 'back' => 'add', ], ], ], ], ], ], ], ]; $options[] = [ 'id_hard' => 'save_and_close', 'label' => __('Save & Close'), 'data_attribute' => [ 'mage-init' => [ 'buttonAdapter' => [ 'actions' => [ [ 'targetName' => 'custom_condition_form.custom_condition_form', 'actionName' => 'save', 'params' => [ true, ], ], ], ], ], ], ]; return $options; } }
After creating buttons form looking like below:
After We Creating controller action file form perform CRUD operation.
Step-6: Create Rule.php at app/code/Dolphin/AddConditionFiled/Controller/Adminhtml/Index
<?php namespace Dolphin\AddConditionFiled\Controller\Adminhtml\Index; abstract class Rule extends \Magento\Backend\App\Action { protected $coreRegistry = null; protected $fileFactory; protected $dateFilter; protected $ruleFactory; protected $logger; public function __construct( \Magento\Backend\App\Action\Context $context, \Magento\Framework\Registry $coreRegistry, \Magento\Framework\App\Response\Http\FileFactory $fileFactory, \Magento\Framework\Stdlib\DateTime\Filter\Date $dateFilter, \Dolphin\AddConditionFiled\Model\CustomConditionFactory $ruleFactory, \Psr\Log\LoggerInterface $logger ) { parent::__construct($context); $this->coreRegistry = $coreRegistry; $this->fileFactory = $fileFactory; $this->dateFilter = $dateFilter; $this->ruleFactory = $ruleFactory; $this->logger = $logger; } protected function _initRule() { $rule = $this->ruleFactory->create(); $this->coreRegistry->register( 'current_rule', $rule ); $id = (int) $this->getRequest()->getParam('id'); if (!$id && $this->getRequest()->getParam('rule_id')) { $id = (int) $this->getRequest()->getParam('rule_id'); } if ($id) { $this->coreRegistry->registry('current_rule')->load($id); } } protected function _initAction() { $this->_view->loadLayout(); return $this; } }
Step-7: Create NewActionHtml.php at app/code/Dolphin/AddConditionFiled/Controller/Adminhtml/Index
<?php namespace Dolphin\AddConditionFiled\Controller\Adminhtml\Index; class NewActionHtml extends \Dolphin\AddConditionFiled\Controller\Adminhtml\Index\Rule { public function execute() { $id = $this->getRequest()->getParam('id'); $typeArr = explode('|', str_replace('-', '/', $this->getRequest()->getParam('type'))); $type = $typeArr[0]; $model = $this->_objectManager->create( $type )->setId( $id )->setType( $type )->setRule( $this->ruleFactory->create() )->setPrefix( 'actions' ); if (!empty($typeArr[1])) { $model->setAttribute($typeArr[1]); } if ($model instanceof \Magento\Rule\Model\Condition\AbstractCondition) { $model->setJsFormObject("custom_condition_form"); $model->setFormName("custom_condition_form"); $html = $model->asHtmlRecursive(); } else { $html = ''; } $this->getResponse()->setBody($html); } }
Step-8: Create Delete.php at app/code/Dolphin/AddConditionFiled/Controller/Adminhtml/Index
<?php namespace Dolphin\AddConditionFiled\Controller\Adminhtml\Index; use Magento\Backend\App\Action; class Delete extends Action { protected $customConditionModel; public function __construct( Action\Context $context, \Dolphin\AddConditionFiled\Model\CustomConditionFactory $customConditionModel ) { parent::__construct($context); $this->customConditionModel = $customConditionModel; } public function execute() { $id = $this->getRequest()->getParam('rule_id'); $resultRedirect = $this->resultRedirectFactory->create(); if ($id) { try { $model = $this->customConditionModel->create(); $model->load($id); $model->delete(); $this->messageManager->addSuccess(__('The rule is deleted successfully.')); return $resultRedirect->setPath('*/*/'); } catch (\Exception $e) { $this->messageManager->addError($e->getMessage()); return $resultRedirect->setPath('*/*/edit', ['rule_id' => $id]); } } $this->messageManager->addError(__('The rule does not exist')); return $resultRedirect->setPath('*/*/'); } }
Step-9: Create Save.php at app/code/Dolphin/AddConditionFiled/Controller/Adminhtml/Index
<?php namespace Dolphin\AddConditionFiled\Controller\Adminhtml\Index; use Dolphin\AddConditionFiled\Model\CustomConditionFactory; use Magento\Backend\App\Action; use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory; use Magento\Framework\Controller\ResultFactory; class Save extends \Magento\Backend\App\Action { protected $ruledatamodel; protected $dataPersistor; protected $productCollectionFactory; public function __construct( Action\Context $context, CollectionFactory $productCollectionFactory, CustomConditionFactory $ruledatamodel ) { $this->productCollectionFactory = $productCollectionFactory; $this->ruledatamodel = $ruledatamodel; parent::__construct($context); } public function execute() { $data = $this->getRequest()->getPostValue(); $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT); if (isset($data['rule']['conditions'])) { $data['conditions'] = $data['rule']['conditions']; } if (isset($data['rule'])) { unset($data['rule']); } try { $model = $this->ruledatamodel->create(); $id = $this->getRequest()->getParam('rule_id'); if ($id) { $model->load($id); } if (!$model->getId() && $id) { $this->messageManager->addErrorMessage(__('This rule is no longer exists.')); return $resultRedirect->setPath('addconditionfiled/index/index'); } $model->loadPost($data); $model->save(); $this->messageManager->addSuccess(__('Rule has been successfully saved.')); if ($this->getRequest()->getParam('back')) { if ($this->getRequest()->getParam('back') == 'add') { return $resultRedirect->setPath('addconditionfiled/index/add'); } else { return $resultRedirect->setPath( 'addconditionfiled/index/edit', [ 'rule_id' => $model->getId(), ] ); } } } catch (\Exception $e) { $this->messageManager->addException($e, __('Something went wrong while saving the data.')); return $resultRedirect->setPath('addconditionfiled/index/add'); } return $resultRedirect->setPath('addconditionfiled/index/index'); } }
Before we save the record, we need to create layout for edit from.
Step-10: Create Edit.php at app/code/Dolphin/AddConditionFiled/Controller/Adminhtml/Index
<?php namespace Dolphin\AddConditionFiled\Controller\Adminhtml\Index; class Edit 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(__('Edit Rule')); return $resultPage; } }
Step-11: Create addconditionfiled_index_edit.xml at app/code/Dolphin/AddConditionFiled/view/adminhtml/layout
<?xml version="1.0"?> <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd"> <update handle="styles"/> <body> <referenceContainer name="content"> <uiComponent name="custom_condition_form"/> </referenceContainer> </body> </page>
we add our from ui component custom_condition_form name here for show from into edit mode. Now your Admin from and grid are ready for CRUD Operation.
Now we show how to check our condition with products. There is 2 way to check the product is matched with our condition or not.
by using getConditions()->validate()
protected $customConditionModel; protected $productFactory; public function __construct( .................................................... \Magento\Catalog\Model\ProductFactory $productFactory, \Dolphin\AddConditionFiled\Model\CustomConditionFactory $customConditionModel, .................................................... ) { .................................................... $this->productFactory = $productFactory; $this->customConditionModel = $customConditionModel; .................................................... } public function checkCondition() { echo "<pre>"; $prdId = 6; //bag product id // Get product data by id $prdData = $this->productFactory->create()->load($prdId); // get rule collection $ruleColl = $this->customConditionModel->create()->getCollection(); foreach ($ruleColl as $ruleKey => $ruleVal) { // check Product with condition if ($ruleVal->getConditions()->validate($prdData)) { echo "Rule Id " . $ruleVal->getId() . " Match<br/>"; } } }
by using the Model function getMatchProductIds() which we already created.
protected $customConditionModel; public function __construct( .................................................... \Dolphin\AddConditionFiled\Model\CustomConditionFactory $customConditionModel, .................................................... ) { .................................................... $this->customConditionModel = $customConditionModel; .................................................... } public function checkCondition() { echo "<pre>"; // get rule collection $ruleColl = $this->customConditionModel->create()->getCollection(); foreach ($ruleColl as $ruleKey => $ruleVal) { // get all product's Ids with match with rule echo "***** Rule Id " . $ruleVal->getId() . " Match Product Ids ***** <br/>"; $matchIds = array_values(array_unique($ruleVal->getMatchProductIds())); print_r($matchIds); } }
Now you can create a condition, perform CRUD operation and also understand how to get match product ids or check the product is match a condition or not.
If you want to use Catalog Price Rule then use \Magento\CatalogRule\Model\Rule\Condition\CombineFactory , If you want to use Cart Price Rules then use \Magento\SalesRule\Model\Rule\Condition\Product\CombineFactory. After adding class Just add it into the below function at app/code/Dolphin/AddConditionFiled/Model/CustomCondition.php
............................................................... ............................................................... protected $condCombineFactory; protected $condProdCombineF; public function __construct( ............................................................... \Magento\CatalogRule\Model\Rule\Condition\CombineFactory $condCombineFactory, \Magento\SalesRule\Model\Rule\Condition\Product\CombineFactory $condProdCombineF, ............................................................... ) { ............................................................... $this->condCombineFactory = $condCombineFactory; $this->condProdCombineF = $condProdCombineF; ............................................................... } ............................................................... ............................................................... public function getConditionsInstance() { return $this->condCombineFactory->create(); } public function getActionsInstance() { return $this->condCombineFactory->create(); } ............................................................... ...............................................................
I hope this helps you. For any doubts regarding this topic, please write your doubts in the comments section.