2016/11/02

6 steps to create a custom admin controller with a entity grid in Magento

If you don´t do this all day, you might need some tiny reminder on how to create a customer resource entity in Magento. This post will give you a list of the things you need to do  to list your entity data in the admin panel.

Here it is:

1. Setting up the config.xml

Create the common config nodes like helpers, blocks, models. In the following is only written what is relevant for your entities (this belongs to your global node):

<models>
 <modulename>
   <class>Vendor_ModuleName_Model</class>
   <resourceModel>modulename_resource</resourceModel>
 </modulename>

 <modulename_resource>
   <class>Vendor_ModuleName_Model_Resource</class>
   <entities>
     <dataset>
       <table>modulename_dataset</table>
     </dataset>
   </entities>
 </modulename_resource>
</models>
<resources>
 <modulename_setup>
   <setup>
     <module>Vendor_ModuleName</module>
   </setup>
 </modulename_setup>
</resources>

modulename is the key for our model name. It is derived from our module name: ModuleName. Our entity will be called dataset and is located in the database within the table modulename_dataset.
The node is defining what resource model to use under the key modulename_resource which you can use in Mage methods like 

Mage::getResourceModel('modulename_dataset')


This is related to the resource definition (under node ) in this config with the classname and its entities (in this case dataset).

The node in the last lines are preparing our setup class where you define the SQL to create the tables for our entity.

2. Setting up the SQL Setup

Create a new file in your modules folder:  sql/modulename_setup/install-0.1.0.php (the last folder name is defined by our previous set node. You can do a lot of magic in this setup file but for simplicity we just will create a new table.


/* @var $installer Mage_Core_Model_Resource_Setup */
$installer = $this;
$installer->startSetup();
$installer->run("

DROP TABLE IF EXISTS {$this->getTable('modulename_dataset')};
CREATE TABLE {$this->getTable('modulename_dataset')} (
  `id` int(255) NOT NULL auto_increment,
  `anyfield` int(255) NOT NULL,
  `text` varchar(255) NOT NULL,
  PRIMARY KEY (`id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Your own table';

$installer->endSetup();


The relation for $this->getTable() we defined in our config above in the node
.
This file is executed when you access your adminpanel the first time after you created the module and the module you created has the exact version number as in the filename.

3. Create the models and resource models

Create the dataset model in app/code/community/Vendor/ModuleName/Model/Dataset.php

class Vendor_ModuleName_Model_Dataset
    extends Mage_Core_Model_Abstract
{
    const CACHE_TAG             = 'modulename_dataset';
    protected $_cacheTag        = 'modulename_dataset';
    protected $_append_class    = '';

    protected function _construct()
    {
        $this->_init('modulename/dataset');
    }
}

The string in the _init method is related to resouce model key and resource name.

Info: It has to be exactly the same as your classname of the model - case sensitive! If you name it DataSet.php (classname = Vendor_ModuleName_Model_DataSet) then you have to give _init this string: 'modulename/dataSet'. And you have to update your part in the config.xml!

Create the dataset resource model in app/code/community/Vendor/ModuleName/Model/Resource/Dataset.php

class Vendor_ModuleName_Model_Resource_Dataset
    extends Mage_Core_Model_Resource_Db_Abstract
{
    /**
     * Initialize resource
     *
     */
    protected function _construct()
    {
        $this->_init('modulename/dataset', 'id');
    }
}

The same here. The second parameter in _init belongs to the id field in your table.

Create the dataset resource collection in app/code/community/Vendor/ModuleName/Model/Resource/Dataset/Collection.php

class Vendor_ModuleName_Model_Resource_Dataset_Collection
    extends Mage_Core_Model_Resource_Db_Collection_Abstract
{
    /**
     * construct
     */
    public function _construct()
    {
        $this->_init('modulename/dataset');
    }
}


4. Create the adminhtml controller


class Vendor_ModuleName_Adminhtml_ModuleName_DatasetController
    extends Mage_Adminhtml_Controller_Action
{
    protected function _construct()
    {
        // Define module dependent translate
        $this->setUsedModuleName('Vendor_ModuleName');
    }
    /**
     * Init actions
     *
     * @return Vendor_ModuleName_Adminhtml_ModuleName_DatasetController
     */
    protected function _initAction()
    {
        return $this;
    }

    /**
     * configure action
     * includes the listing of configuration
     * items
     */
    public function indexAction()
    {
        $this->_title($this->__('ModuleName'));
        $this->loadLayout();

        $this->_addContent($this->getLayout()->createBlock('modulename/adminhtml_dataset'));

        $this->renderLayout();
    }
}


The block we create in the index action, we will define in the next step. This for sure requires the node in you configuration, which we did not wrote here.

5. Create the blocks

class Vendor_ModuleName_Block_Adminhtml_Dataset
    extends Mage_Adminhtml_Block_Widget_Container
{
    public function __construct()
    {
        parent::__construct();
        $this->setTemplate('modulename/dataset.phtml');
    }

    /**
     * Prepare button and grid
     *
     * @return Vendor_ModuleName_Block_Adminhtml_Dataset
     */
    protected function _prepareLayout()
    {
        $this->setChild('grid', $this->getLayout()->createBlock('modulename/adminhtml_dataset_grid', 'adminhtml_modulename_dataset.grid'));
        return parent::_prepareLayout();
    }

    /**
     * Render grid
     *
     * @return string
     */
    public function getGridHtml()
    {
        return $this->getChildHtml('grid');
    }
}


Create the grid block, which we created in this block.

class Vendor_ModuleName_Block_Adminhtml_Dataset_Grid
    extends Mage_Adminhtml_Block_Widget_Grid
{
    /**
     * construct
     */
    public function __construct()
    {
        parent::__construct();
        $this->setId('moduleNameGrid');
        $this->setDefaultSort('id');
        $this->setSaveParametersInSession(true);
        $this->setDefaultDir('DESC');
    }

    /**
     * prepare collection
     *
     * @return Vendor_ModuleName_Block_Adminhtml_Dataset_Grid
     */
    protected function _prepareCollection()
    {
        $collection = Mage::getModel('modulename/dataset')->getCollection();
        $this->setCollection($collection);
        parent::_prepareCollection();

        return $this;
    }

    /**
     * prepare Columns
     */
    public function _prepareColumns()
    {
        $baseUrl = $this->getUrl();

        $this->addColumn('id',array(
            'header'        => Mage::helper('modulename')->__('Id'),
            'align'         => 'center',
            'index'         => 'id',
            'width'         => '1%'
        ));
        $this->addColumn('text',array(
            'header'        => Mage::helper('modulename')->__('Text'),
            'align'         => 'left',
            'index'         => 'type',
            'width'         => '29%',
            'filter_index'  => 'type'
        ));
        return parent::_prepareColumns();
    }

    public function getRowUrl($row) {
        // only works if you create that controller action
        return $this->getUrl('*/*/edit',array('id' => $row->getEntityId()));
    }
}


This creates the grid for you. You can define which fields are displayed in the grid.

6. Create the adminhtml template


<div class="content-header">
<table cellspacing="0">
<tr>
<td style="width:50%;"><h3 class="icon-head head-dataset"><?php echo />Mage::helper('modulename')->__('See data') ?></h3></td>
<td class="a-right">
</td>
</tr>
</table>
</div>
<div>
<?php echo $this->getGridHtml() ?>
</div>

This was a summery of what to do to make the grid work. Some steps, like setting up the locale files or helper are not explained in this steps, but as a professional developer you know how to do this.

No comments:

Post a Comment