cancel
Showing results for 
Search instead for 
Did you mean: 

_beforeSave and _afterSave are not called in backend_model model class

SOLVED

_beforeSave and _afterSave are not called in backend_model model class

Hello,

 

I added a custom table to my plugin and want to populate this table from admin area. I use Magento 1.9.1.0 community edition.

 

In system.xml:

<config>
<sections>

...
<mygroup type="group" translate="label">
    <label>Expandable group</label>
    <frontend_type>text</frontend_type>
    <show_in_default>1</show_in_default>
    <show_in_website>1</show_in_website>
    <show_in_store>1</show_in_store>
    <frontend_model>mycompany/adminhtml_system_config_fieldset_simple</frontend_model>

    <sort_order>60</sort_order>
    <expanded>1</expanded>

    <fields>

        <options_table translate="label">
            <label>Options</label>
            <frontend_type>text</frontend_type>
            <frontend_model>mycompany/adminhtml_system_config_configuredoptions</frontend_model>
            <backend_model>mycompany/system_config_backend_configuredoptions</backend_model>
            <sort_order>1</sort_order>
            <show_in_default>1</show_in_default>
            <show_in_website>1</show_in_website>
            <show_in_store>1</show_in_store>
            <config_path>payment/mycompany/selected_options</config_path>
        </options_table>

    </fields>

</mygroup>
...

</sections>
</config>

 

So for options_table.frontend_model I have a block which extends Mage_Adminhtml_Block_System_Config_Form_Fieldset and uses a template to display a table containing options. Each option has a checkbox and an input field.

 

options_table.backend_model is a model which extends Mage_Core_Model_Config_Data and should save details presented in interface / template to the custom table using _afterLoad(), _beforeSave() and _afterSave() mechanism.

 

mycompany/Model/System/Config/Backend/Configuredoptions.php

class Mycompany_Model_System_Config_Backend_Configuredoptions extends Mage_Core_Model_Config_Data
{
    protected function _afterLoad()
    {
        $logger_obj = Mage::getModel( 'mycompany/logger' );

        $logger_obj->write( 'afterload', 'config_save' );

        return $this;
    }

    protected function _beforeSave()
    {
        $logger_obj = Mage::getModel( 'mycompany/logger' );

        $logger_obj->write( 'Saving', 'config_save' );

        $this->_dataSaveAllowed = true;

        return $this;
    }

    protected function _afterSave()
    {
        $logger_obj = Mage::getModel( 'mycompany/logger' );

        $logger_obj->write( 'After saving', 'config_save' );

        return $this;
    }
}

 

mycompany/Model/Logger.php is a function which writes a buffer in a logging table.

 

So my problem is that _beforeSave() and _afterSave() from Mycompany_Model_System_Config_Backend_Configuredoptions is not called at all. However, _afterLoad() is called as I see in logging table. Am I doing something wrong?

 

Ps. I tried overloading protected function _hasModelChanged() method in Mycompany_Model_System_Config_Backend_Configuredoptions to always return true, but no luck.

 

Any help is much appreciated!

 

Thank you!

1 ACCEPTED SOLUTION

Accepted Solutions

Re: _beforeSave and _afterSave are not called in backend_model model class

Finally found a solution when you want to have a custom frontend_model and backend_model in admin interface.

 

In my case I presented an interface with more inputs (checkboxes, text inputs etc) which then needed to be extracted from configuration form and then saved in a separate table from backend_model.

 

What I thought is that Magento would call _beforeSave and _afterSave methods because I defined the backend_model in system.xml file, but he relies on inputs it received in form submission.

 

So in order for your _beforeSave and _afterSave methods from backend_model to be called you will have to display a hidden input in fronend_model renderer which would define your element (as defined in system.xml) in groups value passed at form submision. In example I provided above for system.xml input would look like:

 

<input type="hidden" name="groups[mygroup][fields][options_table][value]" value="1" />

 

To be sure your _afterSave is called put a default value of 0 or some value different than in hidden input in your config.xml file:

<config>
...
<defualt>
<payment>
<mycompany>
<selected_options>0</selected_options>
</mycompany>
</payment>
</default>
...
</config>

 

Hope this helps...

 

Andy

View solution in original post

4 REPLIES 4

Re: _beforeSave and _afterSave are not called in backend_model model class

Hi @AndyS2P 

 

Save functions are not called if the object is not modfied (I, it uses the the procted method _hasModelChanged on the object to check that, before saving.

 

I hope this helps :-)

 

 

Re: _beforeSave and _afterSave are not called in backend_model model class

Hi Theis,

 

Thanks for your reply.

 

I even added

protected function _hasModelChanged()
{
    return true;
}

 to Mycompany_Model_System_Config_Backend_Configuredoptions to be sure system thinks object is changed, but doesn't work either...

 

Any other ideas?

Re: _beforeSave and _afterSave are not called in backend_model model class

Finally found a solution when you want to have a custom frontend_model and backend_model in admin interface.

 

In my case I presented an interface with more inputs (checkboxes, text inputs etc) which then needed to be extracted from configuration form and then saved in a separate table from backend_model.

 

What I thought is that Magento would call _beforeSave and _afterSave methods because I defined the backend_model in system.xml file, but he relies on inputs it received in form submission.

 

So in order for your _beforeSave and _afterSave methods from backend_model to be called you will have to display a hidden input in fronend_model renderer which would define your element (as defined in system.xml) in groups value passed at form submision. In example I provided above for system.xml input would look like:

 

<input type="hidden" name="groups[mygroup][fields][options_table][value]" value="1" />

 

To be sure your _afterSave is called put a default value of 0 or some value different than in hidden input in your config.xml file:

<config>
...
<defualt>
<payment>
<mycompany>
<selected_options>0</selected_options>
</mycompany>
</payment>
</default>
...
</config>

 

Hope this helps...

 

Andy

Re: _beforeSave and _afterSave are not called in backend_model model class

I wrote a shell script to mass update product images (remove existing images, add new images). Although the new images were imported into media/catalog/product folder, the DB entries (in catalog_product_media_gallery) were not updated, and the product mediagallery were still linked to the old files. It boiled down to the fact that mediagallery backend afterSave() wasn't being called, and that's where much of the magic happens. From this thread and your reply @AndyS2P, I figured that since I don't have a frontend, and there's nothing else I need to change in the object, I can myself trigger gallery backend afterSave(). That works out. Thanks a ton.