Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically changing Magento's adminhtml menu option

I am working on a "for fun" project that I hope to release as a "for fun" open source project. I've built an Arduino web-connected order notifier and I am building up the Magento adminhtml interface side of it. This might seem overly complicated for what I am doing, but this has other applications that are useful to me and I'm trying to learn something new.

With that said, I have create a new "Arduino" adminhtml menu item next to "Reports" in the Magento backend. There are certain times when particular feedback from the Arduino may automatically disable the module, in which case my goal is to remove the menu item from the page UNLESS there are other sub-menu items, in which case I only remove my module specific menu items. Again, this may not seem very realistic for this project but in an effort to do this as "right" as possible that is my goal, to leave the possibility open that somebody else could potentially add a "Arduino" menu item.

Now, I have this working GREAT, without issue, IF caching is turned off. Which is another way of saying, "this doesn't work because obviously everybody will have cache turned on." That said, here is the code I started with:

/**
 * Used to disable the Arduino menu option dynamically.
 *
 * @param Varient_Event_Observer $observer
 */
public function controllerActionLayoutGenerateBlocksBefore(Varien_Event_Observer $observer)
{
    //We only want to disable the arduino menu if our module was specifically disabled in backend
    if(Mage::helper('mynamespace_myarduinomodule')->isDisabled())
    {
        /* @var $arduinoItems Varien_Simplexml_Element */
        /* @var $parent Varien_Simplexml_Element */
        $arduinoItems = Mage::getSingleton('admin/config')->getAdminhtmlConfig()->getNode('menu/arduinomenu/children');
        $parent = Mage::getSingleton('admin/config')->getAdminhtmlConfig()->getNode('menu');

        //If there are other menu options in the arduino menu option we only want to hide
        //the menu items related to our specific module, leaving the top level menu item alone
        if($arduinoItems->children()->count() > 1)
        {
            $parent->setNode("arduino/children/myarduinomodule", "", true);
        }
        //But, if not, then we want to hide the entire arduino tab
        else
        {
            $parent->setNode("arduino", "", true);
        }
    }

    return $this;

}

This obviously adds some overhead, but it's only in the adminhtml section. Now, my goal is to have a "good" solution, but I'm not sure if there is one. I've read this very good blog post and while I think something like this might work for my purposes (in reverse), I would prefer to create a module that doesn't utilize class rewrites so that I don't need to be concerned with other modules rewriting the same class.

Does anybody have any advice on how I might approach this problem? Is the same caching an issue if I were to add my custom menu items to an existing "parent" menu item (for instance if I were to add my Arduino options below "System")?

Thank you for your time and this great resource!

EDIT:

  • logging in/back out seems to "fix" my existing problem and update the menu properly. I don't want to force a user to logout of course, but perhaps there may be a solution there somewhere?
like image 555
Kevin Mitchell Avatar asked Nov 13 '22 08:11

Kevin Mitchell


1 Answers

It seems that the only way to make it work is to clean menu cache everytime you make changes. You can do it using next code:

Mage::app()->getCache()->clean(
    Zend_Cache::CLEANING_MODE_MATCHING_TAG, array(Mage_Adminhtml_Block_Page_Menu::CACHE_TAGS)
);
like image 101
anon Avatar answered Dec 24 '22 02:12

anon