Download the source for this entire series here!

CRUD – Create

  1. More file structure goodness:
    app/
      etc/
        modules/
          - SavantDegrees_All.xml (Or what ever your company name might be)
      code/
        local/
          SavantDegrees/ (Or what ever your company name might be)
            Twits/ (Or whatever your module name might be)
              Block/
                Admin/
                  - Main.php
                  Main/
                    - Grid.php
                  - New.php
                  New/
                    - Form.php
                - HelloWorld.php
              controllers/
                - AdminController.php
                - IndexController.php
              etc/
                - config.xml
              Helper/
                - Data.php
              Model/
                - Tip.php
                Mysql4/
                  - Tip.php
                  Tip/
                    - Collection.php
              sql/
                twits_setup/
                  - mysql4-install-0.2.0.php
                  - mysql4-upgrade-0.1.0-0.2.0.php

    Here we’ve added the block for the New container and Form

  2. Looking at the New.php code:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    
    <?php
    class SavantDegrees_Twits_Block_Admin_New extends Mage_Adminhtml_Block_Widget_Form_Container
    {
        public function __construct()
        {
            parent::__construct();
     
            $this->_blockGroup = 'twits';
            $this->_mode = 'new';
            $this->_controller = 'admin';
        }
     
        public function getHeaderText()
        {
            return Mage::helper('twits')->__('Add New Tip');
        }
    }
  3. Then the New/Form.php code
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    
    <?php
    class SavantDegrees_Twits_Block_Admin_New_Form extends Mage_Adminhtml_Block_Widget_Form
    {
        protected function _prepareForm()
        {
            $form = new Varien_Data_Form();
     
            $fieldset = $form->addFieldset('new_tip', array('legend' => Mage::helper('twits')->__('Tip Details')));
     
            $fieldset->addField('title', 'text', array(
                'name'      => 'title',
                'title'     => Mage::helper('twits')->__('Title'),
                'label'     => Mage::helper('twits')->__('Title'),
                'maxlength' => '250',
                'required'  => true,
            ));
     
            $fieldset->addField('author', 'text', array(
                'name'      => 'author',
                'title'     => Mage::helper('twits')->__('Author'),
                'label'     => Mage::helper('twits')->__('Author'),
                'maxlength' => '250',
                'required'  => true,
            ));
     
            $fieldset->addField('contents', 'textarea', array(
                'name'      => 'contents',
                'title'     => Mage::helper('twits')->__('Contents'),
                'label'     => Mage::helper('twits')->__('Contents'),
                'style'     => 'width: 98%; height: 200px;',
                'required'  => true,
            ));
     
            $form->setMethod('post');
            $form->setUseContainer(true);
            $form->setId('edit_form');
            $form->setAction($this->getUrl('*/*/post'));
     
            $this->setForm($form);
        }
    }

    Just like your listings/grid page, the New.php and Form.php classes are the Form Container and Form respectively. So the Form Container automagically creates the form. Did I mention why containers are good? They come with nice pretty buttons! (Save and Back).

  4. Then lastly the adminController with its newAction and postAction to load and save the form respectively

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    
    <?php
    class SavantDegrees_Twits_AdminController extends Mage_Adminhtml_Controller_Action
    {
    	public function indexAction()
        {
    		$this->loadLayout()
    			->_addContent($this->getLayout()->createBlock('twits/admin_main'))
    			->renderLayout();
        }
     
    	public function deleteAction()
        {
            $tipId = $this->getRequest()->getParam('id', false);
     
            try {
                Mage::getModel('twits/tip')->setId($tipId)->delete();
                Mage::getSingleton('adminhtml/session')->addSuccess(Mage::helper('twits')->__('Tip successfully deleted'));
                $this->getResponse()->setRedirect($this->getUrl('*/*/'));
     
                return;
            } catch (Exception $e){
                Mage::getSingleton('adminhtml/session')->addError($e->getMessage());
            }
     
            $this->_redirectReferer();
        }
     
        public function newAction()
        {
            $this->loadLayout()
            ->_addContent($this->getLayout()->createBlock('twits/admin_new'))
            ->renderLayout();
        }
     
        public function postAction()
        {
            if ($data = $this->getRequest()->getPost()) {
                $tip = Mage::getModel('twits/tip')->setData($data);
                try {
                    $tip->save();
                    Mage::getSingleton('adminhtml/session')->addSuccess(Mage::helper('twits')->__('Tip was successfully saved'));
                    $this->getResponse()->setRedirect($this->getUrl('*/*/'));
                    return;
                } catch (Exception $e){
                    Mage::getSingleton('adminhtml/session')->addError($e->getMessage());
                }
            }
            $this->getResponse()->setRedirect($this->getUrl('*/*/'));
            return;
        }
    }
  5. Reward yourself for your lightning fast copy-and-paste kung foo! Whats happening though?
    When the script receives a call newAction, it’ll show the form to enter data. The data is posted to the postAction method. That method creates an instance of the model, sets the post data into the model, saves it then redirects it back to the indexAction. Did i mention automagically? Yes, thats why we had to learn so much of the Magento code just to write this simple tutorial. The sql is automagically generated and run and the form is automagically created! *sheds a tear*

    Again, your well deserved create form can be found by clicking on the “Add New Tip” button from the Grid!

» Just 1 more … CRUD – Update


4 Responses to “Howto: Repackageable custom extension development in Magento – Part 7 – CRUD – Create”

  1. Margots Says:

    Thanks! This is big for me
    I cannot see how did you attach newAction() to the button “Add New Twit”. I see the button itself was added in the Main.php, but where/how the action is attached to it?

  2. Aromal Says:

    Hi gaweee
    it worked :) I made a mistake by creating the ‘New’ folder outside Admin folder.

    Thanks a lot

  3. Aromal Says:

    Hi gaweee

    Thanks a alot for this great tutorial…
    But I am getting the following error when I click on `Add New Twit`.
    Fatal error: Call to a member function setData() on a non-object in /srv/www/htdocs/Magento/app/code/core/Mage/Adminhtml/Block/Widget/Form/Container.php on line 129

    Could you please help me to fix this issue.

  4. Nightfly Says:

    Very useful stuff!

Leave a Reply