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.

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.

1
  • let me know how we can apply our created condition in the frontend Nov 12, 2019 at 5:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.