Is there a way to dictate which controllers a product uses for various
cart functions without having to do a massive amount of block/class
rewrites?
Unfortunately, there isn't.
However, you could achieve this pretty easily by overriding the product controller (Mage_Catalog_ProductController
). In your custom viewAction
, check the product type - if it's your custom product type, call _forward('foo/bar/baz')
, and if it's not, then leave the default logic.
So, something like this:
Namespace/Foo/etc/config.xml
snippet:
<frontend>
<routers>
<catalog>
<args>
<modules>
<namespace_foo before="Mage_Catalog">Namespace_Foo</namespace_foo>
</modules>
</args>
</review>
</routers>
</frontend>
Namespace/Foo/controllers/BarController.php
snippet:
// controller classes are not autoloaded, so require the file manually
require_once Mage::getModuleDir('controllers', 'Mage_Catalog') . DS . 'ProductController.php';
class Namespace_Foo_BarController extends Mage_Catalog_ProductController
{
// override the view action
public function viewAction()
{
$productId = (int)$this->getRequest()->getParam('id');
$product = Mage::getModel('catalog/product')->load($productId);
if ($product->getId() && $product->getTypeId() === 'custom_foo_product')
{
// pass the product through the registry to avoid loading twice
Mage::register('foo_current_product', $product);
$this->_forward('foo/bar/baz');
}
else
{
// not a custom product, so just leave the regular logic
parent::viewAction();
}
}
function bazAction()
{
$product = Mage::registry('foo_current_product');
if (!$product)
{
// maybe the user got here directly instead of through catalog/product/view
// load the product manually via the id parameter
}
// do stuff with custom product
}
}
This also has the benefit of working fine with URL rewrites. So if there's a rewrite pointing my-custom-product.html
to catalog/product/view/id/60
, it'll still work. It's also easy to extend to other actions (like editAction
).
(Code written within the post and is therefore untested. But the idea is the same.)