1

I want to add condition action in my custom module admin form.

I use like below code all are working perfect, i got also all data in var_dump with save action, but data are not save in database.

I use also follow this link and this link but i can't data save in database.

Please suggest me what i can do now for data save.

app/code/Vendor/Rules/Block/Adminhtml/Rule/Edit/Tab/Conditions.php

<?php
namespace Vendor\Rules\Block\Adminhtml\Rule\Edit\Tab;
use Magento\Framework\App\ObjectManager;
class Conditions extends \Magento\Backend\Block\Widget\Form\Generic implements
 \Magento\Ui\Component\Layout\Tabs\TabInterface
{
 /**
 * Core registry
 *
 * @var \Magento\Backend\Block\Widget\Form\Renderer\Fieldset
 */
 protected $_rendererFieldset;
 /**
 * @var \Magento\Rule\Block\Conditions
 */
 protected $_conditions;
 /**
 * @var \Magento\SalesRule\Model\RuleFactory
 */
 private $ruleFactory;
 /**
 * Initialize dependencies.
 *
 * @param \Magento\Backend\Block\Template\Context $context
 * @param \Magento\Framework\Registry $registry
 * @param \Magento\Framework\Data\FormFactory $formFactory
 * @param \Magento\Rule\Block\Conditions $conditions
 * @param \Magento\Backend\Block\Widget\Form\Renderer\Fieldset $rendererFieldset
 * @param array $data
 */
 public function __construct(
 \Magento\Backend\Block\Template\Context $context,
 \Magento\Framework\Registry $registry,
 \Magento\Framework\Data\FormFactory $formFactory,
 \Magento\Rule\Block\Conditions $conditions,
 \Magento\Backend\Block\Widget\Form\Renderer\Fieldset $rendererFieldset,
 array $data = []
 ) {
 $this->_rendererFieldset = $rendererFieldset;
 $this->_conditions = $conditions;
 parent::__construct($context, $registry, $formFactory, $data);
 }
 /**
 * The getter function to get the new RuleFactory dependency
 *
 * @return \Magento\SalesRule\Model\RuleFactory
 *
 * @deprecated
 */
 private function getRuleFactory()
 {
 if ($this->ruleFactory === null) {
 $this->ruleFactory = ObjectManager::getInstance()->get('Magento\SalesRule\Model\RuleFactory');
 }
 return $this->ruleFactory;
 }
 /**
 * {@inheritdoc}
 * @codeCoverageIgnore
 */
 public function getTabClass()
 {
 return null;
 }
 /**
 * {@inheritdoc}
 * @codeCoverageIgnore
 */
 public function getTabUrl()
 {
 return null;
 }
 /**
 * {@inheritdoc}
 * @codeCoverageIgnore
 */
 public function isAjaxLoaded()
 {
 return false;
 }
 /**
 * {@inheritdoc}
 * @codeCoverageIgnore
 */
 public function getTabLabel()
 {
 return __('Conditions');
 }
 /**
 * {@inheritdoc}
 * @codeCoverageIgnore
 */
 public function getTabTitle()
 {
 return __('Conditions');
 }
 /**
 * {@inheritdoc}
 * @codeCoverageIgnore
 */
 public function canShowTab()
 {
 return true;
 }
 /**
 * {@inheritdoc}
 * @codeCoverageIgnore
 */
 public function isHidden()
 {
 return false;
 }
 protected function _prepareForm()
 {
 $model = $this->_coreRegistry->registry('\Magento\SalesRule\Model\RegistryConstants::CURRENT_SALES_RULE');
 if (!$model) {
 $id = $this->getRequest()->getParam('rule_id');
 $model = $this->getRuleFactory()->create();
 $model->load($id);
 }
 $formName = 'sales_rule_form';
 $conditionsFieldSetId = $model->getConditionsFieldSetId($formName);
 /** @var \Magento\Framework\Data\Form $form */
 $form = $this->_formFactory->create();
 $form->setHtmlIdPrefix('rule_');
 $renderer = $this->_rendererFieldset->setTemplate(
 'Magento_CatalogRule::promo/fieldset.phtml'
 )->setNewChildUrl(
 $this->getUrl('sales_rule/promo_quote/newConditionHtml/form/')
 );
 $fieldset = $form->addFieldset(
 'conditions_fieldset',
 [
 'legend' => __(
 'Apply the rule only if the following conditions are met (leave blank for all products).'
 )
 ]
 )->setRenderer(
 $renderer
 );
 $fieldset->addField(
 'conditions',
 'text',
 ['name' => 'conditions', 'label' => __('Conditions'), 'title' => __('Conditions')]
 )->setRule(
 $model
 )->setRenderer(
 $this->_conditions
 );
 $form->setValues($model->getData());
 $this->setForm($form);
 return parent::_prepareForm();
 }
}
?>

