In a recent project, I had to deal with creating a suite of modules in Magento (a module that contains other modules). After several searches on Google, I realised that nobody had created a proper solution for this - I was looking to create the following module structure:
app/code/local/Company/SuiteModule app/code/local/Company/SuiteModule/Core app/code/local/Company/SuiteModule/OtherModule
After setting up the above structure, I started testing whether Blocks, Helpers and Models could be instantiated correctly by Magento Factory methods, and I also tested setting up resources for each module to ensure that they would install correctly.
The following structure would work perfectly in Magento without any modification:
app/code/local/Company/SuiteModule app/code/local/Company/SuiteModule/etc app/code/local/Company/SuiteModule/Helper app/code/local/Company/SuiteModule/Model app/code/local/Company/SuiteModule/Core app/code/local/Company/SuiteModule/Core/etc app/code/local/Company/SuiteModule/Core/Block app/code/local/Company/SuiteModule/Core/Helper app/code/local/Company/SuiteModule/Core/Model app/code/local/Company/SuiteModule/OtherModule app/code/local/Company/SuiteModule/OtherModule/etc app/code/local/Company/SuiteModule/OtherModule/Block app/code/local/Company/SuiteModule/OtherModule/Helper app/code/local/Company/SuiteModule/OtherModule/Model
Magento Factory methods would look as follows:
Mage::helper('suitemodule');
Mage::getModel('suitemodule/model');
Mage::helper('suitemodule_core');
Mage::getModel('suitemodule_core/model');
Mage::helper('suitemodule_othermodule');
Mage::getModel('suitemodule_othermodule/model');
The problems with such a module structure started when I tried adding controllers to nested Modules. Magento could not correctly route the request to the correct controller. This sent me back on Google big time!!!
After a bit of searching I found a post on the Magento Forum that put me in the right direction...Read post here.
I had to find a way to have my own implementation of getControllerFileName method defined in Mage_Core_Controller_Varien_Router_Standard class. After a bit of thinking I decided that creating custom routers for the suite of modules would have allowed me to implement getControllerFileName as I needed.
I didn't want the new router's classes encapsulated in the suite though, as projects with similar requirements could come up. Because I was not overriding any already defined Magento class, I thought the best way would be to put the new routers in local/Mage/Core namespace (extending like this Mage Core codebase).
I added app/code/local/Mage directory and defined the following:
app/code/local/Mage/Core/Controller/Varien/Router/Suite.php app/code/local/Mage/Core/Controller/Varien/Router/Suiteadmin.php
In app/code/local/Mage/Core/Controller/Varien/Router/Suite.php I defined getControllerFileName method as follow:
public function getControllerFileName($realModule, $controller)
{
$parts = explode('_', $realModule);
$realModule = implode('_', array_splice($parts, 0, 3));
$file = Mage::getModuleDir('controllers', $realModule);
if (count($parts)) {
$file .= DS . implode(DS, $parts);
}
$file .= DS.uc_words($controller, DS).'Controller.php';
return $file;
}
All I did in the above method was change the following line:
$realModule = implode('_', array_splice($parts, 0, 2));
to:
$realModule = implode('_', array_splice($parts, 0, 3));
The final step was to edit config.xml for my suite modules and set them to use the suite routers instead of Magento Standard/Admin ones.
Firstly, I had to register the router in 'default/web' config area:
<default>
<web>
<routers>
<suiteadmin>
<area>admin</area>
<class>Mage_Core_Controller_Varien_Router_Suiteadmin</class>
</suiteadmin>
<suite>
<area>frontend</area>
<class>Mage_Core_Controller_Varien_Router_Suite</class>
</suite>
</routers>
</web>
</default>
And then to specify routers for frontend and admin config area:
<frontend>
<routers>
<othermodule>
<use>suite</use>
<args>
<module>GPMD_SuiteModule_OtherModule</module>
<frontName>othermodule</frontName>
</args>
</othermodule>
</routers>
</frontend>
<admin>
<routers>
<othermodule>
<use>suiteadmin</use>
<args>
<module>GPMD_SuiteModule_OtherModule</module>
<frontName>othermodule</frontName>
</args>
</othermodule>
</routers>
</admin>
That's it!!!
Comments
No one has commented on this page yet.
Post your comment