为什么加载网站的所有商店取决于当前加载的商店?

时间:2013-10-11 14:54:51

标签: php magento

在Magento中,有几种方法可以加载一个或多个网站的所有商店。您可以执行Mage::app()->getStores(true)Mage::app()->getWebsites(),然后遍历生成的集合中的所有商店。这has already been answered here。我最近发现的是,在调用上述方法之前加载商店正在影响结果。特别是关于默认商店。例如:

设置:1个包含3家商店的网站(englishfrenchgerman,而german是默认商店)

Mage::app()->getStore()->load(0); // load admin store (or any other)
foreach (Mage::app()->getStores(true) as $store) {
    echo "\n" . $store->getId() . " - " . $store->getCode();
} 
result is: 
0 - admin
1 - english
3 - french

Mage::app()->getStore()->load(2); // load german store (default)
foreach (Mage::app()->getStores(true) as $store) {
    echo "\n" . $store->getId() . " - " . $store->getCode();
} 
result is: 
0 - admin
1 - english
3 - french
2 - german

当我浏览网站以获取它的商店时,甚至会发生更奇怪的事情。默认商店的值将替换为当前加载的商店的值:

Mage::app()->getStore()->load(0); // load admin store
foreach (Mage::app()->getWebsites() as $website) {
    foreach ($website->getStores() as $store) {
        echo "\n".$store->getId() . ' - ' . $store->getCode();
    }
}
result: 
1 - english
3 - french
0 - admin

in case of Mage::app()->getStore()->load(1) the result is:
1 - english
3 - french
1 - english

唯一正确的方法是让所有商店的网站独立于当前加载的商店,如下所示:

Mage::app()->getStore()->load($anyStoreId); // load any store
/** @var $websites Mage_Core_Model_Resource_Website_Collection */
$websites = Mage::getResourceModel('core/website_collection');
foreach ($websites as $website) {
    foreach ($website->getStores() as $store) {
        echo "\n".$store->getId() . ' - ' . $store->getCode();
    }
}
result is always:
1 - english
3 - french
2 - german

这些结果的原因是什么?这是Magento中的错误还是这种行为?是否有更好的方法来加载网站的商店?

1 个答案:

答案 0 :(得分:1)

看一下方法Mage_Core_Model_App::getStore() 它接受一个名为$id的参数,但如果为null,则返回当前存储:

if (!isset($id) || ''===$id || $id === true) {
     $id = $this->_currentStore;
}

现在......在模型上调用->load(),修改当前对象。 因此,当您致电Mage::app()->getStore()->load(0)时,它会产生以下影响:

  1. 您检索当前商店
  2. 您加载ID为0(admin)
  3. 的商店
  4. 由于对象是通过引用传递的,因此您最终拥有Mage_Core_Model_App::_currentStore管理存储。
  5. 由于Mage_Core_Model_App在脚本的其余部分被实例化为单例,因此您将管理存储作为当前存储。

    此外,在同一方法的最后还有以下几行:

    $this->_stores[$store->getStoreId()] = $store;
    $this->_stores[$store->getCode()] = $store;
    

    这会将getStore的结果缓存到成员变量中,这样您就不必再加载它了。调用_stores时会使用getStores() 结论。:调用Mage::getStore()->load()会对您的脚本造成很大伤害。在前端页面上调用此方法可能会导致访问某些管理方法(但不是控制器或操作)。要遍历商店和网站Mage::getResourceModel()方法。