Magento 1.7 – Fix 404 on Store Switch with Product Store View Scoped URL Key

catalogce-1.7.0.2languagestore-viewurl

By default URL Key on product page is Global scoped.

EDIT:
As suggested by FlorinelChis the scope can be changes in Manage attributes.
However this breaks the store view switcher behavior.

This is has been tested on 1.7.0.2 with samples data and "Add store code to URL" enabled:

  1. edit a product and set a different url for a particular storeview (french)
  2. Re-index
  3. Open product page on the site on english store view
  4. Switch to french: you will have the page URL containg /French/
  5. Switch back to english -> 404 page error ( the url miss the store code /default/

    how to make it work correctly with store view/language switch ?

Details:

  • URL for english : /default/sony-vaio-vgn-txn27n-b-11-1-notebook-pc.html
  • URL for french : /french/sony-vaio-vgn-txn27n-b-11-1-notebook-pc-french.html

If I'm on english site on this page -> /default/sony-vaio-vgn-txn27n-b-11-1-notebook-pc.html

Then I switch to french:

I got this URL (the store code is missed):
MAGEDOMAIN/sony-vaio-vgn-txn27n-b-11-1-notebook-pc-french.html

So magento re-write the url correctly but miss the store code for some reason

Reference:

For sure this is related to /core/model/store.php and /core/model/url/rewrite.php, and in particular to those methods:

Mage_Core_Model_Url_Rewrite::rewrite
Mage_Core_Model_Store::getCurrentUrl

UPDATE

If you are on 1.9.1 @Vinai fix will not work, check the new answer I have added

Best Answer

The problem is a bug in the model Mage_Core_Model_Url_Rewrite_Request (Magento 1.8) and Mage_Core_Model_Url_Rewrite (earlier versions).

The section of core code in 1.8 looks like this:

    // Section from Mage_Core_Model_Url_Rewrite_Request::_rewriteDb()

    $fromStore = $this->_request->getQuery('___from_store');
    if (!$this->_rewrite->getId() && $fromStore) {
        $stores = $this->_app->getStores();
        if (!empty($stores[$fromStore])) {
            $store = $stores[$fromStore];
            $fromStoreId = $store->getId();
        } else {
            return false;
        }

The Bug: the value of the query parameter is the store code, (in my case de, en or fr). The keys of the array returned by app->getStores() are the numeric store IDs. Thats why if (!empty($stores[$fromStore])) { always fails.

Once that bug is fixed, another bug becomes apparent later in the same method (I think only in 1.8):

$targetUrl = $this->_request->getBaseUrl() . '/' . $this->_rewrite->getRequestPath();

The request objects base url always is the Magento base_url, without the store code. Using $currentStore->getBaseUrl() instead there fixes that bug, too.

Once those two issues are fixed the language switcher works fine. Here is an extension which does exactly that for Magento 1.8 (CE): https://github.com/Vinai/VinaiKopp_StoreUrlRewrites

In Magento 1.7 the issue might be something different. I still thought I'd add this answer, just in case google brings somebody else here who is running 1.8 or newer.

Related Topic