Magento – Call to a member function toOptionArray() on boolean error when custom dropdown source model is used in system.xml

adminhtmlmagento-1modulesource-modelsystem-config

My application is configurable, so I have a few settings in the system.xml file. One of the setting uses a custom adminhtml dropdown source model.

So, in the XML, I have defined the setting row like this:

<store_id translate="label">
    <label>Select Store View</label>
    <frontend_type>select</frontend_type>
    <source_model>mymodule_adminhtml/system_config_source_dropdown_stores</source_model>
    <comment>Select the store view that is used for the integration.</comment>
    <sort_order>1</sort_order>
    <show_in_default>1</show_in_default>
    <show_in_website>0</show_in_website>
    <show_in_store>0</show_in_store>
</store_id>

So, I have created the dropdown source model Stores.php here:

app/code/local/Mycompany/Mymodule/Adminhtml/Model/System/Config/Source/Dropdown/Stores.php

This file's contents are:

class Mycompany_Mymodule_Adminhtml_Model_System_Config_Source_Dropdown_Stores
{
    public function toOptionArray()
    {
        // Build Option Array
        $optionArray = array();
        foreach (Mage::app()->getStores() as $store) {
            $optionArray[] = array(
                'value' => $store->getId(),
                'label' => Mage::helper('mymodule')->__($store->getName())
            );
        }

        // Finished
        return $optionArray;
    }
}

My config.xml section for defining the models looks like this:

<models>
    <mymodule>
        <class>Mycompany_Mymodule_Model</class>
        <resourceModel>mymodule_mysql4</resourceModel>
    </mymodule>
    <mymodule_mysql4>
        <class>Mycompany_Mymodule_Model_Mysql4</class>
        <entities>
            <setup>
                <table>mymodule_setup</table>
            </setup>
        </entities>
    </mymodule_mysql4>
</models>

This was working fine before. I could go into System -> Config and click on my module tab and I could see a dropdown list of stores.

Today, this isn't working & I am not sure why. I get the following error:

Fatal error: Call to a member function toOptionArray() on boolean in
/home/www-data/public_html/includes/src/Mage_Adminhtml_Block_System_Config_Form.php
on line 463

Any ideas what might have gone wrong? If I comment out the config section row in the system.xml the config page works in the backend.

Best Answer

From looking in your part of the config.xml codes I can see module calling problem in system.xml

<source_model>mymodule_adminhtml/system_config_source_dropdown_stores</source_model>

Change to

<source_model>mymodule/system_config_source_dropdown_stores</source_model>

And also change the path of your this file and change class name as well:

class Mycompany_Mymodule_Model_System_Config_Source_Dropdown_Stores

Magento strongly follows folder and file structure. You should match it's requirement exactly to be able to get it work.

[UPDATE]

Magento module folder structure should be this:

\app\code\local\MyNamespace\Appname\Model
\app\code\local\MyNamespace\Appname\Block
\app\code\local\MyNamespace\Appname\Helper
\app\code\local\MyNamespace\Appname\etc
\app\code\local\MyNamespace\Appname\controllers
etc

This means your adminhtml cannot come before model or block or etc folders. It should/must go inside them.

To your problem

When declaring a source model for a field in system.xml, Magento will try to retrieve the options for the field by calling:

Mage::getModel('source model here')->toOptionArray();

So in your case it tries :

Mage::getModel('mymodule_adminhtml/system_config_source_dropdown_stores')->toOptionArray();

and returns null.

If I changed it like you said, then the file's location must be moved. I tried it anyway and still same error.

Then there is something wrong in your Model/System/Config/Source/Dropdown/Stores.php file. Try replacing this function and see if that works for debugging:

public function toOptionArray()
    {
        return array(
            //array('value'=>'', 'label'=>''),
            array('value'=>'grid', 'label'=>Mage::helper('adminhtml')->__('Grid Only')),
            array('value'=>'list', 'label'=>Mage::helper('adminhtml')->__('List Only')),
            array('value'=>'grid-list', 'label'=>Mage::helper('adminhtml')->__('Grid (default) / List')),
            array('value'=>'list-grid', 'label'=>Mage::helper('adminhtml')->__('List (default) / Grid')),
        );
    }
Related Topic