app/code/Vendor/Rules/Setup/InstallSchema.php

<?php
/**
 * Copyright © 2015 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */
namespace Vendor\Rules\Setup;
use Magento\Framework\Setup\InstallSchemaInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\SchemaSetupInterface;
/**
 * @codeCoverageIgnore
 */
class InstallSchema implements InstallSchemaInterface
{
 /**
 * {@inheritdoc}
 */
 public function install(SchemaSetupInterface $setup, ModuleContextInterface $context)
 {
 $installer = $setup;
 $installer->startSetup();
 $table = $installer->getConnection()->newTable(
 $installer->getTable('rule_conditions')
 )->addColumn(
 'cond_id',
 \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
 null,
 ['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true],
 'Condition ID'
 )->addColumn(
 'rule_id',
 \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
 32,
 [],
 'Shipping Restriction Id (Rule Id)'
 )->addColumn(
 'coupon_code',
 \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
 null,
 ['nullable' => false],
 'Coupon Code'
 )->addColumn(
 'shopping_cart_rule',
 \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
 null,
 ['nullable' => false],
 'Shopping Cart Rule'
 );
 $installer->getConnection()->createTable($table);
 $installer->endSetup();
 }
}
?>

app/code/Vendor/Rules/Model/Conditions.php

<?php
namespace Vendor\Rules\Model;
class Conditions extends \Magento\Framework\Model\AbstractModel
{
 /**
 * Initialize resource model
 *
 * @return void
 */
 const STATUS_ENABLED = 1;
 const STATUS_DISABLED = 0;
 protected function _construct()
 {
 $this->_init('Vendor\Rules\Model\ResourceModel\Conditions');
 }
 public function getAvailableStatuses()
 {
 return [self::STATUS_ENABLED => __('Enabled'), self::STATUS_DISABLED => __('Disabled')];
 }
}
?>

app/code/Vendor/Rules/Model/ResourceModel/Conditions.php

<?php
namespace Vendor\Rules\Model\ResourceModel;
class Conditions extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
{ 
 public function __construct(
 \Magento\Framework\Model\ResourceModel\Db\Context $context,
 $connectionName = null
 ) { 
 parent::__construct($context, $connectionName);
 }
 protected function _construct()
 {
 $this->_init('rule_conditions', 'cond_id');
 } 
}
?>

app/code/Vendor/Rules/Model/ResourceModel/Conditions/Collection.php

<?php
namespace Vendor\Rules\Model\ResourceModel\Conditions;
class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection
{
 /**
 * Define resource model
 *
 * @return void
 */
 protected $_idFieldName = 'cond_id';
 protected function _construct()
 {
 $this->_init('Vendor\Rules\Model\Conditions', 'Vendor\Rules\Model\ResourceModel\Conditions');
 $this->_map['fields']['cond_id'] = 'main_table.cond_id';
 }
 public function getAvailableStatuses()
 {
 return [self::STATUS_ENABLED => __('Enabled'), self::STATUS_DISABLED => __('Disabled')];
 }
}
?>

app/code/Vendor/Rules/Controller/Adminhtml/Index/Save.php

<?php
/**
 *
 * Copyright © 2015 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */
namespace Vendor\Rules\Controller\Adminhtml\Index;
use Magento\Backend\App\Action;
use Vendor\Rules\Model\ConditionsFactory;
class Save extends \Magento\Backend\App\Action
{
 protected $ConditionsFactory;
 /**
 * @param Action\Context $context
 * @param PostDataProcessor $dataProcessor
 */
 public function __construct(
 Action\Context $context,
 ConditionsFactory $ConditionsFactory,
 )
 {
 $this->ConditionsFactory = $ConditionsFactory;
 parent::__construct($context);
 }
 /**
 * {@inheritdoc}
 */
 protected function _isAllowed()
 {
 return $this->_authorization->isAllowed('Vendor_Rules::rules_save');
 }
 /**
 * Save action
 *
 * @return \Magento\Framework\Controller\ResultInterface
 */
 public function execute()
 {
 $data = $this->getRequest()->getPostValue();
 /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */
 $resultRedirect = $this->resultRedirectFactory->create();
 if ($data) {
 /*----Rules-Model----*/
 $Condmodel = $this->ConditionsFactory->create();
 //var_dump($data['rule']['conditions']);exit; i got all data here, but data don't save in database
 if (isset($data['rule']['conditions'])) {
 $data['conditions'] = $data['rule']['conditions'];
 }
 if (isset($data['rule']['actions'])) {
 $data['actions'] = $data['rule']['actions'];
 }
 unset($data['rule']);
 $Condmodel->setData($data['rule']['conditions'])
 ->setRuleId($data['rule_id'])
 ->setId($this->getRequest()->getParam('cond_id'));
 try {
 $Condmodel->save();
 $this->messageManager->addSuccess(__('Rules was successfully saved'));
 $this->_objectManager->get('Magento\Backend\Model\Session')->setFormData(false);
 if ($this->getRequest()->getParam('back')) {
 return $resultRedirect->setPath('*/*/edit', ['rule_id' => $Condmodel->getId(), '_current' => true]);
 }
 $this->_redirect('*/*/');
 return;
 } catch (\Magento\Framework\Exception\LocalizedException $e) {
 $this->messageManager->addError($e->getMessage());
 } catch (\RuntimeException $e) {
 $this->messageManager->addError($e->getMessage());
 } catch (\Exception $e) {
 $this->messageManager->addException($e, __($e->getMessage().'Something went wrong while saving the page.'));
 }
 $this->_getSession()->setFormData($data);
 return $resultRedirect->setPath('*/*/edit', ['rule_id' => $this->getRequest()->getParam('rule_id')]);
 }
 return $resultRedirect->setPath('*/*/');
 }
}
?>
  1. Below my admin image this is perfect but data can't save in database and also don't get collection.

enter image description here

