2011-05-11 100 views
12

假设,我有3个商店。Magento:禁用任何特定商店的模块

我想禁用商店2.模块我只希望它在商店1和商店被启用3.

我知道我可以做到这一点: -

  • 展望到系统 - >配置 - >高级

  • 选择所需的商店从当前配置范围下拉列表。

但是这并不完全奏效。

而且,我也不想检查存储在模块代码本身或创建系统配置字段为模块检查/取消选中存储启用/禁用。

我期待的是在app/etc/modules/MyNamespace_MyModule.xml中添加一些代码。我们可以这样做吗?

回答

3

该配置只是禁用了前端布局中的模块输出,但模块控制器,事件观察器,管理页面等仍在工作。

而且不要忘了指定布局文件定义的模块名称,否则所有的布局文件的内容将被加载特定的商店:

<config> 
    <layout> 
     <module_alias module="Module_Name"> 
      <file>yourlayoutfile.xml</file> 
     </module_alias> 
    </layout> 
</config> 

如果你正在开发一个模块并要禁用在特定商店的完整功能上,你应该创建一个“Yes/No”类型的配置字段,并通过你的模块代码中的Mage :: getStoreConfigFlag('config/field/path')来检查它的值。

+0

我知道。我可以为商店启用创建系统配置字段。但是,我正在寻求仅在应用程序/ etc/modules目录中更改模块配置文件的答案。 – 2011-05-11 10:39:22

+0

@chapagain它不可能更改每个商店的应用程序/ etc/modules,它是全局配置。 – 2011-05-12 07:46:25

15

要禁止在商店范围的模块,我发现这是可以做到这样的:

移动应用程序/代码/核心/法师/核心/型号/ config.php文件到App /代码/本地/法师/核心/模型/ Config.php

内部Config.php找到方法“loadModulesConfiguration”不要改变任何东西,但添加下面的代码,使该方法看起来像这样。

public function loadModulesConfiguration($fileName, $mergeToObject = null, $mergeModel=null) 
{ 
    $disableLocalModules = !$this->_canUseLocalModules(); 

    if ($mergeToObject === null) { 
     $mergeToObject = clone $this->_prototype; 
     $mergeToObject->loadString('<config/>'); 
    } 
    if ($mergeModel === null) { 
     $mergeModel = clone $this->_prototype; 
    } 
    $modules = $this->getNode('modules')->children(); 
    foreach ($modules as $modName=>$module) { 
     if ($module->is('active')) { 
      // Begin additional code 
      if((bool)$module->restricted) { 
       $restricted = explode(',', (string)$module->restricted); 
       $runCode = (isset($_SERVER['MAGE_RUN_CODE']) ? $_SERVER['MAGE_RUN_CODE'] : 'default'); 
       if(in_array($runCode, $restricted)) { 
        continue; 
       } 
      } 
      // End additional code 
      if ($disableLocalModules && ('local' === (string)$module->codePool)) { 
       continue; 
      } 
      if (!is_array($fileName)) { 
       $fileName = array($fileName); 
      } 

      foreach ($fileName as $configFile) { 
       $configFile = $this->getModuleDir('etc', $modName).DS.$configFile; 
       if ($mergeModel->loadFile($configFile)) { 
        $mergeToObject->extend($mergeModel, true); 
       } 
      } 
     } 
    } 
    return $mergeToObject; 
} 

新的代码将导致该方法还检查限制>在模块xml文件的新节点,<。如果节点存在,则该值将是您不希望模块加载的逗号分隔的商店代码列表。如果您有多个商店,则应使用当前商店代码设置$ _SERVER变量“MAGE_RUN_CODE”。如果没有设置,那么脚本会后退到假设商店代码是“默认”,这是默认情况下,除非有一些奇怪的原因,您决定在后端更改它。

A模块XML文件,然后可以是这样的:

<?xml version="1.0"?> 
<config> 
    <modules> 
     <MyPackage_MyModule> 
      <active>false</active> 
      <restricted>mystore1,mystore4,mystore5</restricted> 
      <codePool>local</codePool> 
     </MyPackage_MyModule> 
    </modules> 
</config> 

这样,模块甚至不会加载,同时用mystore1,mystore4,或mystore5的商店代码商店。<受限制的>标记完全是可选的,如果您省略,模块将按照正常情况加载。

+0

谢谢,对我有用:) – Magefast 2013-11-11 13:14:06

+1

启用缓存时,此解决方案无法正常工作。请让我知道,如果你有任何其他解决方案来禁用模块和模块文件,如观察员和所有。 – Nits 2016-10-10 07:02:12

+0

@Nits:请在下面检查我的解决方案。它基于这一个,但我解决了这个缓存问题。适用于1.9.2.3。 – Deus777 2017-03-02 07:30:15

0
+2

请注意,[只有链接的答案](http://meta.stackoverflow.com/tags/link-only-answers/info)不鼓励,所以答案应该是搜索解决方案的终点(vs.而另一个引用的中途停留时间往往会随着时间推移而过时)。请考虑在此添加独立的摘要,并将链接保留为参考。 – kleopatra 2013-11-11 13:43:29

1

我的客户端上安装的Magento 1.8.1.0有打破另一个网站在一个多店设置菜单有问题的模块。由Eric Hainer发布的上述解决方案不适用于此安装,因此我稍微修改了它:

而不是使用$_SERVER['MAGE_RUN_CODE'],我使用$_SERVER['SERVER_NAME']。像魅力一样工作。 :)

所以不是:

$runCode = (isset($_SERVER['MAGE_RUN_CODE']) ? $_SERVER['MAGE_RUN_CODE'] : 'default'); 

