2

I have created a custom product type extending from Mage_Catalog_Model_Product_Type_Abstract. What I would like to do is change this product's main controller class to use my own. If a user clicks the product on a product grid, cart line item, anywhere, I would like them to go to my_module/my_controller/my_action instead of some form of the generic catalog/product structure (catalog/product/view/id/5).

This would hold true as well for links such as the edit link on the cart page.

Best I can find, the only option I really see is to rewrite all the blocks that display these urls. It seems there should be a better way that I might just not be seeing. Also, using URL rewrites is not a good option as while it might be simple, I see lots of headaches down the road basing this on such a nebulous trick.

Is there a way to dictate which controllers/routers a product uses for various cart functions without having to do a massive amount of block/class rewrites?

3

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.)

  • So then, I assume the same thing would be repeated for every controller that exists that interacts with products. I will need to do the same for CategoryController, ConfigureController, WishlistController, SeoController, IndexController, etc .... So in the end it's not as simple as rewriting a single controller but instead rewriting many controllers with duplicate logic. sigh – pspahn May 1 '15 at 18:24
  • Well, not necessarily. It depends on what you're doing with the custom product type that requires a custom controller. A custom product view controller I can understand, but why a custom category controller, for example? Many of your examples are probably better off as template and/or layout XML changes. For example, you can show your custom product in a special way on a category page by overriding the catalog/product/list.phtml template. It all depends on what you're trying to do exactly. – Agop May 1 '15 at 18:31
  • And just to make sure we're on the same page, keep in mind that all of those controllers will generate standard product URLs of the form catalog/product/view/id/123 (or their rewritten versions). Your custom controller already overrides this standard URL form, so I don't see why you would need to override each controller with duplicate logic. – Agop May 1 '15 at 18:33
  • A previous question may provide some insight into what I am doing. The main reason is that I am creating a product type that is completely dynamic in nature. The price, image, description, options, etc will all be different depending on some seed values provided by the user. The product is essentially a single product that is custom built for every order. see: magento.stackexchange.com/questions/65254/… – pspahn May 1 '15 at 18:51
  • Interesting. I'll add some thoughts on your other question. As for this question, I believe that my answer is sufficient for the specific question at hand. – Agop May 1 '15 at 19:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.