动态更改Magento的adminhtml菜单选项

5
我正在做一个“娱乐”项目,希望将其发布为“娱乐”开源项目。我已经构建了一个Arduino网络连接的订单通知器,并正在构建它的Magento adminhtml接口。这可能看起来过于复杂,但这有其他对我有用的应用程序,并且我正在尝试学习一些新东西。
说到这里,我在Magento后端“报告”旁边创建了一个新的“Arduino” adminhtml菜单项。在某些情况下,来自Arduino的特定反馈可能会自动禁用模块,在这种情况下,我的目标是从页面中删除菜单项,除非存在其他子菜单项,在这种情况下,我只删除我的模块特定的菜单项。再次说明,这对于此项目可能不太现实,但为了尽可能地做得“正确”,这是我的目标,留下可能让其他人添加“Arduino”菜单项的可能性。
现在,如果缓存关闭,这个功能运行得非常好,没有问题。这也就意味着,“这个功能不可用,因为显然每个人都会开启缓存”。话虽如此,以下是我开始使用的代码:
/**
 * 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;

}

这显然增加了一些开销,但仅限于 adminhtml 部分。现在,我的目标是拥有一个“好”的解决方案,但我不确定是否有这样的解决方案。我已经阅读了这篇非常好的博客文章,虽然我认为像这样的东西可能适合我的用途(反过来),但我更喜欢创建一个不使用类重写的模块,这样我就不需要考虑其他模块重写同一个类。
有人有任何关于我如何解决这个问题的建议吗?如果我将自定义菜单项添加到现有的“父”菜单项中(例如,如果我将我的 Arduino 选项添加到“系统”下面),同样的缓存是否会成为问题?
谢谢你花时间阅读和提供这么好的资源!
编辑:
登录/退出似乎可以“修复”我的现有问题并正确地更新菜单。当然我不想强迫用户退出,但也许那里有一个解决方案?

我开始认为我的解决方案可能适用于我的特定情况,我可以简单地将用户重定向回仪表板或显示适当的消息,如果他们尝试访问我的自定义后端页面/控制器。但我仍然希望在用户退出后端之前自动删除我的菜单选项。 - Kevin Mitchell
如果我没记错的话,你会这样做:假设你有许多扩展,你想将它们收集在一个菜单下,该菜单根据扩展可用。如果客户购买了一个扩展并安装了系统,则扩展选项应出现在菜单中。对吗?另外,你的问题具体是什么? - Oğuz Çelikdemir
如果您需要隐藏某些内容,我建议使用一些jQuery或Prototype动态隐藏元素。让页面查找数据库(或其他地方)中的字段,并从那里开始操作。 - CCBlackburn
你需要在缓存中打一个洞,这里有一篇不错的文章:https://dev59.com/Kl3Ua4cB1Zd3GeqP-Tni - Nick McCormack
请记住,您安装的大多数插件都会要求您注销并重新登录,以便反映所有更改,因此我想要求用户这样做也是可以的。 - Alex Siri
@CCBlackburn:你的链接是关于FPC的。这里似乎不是FPC问题,因为它在管理中不适用! - Alex
2个回答

1

看起来唯一让它工作的方法是每次更改后清除菜单缓存。您可以使用以下代码进行操作:

Mage::app()->getCache()->clean(
    Zend_Cache::CLEANING_MODE_MATCHING_TAG, array(Mage_Adminhtml_Block_Page_Menu::CACHE_TAGS)
);

0

如何在不留下菜单空白文本的情况下删除项目的代码示例:

/**
 * Used to disable the Arduino menu option dynamically.
 *
 * @param Varient_Event_Observer $observer
 */
public function controller_action_layout_render_before(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())
    {
    $_config = Mage::getSingleton('admin/config')->getAdminhtmlConfig()->getNode();


    if($_config->menu->arduino->children){
        unset($_config->menu->arduino->children->myarduinomodule);
    }else{
        // hide the tab altogether
        unset($_config->menu->arduino);
    }
    Mage::getSingleton('admin/config')->getAdminhtmlConfig()->setXml($_config);

    return $this;

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接