Howto: Repackageable custom extension development in Magento – Part 9 – Frontend – List
Author: gaweee | Filed under: development, howtoFrontend – List
Let us revisit our frontend controller. Surely by now you’ve gotten a better grasp of the controller and models. So we’ll be revisiting those concepts here. So lets say you want to allow users to view you current Twits as well as create a new Tip.
- Some new file structure loving
app/ design/ frontend/ base/ default/ template/ twits/ - tip_list.phtml 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 - Edit.php Edit/ - Form.php - New.php New/ - Form.php - HelloWorld.php - Index.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.phpWe’ve added a whole nasty branch of subdirectories under
app/designs. Read on to understand what its all for… - Let us return to our
IndexController.php<?php class SavantDegrees_Twits_IndexController extends Mage_Core_Controller_Front_Action { public function indexAction() { $this->loadLayout(); $this->getLayout()->getBlock('content')->append( $this->getLayout()->createBlock('twits/index') ); $this->renderLayout(); } }
Hold your horses, this code is EXACTLY the same as the Part 1. Its just a revision. However, that being said, we see that in Part 1, we made the system create a
Blockcalledindex. That’s an opening… - So let us modify our
Index.phpblock:<?php class SavantDegrees_Twits_Block_Index extends Mage_Core_Block_Template { public function __construct() { parent::__construct(); $this->setTemplate('twits/tip_list.phtml'); } public function getTips() { $model = Mage::getModel('twits/tip'); $collection = $model ->getCollection() ->load(); return $collection->getItems(); } }
What the difference here? We made the block load the template from
twits/tip_list.phtml. We can create/find this file in/app/design/frontend/default/default/template/twits/tip_list.phtml. Some explanation is due here:- When you say
setTemplatein the block, it means, use this file as the presentation/view - This file exists in the some subdirectory of
/app/design/frontend/default/default/template. That is the path to your default template. Even though you may have other templates, this is the default 1. So when Magento cant find your template file in the other template directories, it always reverts back to this folder. Its a directory form of inheritance/ancestory/precedence.
- When you say
- Lastly, the
tip_list.phtmlfile:<?php $_tips = $this->getTips(); if ($_tips) { $count = 0; foreach ($_tips as $i=>$tip) { ?> <div class="tip"> <div class='title'><?= $tip->getTitle() ?></div> <div class='author'><?= $tip->getAuthor() ?></div> <p><?= $tip->getContents() ?></p> </div> <?php } } ?>Since the whole purpose of
tip_list.phtmlis to prepare the view for the list of tips, it obviously needs to get the data from somewhere. It turns out, theTemplateis the extension of theBlock. So by calling$this->getTips(), we’re calling theBlock'sgetTips()method. - There you have it! check your tips list at http://127.0.0.1/magento/index.php/twits
If it works for you, leave a comment! =)
Howto: Repackageable custom extension development in Magento – Part 8 – CRUD – Update
Author: gaweee | Filed under: development, howtoCRUD – Update
Very similar to the Create phase, this phase basically requires the Form and Form Container blocks, and the controller to save them. Thats all!
- Repeat the 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 - Edit.php Edit/ - Form.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.phpHere we’ve added the block for the
Editcontainer andForm - Looking at the
Edit.phpcode:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
<?php class SavantDegrees_Twits_Block_Admin_Edit extends Mage_Adminhtml_Block_Widget_Form_Container { public function __construct() { parent::__construct(); $this->_blockGroup = 'twits'; $this->_mode = 'edit'; $this->_controller = 'admin'; if( $this->getRequest()->getParam($this->_objectId) ) { $tip = Mage::getModel('twits/tip') ->load($this->getRequest()->getParam($this->_objectId)); Mage::register('frozen_tip', $tip); } } public function getHeaderText() { return Mage::helper('twits')->__("Edit Tip'%s'", $this->htmlEscape(Mage::registry('frozen_tip')->getName())); } }
The additional code loads the right
Tipdata based on theRequestparameter, then stores that data in theMageregistry. We’ll be using that data on theFormpage again later to populate the form.
Notice that the saving code isMage::registerand the retrieving code isMage::registry - Then the accompanying
Edit/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 42
<?php class SavantDegrees_Twits_Block_Admin_Edit_Form extends Mage_Adminhtml_Block_Widget_Form { protected function _prepareForm() { $form = new Varien_Data_Form(); $fieldset = $form->addFieldset('edit_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('*/*/save')); $form->setValues(Mage::registry('frozen_tip')->getData()); $this->setForm($form); } }
-
Then lastly the
adminControllerwith itseditActionandsaveActionto 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 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
<?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 successfully saved')); $this->getResponse()->setRedirect($this->getUrl('*/*/')); return; } catch (Exception $e){ Mage::getSingleton('adminhtml/session')->addError($e->getMessage()); } } $this->getResponse()->setRedirect($this->getUrl('*/*/')); return; } public function editAction() { $this->loadLayout(); $this->_addContent($this->getLayout()->createBlock('twits/admin_edit')); $this->renderLayout(); } public function saveAction() { $tipId = $this->getRequest()->getParam('id', false); if ($data = $this->getRequest()->getPost()) { $tip = Mage::getModel('twits/tip')->load($tipId)->addData($data); try { $tip ->setId($tipId)->save(); Mage::getSingleton('adminhtml/session')->addSuccess(Mage::helper('twits')->__('Tip successfully saved')); $this->getResponse()->setRedirect($this->getUrl('*/*/')); return; } catch (Exception $e){ Mage::getSingleton('adminhtml/session')->addError($e->getMessage()); } } $this->_redirectReferer(); } }
-
Ok i admit the code is a tad inefficient. We have 2 separate functions that both does save. In fact,
postActionandsaveActiononly differ that saveAction loads the right record via the->load($tipId)function. Thats separates aCREATEfrom anUPDATErequest.And we’re finally finally finally done! To test out the edit function, simply click on any row from the
Grid! Thats assuming of course that you actually have some data.
» For frontend stuff, carry on … Fontend – List
Otherwise, if it works for you, leave a comment! =)
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) 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.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_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'); } }
- 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_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.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
<?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; } }
-
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 Tip” button from the
Grid!
» Just 1 more … CRUD – Update
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_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(); } }
» Almost there … CRUD – Create
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) Twits/ (Or whatever your module name might be) Block/ Admin/ - Main.php Main/ - Grid.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.phpWe’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_Twits_Block_Admin_Main extends Mage_Adminhtml_Block_Widget_Grid_Container { public function __construct() { $this->_addButtonLabel = Mage::helper('twits')->__('Add New Tip'); parent::__construct(); $this->_blockGroup = 'twits'; $this->_controller = 'admin_main'; $this->_headerText = Mage::helper('twits')->__('Tips(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_Twits_Block_Admin_Main_Grid extends Mage_Adminhtml_Block_Widget_Grid { public function __construct() { parent::__construct(); $this->setId('tipsGrid'); $this->_controller = 'twits'; } protected function _prepareCollection() { $model = Mage::getModel('twits/tip'); $collection = $model->getCollection(); $this->setCollection($collection); return parent::_prepareCollection(); } protected function _prepareColumns() { $this->addColumn('tip_id', array( 'header' => Mage::helper('twits')->__('ID'), 'align' => 'right', 'width' => '50px', 'filter_index' => 'dt.tip_id', 'index' => 'tip_id', )); $this->addColumn('name', array( 'header' => Mage::helper('twits')->__('Title'), 'align' => 'left', 'width' => '150px', 'filter_index' => 'dt.title', 'index' => 'title', 'type' => 'text', 'truncate' => 50, 'escape' => true, )); $this->addColumn('tags', array( 'header' => Mage::helper('twits')->__('Author'), 'align' => 'left', 'filter_index' => 'dt.author', 'index' => 'author', 'type' => 'text', 'escape' => true, )); $this->addColumn('summary', array( 'header' => Mage::helper('twits')->__('Contents'), 'align' => 'left', 'filter_index' => 'dt.contents', 'index' => 'contents', 'type' => 'text', 'escape' => false, )); $this->addColumn('action', array( 'header' => Mage::helper('twits')->__('Action'), 'width' => '150px', 'type' => 'action', 'getter' => 'getTipId', 'actions' => array( array( 'caption' => Mage::helper('twits')->__('Edit'), 'url' => array( 'base'=>'*/*/edit' ), 'field' => 'id' ), array( 'caption' => Mage::helper('twits')->__('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->getTipId(), )); } }
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_Twits_AdminController extends Mage_Adminhtml_Controller_Action { public function indexAction() { $this->loadLayout() ->_addContent($this->getLayout()->createBlock('twits/admin_main')) ->renderLayout(); } }
Well it says
createBlockdoesnt it? What do you think it does?twits/admin_mainas always refers to the twits namespace and theadmin/main.phpblock file. - Viola! Your very very very hard earned grid!
» Anytime now … Part 6 – CRUD – Delete
Howto: Repackageable custom extension development in Magento – Part 4 – Model
Author: gaweee | Filed under: development, howtoPrepare the model
- Back to the file structure drawing board
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/ - 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.phpNotice the new folder
Modeland the associated files inside. Lets clarify:
Model/Tip.phpis the logical model that holds code regarding business logic and relations.
Model/Mysql4/Tip.phpis the data implementation model that associates the model with the table and its primary key.
Model/Mysql4/Tip/Collection.phpis the data implementation model of a collection ofTip. Similar to arecordset/resultsetin.Net/Java. This will be used with a Grid later. - Even more
config.xmlmagic. Yay! More hairloss!<?xml version="1.0"?> <config> <modules> <SavantDegrees_Twits> <version>0.2.0</version> </SavantDegrees_Twits> </modules> <global> <models> <twits> <class>SavantDegrees_Twits_Model</class> <resourceModel>twits_mysql4</resourceModel> </twits> <twits_mysql4> <class>SavantDegrees_Twits_Model_Mysql4</class> <entities> <tip> <table>tips</table> </tip> </entities> </twits_mysql4> </models> <blocks> <twits> <class>SavantDegrees_Twits_Block</class> </twits> </blocks> <helpers> <twits><class>SavantDegrees_Twits_Helper</class></twits> </helpers> <resources> <twits_setup> <setup> <module>SavantDegrees_Twits</module> </setup> <connection> <use>core_setup</use> </connection> </twits_setup> <twits_write> <connection> <use>core_write</use> </connection> </twits_write> <twits_read> <connection> <use>core_read</use> </connection> </twits_read> </resources> </global> <adminhtml> <menu> <twits translate="title" module="twits"> <title>Twits</title> <sort_order>100</sort_order> <action>twits/admin</action> </twits> </menu> </adminhtml> <frontend> <routers> <SavantDegrees_Twits> <use>standard</use> <args> <module>SavantDegrees_Twits</module> <frontName>twits</frontName> </args> </SavantDegrees_Twits> </routers> </frontend> </config>
The
global > modelsfragment define thetipstable, thetip modeland itsresourceModelthat we will be using shortly. - Now for the
model/Tip.phpcode:<?php class SavantDegrees_Twits_Model_Tip extends Mage_Core_Model_Abstract { protected function _construct() { $this->_init('twits/tip'); } }
Whats the point you ask!? The code does nothing but binds the model to the Twits namespace under the model twits. In Java that line would have been
package Twits;. *i assume/think/foretold*
(quickly moving on…) - Then
Model/Mysql4/Tip.php<?php class SavantDegrees_Twits_Model_Mysql4_Tip extends Mage_Core_Model_Mysql4_Abstract { protected function _construct() { $this->_init('twits/tip', 'tip_id'); } }
The code above tells Magento to hunt for the twits application’s twits table in the configuration. Yes i know the names are confusing now. Lets say instead of
twits/tipit istwits/foo. In that case the system will find the configuration file associated with twits (which is our app/code/local/SavantDegrees/Twits/etc/config.xml), and look underconfig > global > models > twits_mysql4 > entities > footo figure out its configuration instructions. You’ll see next that we’ll request for the table from that same configuration file. Capiche?
As aresourceModel, the code binds the model to a underlyingMysql4 table. - Lastly,
Model/Mysql4/Tip/Collection.php<?php class SavantDegrees_Twits_Model_Mysql4_Tip_Collection extends Varien_Data_Collection_Db { protected $_tipTable; public function __construct() { $resources = Mage::getSingleton('core/resource'); parent::__construct($resources->getConnection('twits_read')); $this->_tipTable= $resources->getTableName('twits/tip'); $this->_select->from( array('tip'=>$this->_tipTable), array('*') ); $this->setItemObjectClass(Mage::getConfig()->getModelClassName('twits/tip')); } }
Basically the model files created at this phase are simply trying to tie the model (singular and collection) to the underlying
Mysql resource. The entire mechanism is half tied in theconfig.xmltable declaration, the model individual instructions (from identifying the namespace to actually declaring the primary key of the table) - Viola. Models are ready
» Arent we there yet? Part 5 – CRUD – Retrieve
