【问题标题】:Why does loading all stores for a website depend on what store is currently loaded?为什么加载网站的所有商店取决于当前加载的商店?
【发布时间】:2013-10-11 14:54:50
【问题描述】:

在 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 中的错误还是这种行为是有意的?有没有更好的方法来加载网站的商店?

【问题讨论】:

    标签: php magento


    【解决方案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. 由于对象是通过引用传递的,因此您最终在 Mage_Core_Model_App::_currentStore 管理存储中拥有。

    由于Mage_Core_Model_App 在脚本的其余部分中被实例化为单例,您将拥有管理存储作为当前存储。

    此外,在同一方法的末尾有以下几行:

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

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

    【讨论】:

    • 好的,我明白了。但无论如何,我觉得Mage::app()->getStores() 的结果可能取决于加载的商店有点奇怪。我并不总是对此有控制权,例如,在我尝试获取商店之前,有人可以在观察者中调用 Mage::app()->getStore()->load(1)
    • @JanWy 你不需要使用Mage::app()->getStore()->load(1)。只需使用$store = Mage::getModel('core/store')->load(1)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多