【问题标题】:Magento 404 error on language store specific URLs语言存储特定 URL 上的 Magento 404 错误
【发布时间】:2013-01-18 20:32:55
【问题描述】:

我有一个带有 2 个语言商店的 magento(企业)网站。每个给定项目或资源都有自己的专用 URL,无论是静态页面还是产品页面。

我通过 CMS 使用 URL 规则来管理我所有资源的 SEF URL。

问题出在以下场景:

  1. 站点默认为 LANG #1。

  2. 当用户从 LANG#1 切换到 LANG#2 时,切换没有问题 - 内容切换到特定语言 (_store=lang">http://www.sitename.com/?_store=lang)

  3. 但无论我在哪个语言商店,如果我将另一个语言商店的 url 输入到我当前的语言商店,我都会收到 404 错误。

我希望系统检查当前存储以获取所请求的资源。如果没有找到,它应该路由到下一个商店并检查那里的资源。如果找到,store 应该切换到找到该项目并重定向 url 的 lang store。

为了实现这一点,我应该扩展什么类(我对 magento 很陌生)。

我检查是否可以扩展这个类来做我想做的事:/app/code/core/Mage/Core/Model/Mysql4/Url/Rewrite.php

但不确定我是否处于满足此类要求的正确位置。

任何帮助将不胜感激!

谢谢

【问题讨论】:

    标签: magento


    【解决方案1】:

    我能够解决这个问题。我所做的只是扩展 /app/code/core/Mage/Core/Model/Mysql4/Url/Rewrite.php 文件。

    所以我重载了 loadByRequestPath 函数以在当前存储中为请求提供服务,如果未找到,则获取所有其他可用存储的列表,循环并查找该项目是否存在。如果找到,则重定向到产品和整个 URL 密钥所在的商店。

    如果没有商店有,则返回 404 错误。

    对于静态页面,当您切换商店/语言时,URL 重写管理器将能够为您解决问题。

    我希望这对某人有帮助!

    【讨论】:

    • 能否为您的 loadByRequestPath 函数添加循环代码?
    • 您是否愿意分享代码,因为我在同一 magento 安装中遇到了 5 家以上商店的类似问题。
    【解决方案2】:

    我不认为我的解决方案是最优雅的,但无论如何我都会发布它,因为它对我有用。 基本上我在所有商店中搜索我正在寻找的路径,而不仅仅是指定的商店。任何建议都会受到欢迎。

    我的 config.xml

    <?xml version="1.0"?>
    <config>
     <global>
      <modules>
        <Soipo_UrlRewrite>
            <version>0.1</version>
        </Soipo_UrlRewrite>
      </modules>
      <models>
        <soipo_urlrewrite>
            <class>Soipo_UrlRewrite_Model</class>
        </soipo_urlrewrite>
        <core_mysql4>
            <rewrite>
                <url_rewrite>Soipo_UrlRewrite_Model_Mage_Core_Model_Mysql4_Url_Rewrite</url_rewrite>
            </rewrite>
        </core_mysql4>
      </models>
     </global>
    </config>
    

    重写.php

    <?php
    class Soipo_UrlRewrite_Model_Mage_Core_Model_Mysql4_Url_Rewrite extends Mage_Core_Model_Mysql4_Url_Rewrite{
    
    /**
     * This function get an array of store ids, containing the Admin store.
     * @return array
     */
    public function getStoreIds(){
        $allStores = Mage::app()->getStores();
        $storeIds = array();
        $storeIds[] = Mage_Core_Model_App::ADMIN_STORE_ID;
        foreach ($allStores as $_eachStoreId => $val)
        {
            $_storeId = Mage::app()->getStore($_eachStoreId)->getId();
            $storeIds[] = $_storeId;
        }
        return $storeIds;
    }
    
    /**
     * Load rewrite information for request
     * If $path is array - we must load all possible records and choose one matching earlier record in array
     *
     * @param   Mage_Core_Model_Url_Rewrite $object
     * @param   array|string $path
     * @return  Mage_Core_Model_Resource_Url_Rewrite
     */
    public function loadByRequestPath(Mage_Core_Model_Url_Rewrite $object, $path)
    {
    
        if (!is_array($path)) {
            $path = array($path);
        }
    
        $pathBind = array();
        foreach ($path as $key => $url) {
            $pathBind['path' . $key] = $url;
        }
    
        $storeIds = $this->getStoreIds();
    
    
        // Form select
        $adapter = $this->_getReadAdapter();
        $select  = $adapter->select()
            ->from($this->getMainTable())
            ->where('request_path IN (:' . implode(', :', array_flip($pathBind)) . ')')
            ->where('store_id IN(?)', $storeIds);
    
        $items = $adapter->fetchAll($select, $pathBind);
    
    
        // Go through all found records and choose one with lowest penalty - earlier path in array, concrete store
        $mapPenalty = array_flip(array_values($path)); // we got mapping array(path => index), lower index - better
        $currentPenalty = null;
        $foundItem = null;
        foreach ($items as $item) {
            if (!array_key_exists($item['request_path'], $mapPenalty)) {
                continue;
            }
            $penalty = $mapPenalty[$item['request_path']] << 1 + ($item['store_id'] ? 0 : 1);
            if (!$foundItem || $currentPenalty > $penalty) {
                $foundItem = $item;
                $currentPenalty = $penalty;
                if (!$currentPenalty) {
    
                    break; // Found best matching item with zero penalty, no reason to continue
                }
            }
        }
    
        // Set data and finish loading
        if ($foundItem) {
            $object->setData($foundItem);
        }
    
        // Finish
        $this->unserializeFields($object);
        $this->_afterLoad($object);
    
        return $this;
    }
    
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-09
      • 1970-01-01
      • 2014-06-25
      • 1970-01-01
      • 2021-07-02
      • 1970-01-01
      相关资源
      最近更新 更多