  1. Below my var_dump data with save action in image

enter image description here

Any one know tell me please.

Thanks.

asked Oct 6, 2016 at 13:26

1 Answer 1

2

You have a serious error in the controller's code:

if (isset($data['rule']['conditions'])) {
 $data['conditions'] = $data['rule']['conditions'];
}
if (isset($data['rule']['actions'])) {
 $data['actions'] = $data['rule']['actions'];
}
unset($data['rule']);
$Condmodel->setData($data['rule']['conditions'])
 ->setRuleId($data['rule_id'])
 ->setId($this->getRequest()->getParam('cond_id'));

You are trying to delete $data['rule'] and then to transmit the data to the $Condmodel->setData($data['rule']['conditions']) model.

Try to modify this part of the code the following way:

$Condmodel->addData($data)->setId($this->getRequest()->getParam('cond_id'));

Also, you have an error in the models. They should expand the default rule models and not an abstract ones.

You need to replace in the app/code/Vendor/Rules/Model/Conditions.php file:

class Conditions extends \Magento\Framework\Model\AbstractModel

by:

class Conditions extends \Magento\Rule\Model\AbstractModel

In the app/code/Vendor/Rules/Model/ResourceModel/Conditions.php file:

class Conditions extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb

by:

class Conditions extends \Magento\Rule\Model\ResourceModel\AbstractResource

And in the app/code/Vendor/Rules/Model/ResourceModel/Conditions/Collection.php file:

class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection

by:

class Collection extends \Magento\Rule\Model\ResourceModel\Rule\Collection\AbstractCollection

Then, you need to check what is missing in your classes from these abstract classes and add it.

Siarhey Uchukhlebau
16.2k11 gold badges57 silver badges89 bronze badges
answered Oct 7, 2016 at 8:56
1
  • let me know how we can apply our created condition in the frontend Commented Nov 12, 2019 at 5:23

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.