Howto: Repackageable custom extension development in Magento – Part 7 – CRUD – Create
Author: gaweee | Filed under: development, howtoCRUD – Create
- 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) Twit/ (Or whatever your module name might be) Block/ Admin/ - Main.php Main/ - Grid.php - New.php New/ - Form.php - Index.php controllers/ - AdminController.php - IndexController.php etc/ - config.xml Helper/ - Data.php Model/ - Twit.php Mysql4/ - Twit.php Twit/ - Collection.php sql/ twit_setup/ - mysql4-install-0.2.0.php - mysql4-upgrade-0.1.0-0.2.0.phpHere we’ve added the block for the
Newcontainer andForm - Looking at the
New.phpcode:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
<?php class SavantDegrees_Twit_Block_Admin_New extends Mage_Adminhtml_Block_Widget_Form_Container { public function __construct() { parent::__construct(); $this->_blockGroup = 'twit'; $this->_mode = 'new'; $this->_controller = 'admin'; } public function getHeaderText() { return Mage::helper('twit')->__('Add New Twit'); } }
- Then the
New/Form.phpcode1 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_Twit_Block_Admin_New_Form extends Mage_Adminhtml_Block_Widget_Form { protected function _prepareForm() { $form = new Varien_Data_Form(); $fieldset = $form->addFieldset('new_twit', array('legend' => Mage::helper('twit')->__('Twit Details'))); $fieldset->addField('name', 'text', array( 'name' => 'name', 'title' => Mage::helper('twit')->__('Name'), 'label' => Mage::helper('twit')->__('Name'), 'maxlength' => '50', 'required' => true, )); $fieldset->addField('tags', 'text', array( 'name' => 'tags', 'title' => Mage::helper('twit')->__('Tags'), 'label' => Mage::helper('twit')->__('Tags'), 'maxlength' => '255', 'required' => true, )); $fieldset->addField('summary', 'textarea', array( 'name' => 'summary', 'title' => Mage::helper('twit')->__('Summary'), 'label' => Mage::helper('twit')->__('Summary'), '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.phpandForm.phpclasses are theForm ContainerandFormrespectively. So theForm Containerautomagically creates the form. Did I mention why containers are good? They come with nice pretty buttons! (Save and Back). -
Then lastly the
adminControllerwith itsnewActionandpostActionto load and save the form respectively1 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
class SavantDegrees_Twit_AdminController extends Mage_Adminhtml_Controller_Action { public function indexAction() { $this->loadLayout() ->_addContent($this->getLayout()->createBlock('twit/admin_main')) ->renderLayout(); } public function deleteAction() { $twitId = $this->getRequest()->getParam('id', false); try { Mage::getModel('twit/twit')->setId($twitId)->delete(); Mage::getSingleton('adminhtml/session')->addSuccess(Mage::helper('twit')->__('Page 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('twit/admin_new')) ->renderLayout(); } public function postAction() { if ($data = $this->getRequest()->getPost()) { $twit = Mage::getModel('twit/twit')->setData($data); try { $twit->save(); Mage::getSingleton('adminhtml/session')->addSuccess(Mage::helper('twit')->__('Twit 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; } }
-
Reward yourself for your lightning fast copy-and-paste kung foo! Whats happening though?
When the script receives a callnewAction, it’ll show the form to enter data. The data is posted to thepostActionmethod. That method creates an instance of the model, sets the post data into the model, saves it then redirects it back to theindexAction. 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 Twit” button from the
Grid!
Howto: Repackageable custom extension development in Magento – Part 6 – CRUD – Delete
Author: gaweee | Filed under: development, howtoCRUD – Delete
- The simplest step thus far, add a new function to your
adminController.php1 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
<?php class SavantDegrees_Twit_AdminController extends Mage_Adminhtml_Controller_Action { public function indexAction() { $this->loadLayout() ->_addContent($this->getLayout()->createBlock('twit/admin_main')) ->renderLayout(); } public function deleteAction() { $twitId = $this->getRequest()->getParam('id', false); try { Mage::getModel('twit/twit')->setId($twitId)->delete(); Mage::getSingleton('adminhtml/session')->addSuccess(Mage::helper('twit')->__('Page successfully deleted')); $this->getResponse()->setRedirect($this->getUrl('*/*/')); return; } catch (Exception $e){ Mage::getSingleton('adminhtml/session')->addError($e->getMessage()); } $this->_redirectReferer(); } }
Howto: Repackageable custom extension development in Magento – Part 5 – CRUD – Retrieve
Author: gaweee | Filed under: development, howtoCRUD – Retrieve
- Lets add a new block to the file structure
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) Twit/ (Or whatever your module name might be) Block/ Admin/ - Main.php Main/ - Grid.php - Index.php controllers/ - AdminController.php - IndexController.php etc/ - config.xml Helper/ - Data.php Model/ - Twit.php Mysql4/ - Twit.php Twit/ - Collection.php sql/ twit_setup/ - mysql4-install-0.2.0.php - mysql4-upgrade-0.1.0-0.2.0We’ll create folder called
Adminto store all the admin related blocks. Inside we’ll have a Main.php file that contains theGrid Container. Why do we need a grid container? To put the title andCreatebutton! -
The
Main.phpcode1 2 3 4 5 6 7 8 9 10 11 12 13
<?php class SavantDegrees_Twit_Block_Admin_Main extends Mage_Adminhtml_Block_Widget_Grid_Container { public function __construct() { $this->_addButtonLabel = Mage::helper('twit')->__('Add New Twit'); parent::__construct(); $this->_blockGroup = 'twit'; $this->_controller = 'admin_main'; $this->_headerText = Mage::helper('twit')->__('Twit(s)'); } }
Here you see a first use of the helper, which will assist in translation
-
The
Grid.phpitself1 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 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
<?php class SavantDegrees_Twit_Block_Admin_Main_Grid extends Mage_Adminhtml_Block_Widget_Grid { public function __construct() { parent::__construct(); $this->setId('twitGrid'); $this->_controller = 'twit'; } protected function _prepareCollection() { $model = Mage::getModel('twit/twit'); $collection = $model->getCollection(); $this->setCollection($collection); return parent::_prepareCollection(); } protected function _prepareColumns() { $this->addColumn('twit_id', array( 'header' => Mage::helper('twit')->__('ID'), 'align' => 'right', 'width' => '50px', 'filter_index' => 'dt.twit_id', 'index' => 'twit_id', )); $this->addColumn('name', array( 'header' => Mage::helper('twit')->__('Name'), 'align' => 'left', 'width' => '150px', 'filter_index' => 'dt.name', 'index' => 'name', 'type' => 'text', 'truncate' => 50, 'escape' => true, )); $this->addColumn('summary', array( 'header' => Mage::helper('twit')->__('Summary'), 'align' => 'left', 'filter_index' => 'dt.summary', 'index' => 'summary', 'type' => 'text', 'escape' => false, )); $this->addColumn('tags', array( 'header' => Mage::helper('twit')->__('Tags'), 'align' => 'left', 'filter_index' => 'dt.tags', 'index' => 'tags', 'type' => 'text', 'escape' => true, )); $this->addColumn('action', array( 'header' => Mage::helper('twit')->__('Action'), 'width' => '150px', 'type' => 'action', 'getter' => 'getTwitId', 'actions' => array( array( 'caption' => Mage::helper('twit')->__('Edit'), 'url' => array( 'base'=>'*/*/edit' ), 'field' => 'id' ), array( 'caption' => Mage::helper('twit')->__('Delete'), 'url' => array( 'base'=>'*/*/delete' ), 'field' => 'id' ) ), 'filter' => false, 'sortable' => false )); return parent::_prepareColumns(); } public function getRowUrl($row) { return $this->getUrl('*/*/edit', array( 'id' => $row->getTwitId(), )); } }
If you scrutinize the code (which i’d advise against), you’ll see most of the code is geared towards the setup of the grid columns and the edit/delete urls i’ll eventually call to perform the other
CRUDfunctions.
But whats going on? Where do we use this code? The main code (being aGrid_Containerautomatically adds the childGridcode associated to it. By child we’re talking about theGrid.phpfile in theMainfolder. The folder’s name follows the file. So if you changed the folder’s name toMain2, it wouldnt work. That being said, you can just put any block code in the folder and expect it to run. The reason why this all works now is cause the geniuses at Magento already did alot of work to call the Grid child to run. They have no super time travel powers to tell what else you’re gonna put in there. So, it simply wont work (yet). - Now lets make our
adminController.phpuse that block instead of Hello world.1 2 3 4 5 6 7 8 9
class SavantDegrees_Twit_AdminController extends Mage_Adminhtml_Controller_Action { public function indexAction() { $this->loadLayout() ->_addContent($this->getLayout()->createBlock('twit/admin_main')) ->renderLayout(); } }
Well it says
createBlockdoesnt it? What do you think it does?twit/admin_mainas always refers to the twit namespace and theadmin/main.phpblock file. - Viola! Your very very very hard earned grid!
Most Popular
- HOWTO: PHP and jQuery upload progress bar (47)
- JQuery Progress Bar 1.1 (41)
- Howto: Repackageable custom extension development in Magento - Part 2 - Admin Controller (24)
- Howto: Repackageable custom extension development in Magento - Part 8 - CRUD - Update (13)
- HOWTO: struts 2 i18n (12)
- JQuery Progress Bar 2.0 (11)
- JQuery Progress Bar 1.2 (10)
- Howto: Repackageable custom extension development in Magento - Part 3 - Database (9)
- Howto: Repackageable custom extension development in Magento (8)
- Howto: Repackageable custom extension development in Magento - Part 5 - CRUD - Retrieve (6)
Recent Comments
- donald: Hi Wen, I have checked out
- donald: Hi Ashley, Currently, I simply use
- donald: Hi Noemi, there are many
- Serge: Thanks a lot. It's the simplest
- Zoran: Excellent posts you got here...
- Craig: Brilliant tutorial! There's NOTHING on
- Will: Thnak you! I was
- Margots: Thank you a lot for
- Aswin S: Wow great dude.. For the
- Noemi Heier: This is great! How did
Latest Entries
- jQuery Progress Bar Configuration
- Extracting email addresses from inbox
- 10 Good (Free and Legal) Source for Photos and Images
- Howto: Backup Microsoft SQL Server Database, as in Dump it to a SQL Script (like MYSQL's sqldump)
- Managing client's expectation with wireframe software
- Howto: Repackageable custom extension development in Magento - Part 9 - Frontend - List
- JQuery Progress Bar 2.0
- HOWTO: Find icons for your new prototype system
- Google Maps Helper
- laying the cornerstones