使用:

$runCode = (isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : 'www.site1.com'); 

,而不是和:

<restricted>mystore1,mystore4,mystore5</restricted> 

使用:

<restricted>www.site2.com,www.site3.com</restricted> 

显然将您的位置更改为“www.site1.com”,“www.site2.com”和“www.site3.com”。

感谢这个想法Eric :)

2

我在使用Eric解决方案一段时间。在我的情况下,我禁用了某个模块,负责我店铺中的分层导航 - 因此返回默认的分层导航行为。

它看起来像它的工作,但过了一段时间,我发现分层导航选项停止出现在他们应该在的地方。不久,我注意到,实际上不应该在这家商店工作的模块继续工作。然后我意识到,当我禁用配置缓存埃里克的解决方案的作品,但后启用它再次停止。

经过一段时间,我意识到它必须以这种方式工作,启用配置缓存,因为Eric的解决方案仅在生成此xml时在全局xml中包含(或不)指定配置文件。然后将其缓存并仅从缓存中调用。所以当它从应该使用某个模块的站点生成时,它被包含在内,然后在没有使用它的站点上使用。

无论如何,我制定了另一个解决方案,基于埃里克的代码(使用限制在模块配置)。我认为Magento应该决定在请求课程时加载什么内容。然后它可以检查当前的MAGE_RUN_CODE并动态使用它。

有一个在Mage_Core_Model_Config的方法,其负责获取类名:getGroupedClassName

这里是我以前没有的代码:

if (strpos($className, 'Pneumatig_') !== false) { 
    $var = substr($className, 0, strpos($className, '_', strpos($className, '_') + 1)); 
    if (isset($this->_xml->modules->$var)) { 
     if ((bool)$this->_xml->modules->$var->restricted === true) { 
      $code = isset($_SERVER['MAGE_RUN_CODE']) ? $_SERVER['MAGE_RUN_CODE'] : 'default'; 
      if (strpos((string)$this->_xml->modules->$var->restricted, $code) !== false) { 
       $className = ''; 
      } 
     } 
    } 
} 

Pneumatig条件,因为我所有的模块从公司名称开始,所以我想避免没有必要的处理,但其可选的,代码应该没有它的工作,或者您可以将其更改为其他任何内容。

然后我得到实际模块名[公司] _ [模块],然后检查其在_xml(这是当前配置对象)运行。如果它受到限制,我清除$ className所以它强制Magento在下一行加载默认值。

而这种代码添加之前是空的条件:

// Second - if entity is not rewritten then use class prefix to form class name 
    if (empty($className)) { 
     if (!empty($config)) { 
      $className = $config->getClassName(); 
     } 
     if (empty($className)) { 
      $className = 'mage_'.$group.'_'.$groupType; 
     } 
     if (!empty($class)) { 
      $className .= '_'.$class; 
     } 
     $className = uc_words($className); 
    } 

    $this->_classNameCache[$groupRootNode][$group][$class] = $className; 
    return $className; 

并为您提供便利贴我整个getGroupedClassName代码:

public function getGroupedClassName($groupType, $classId, $groupRootNode=null) 
{ 
    if (empty($groupRootNode)) { 
     $groupRootNode = 'global/'.$groupType.'s'; 
    } 

    $classArr = explode('/', trim($classId)); 
    $group = $classArr[0]; 
    $class = !empty($classArr[1]) ? $classArr[1] : null; 

    if (isset($this->_classNameCache[$groupRootNode][$group][$class])) { 
     return $this->_classNameCache[$groupRootNode][$group][$class]; 
    } 

    $config = $this->_xml->global->{$groupType.'s'}->{$group}; 

    // First - check maybe the entity class was rewritten 
    $className = null; 
    if (isset($config->rewrite->$class)) { 
     $className = (string)$config->rewrite->$class; 
    } else { 
     /** 
     * Backwards compatibility for pre-MMDB extensions. 
     * In MMDB release resource nodes <..._mysql4> were renamed to <..._resource>. So <deprecatedNode> is left 
     * to keep name of previously used nodes, that still may be used by non-updated extensions. 
     */ 
     if (isset($config->deprecatedNode)) { 
      $deprecatedNode = $config->deprecatedNode; 
      $configOld = $this->_xml->global->{$groupType.'s'}->$deprecatedNode; 
      if (isset($configOld->rewrite->$class)) { 
       $className = (string) $configOld->rewrite->$class; 
      } 
     } 
    } 

    //START CHECKING IF CLASS MODULE IS ENABLED 
    if (strpos($className, 'Pneumatig_') !== false) { 
     $var = substr($className, 0, strpos($className, '_', strpos($className, '_') + 1)); 
     if (isset($this->_xml->modules->$var)) { 
      if ((bool)$this->_xml->modules->$var->restricted === true) { 
       $code = isset($_SERVER['MAGE_RUN_CODE']) ? $_SERVER['MAGE_RUN_CODE'] : 'default'; 
       if (strpos((string)$this->_xml->modules->$var->restricted, $code) !== false) { 
        $className = ''; 
       } 
      } 
     } 
    } 
    //END CHECKING IF CLASS MODULE IS ENABLED 

    // Second - if entity is not rewritten then use class prefix to form class name 
    if (empty($className)) { 
     if (!empty($config)) { 
      $className = $config->getClassName(); 
     } 
     if (empty($className)) { 
      $className = 'mage_'.$group.'_'.$groupType; 
     } 
     if (!empty($class)) { 
      $className .= '_'.$class; 
     } 
     $className = uc_words($className); 
    } 

    $this->_classNameCache[$groupRootNode][$group][$class] = $className; 
    return $className; 
}