404 sur le commutateur de magasin avec la clé d'URL de portée du magasin de produits

13

Par défaut URL Key, la page du produit est de portée globale.

EDIT: Comme suggéré par FlorinelChis, la portée peut être des changements dans la gestion des attributs. Cependant, cela rompt le comportement du commutateur de vue de magasin.

Ceci a été testé sur 1.7.0.2 avec des exemples de données et "Ajouter le code de magasin à l'URL" activé :

  1. modifier un produit et définir une URL différente pour un magasin particulier (français)
  2. Réindexer
  3. Ouvrir la page du produit sur le site en vue boutique en anglais
  4. Passez en français: vous aurez l'URL de la page containg /French/
  5. Revenir à l'anglais -> erreur de page 404 (l'url manque le code de magasin /default/

    comment le faire fonctionner correctement avec la vue de magasin / le commutateur de langue?

Détails:

  • URL pour l'anglais: /default/sony-vaio-vgn-txn27n-b-11-1-notebook-pc.html
  • URL pour le français: /french/sony-vaio-vgn-txn27n-b-11-1-notebook-pc-french.html

Si je suis sur le site anglais sur cette page -> /default/sony-vaio-vgn-txn27n-b-11-1-notebook-pc.html

Je passe ensuite au français:

J'ai reçu cette URL ( le code du magasin est manquant ):
MAGEDOMAIN/sony-vaio-vgn-txn27n-b-11-1-notebook-pc-french.html

Donc, magento réécrit l'url correctement mais manque le code du magasin pour une raison quelconque

Référence:

Bien sûr, cela est lié à /core/model/store.phpet /core/model/url/rewrite.php, et en particulier à ces méthodes:

Mage_Core_Model_Url_Rewrite::rewrite
Mage_Core_Model_Store::getCurrentUrl

MISE À JOUR

Si vous êtes sur 1.9.1 @Vinai fix ne fonctionnera pas, vérifiez la nouvelle réponse que j'ai ajoutée

Fra
la source
quelle version de Magento utilisez-vous?
FlorinelChis
Magento 1.7.0.2
Fra
Tim Je teste actuellement une réponse et je les accepterai après avoir confirmé qu'ils fonctionnent.
partir de

Réponses:

12

Le problème est un bogue dans le modèle Mage_Core_Model_Url_Rewrite_Request(Magento 1.8) et Mage_Core_Model_Url_Rewrite(versions antérieures).

La section du code principal en 1.8 ressemble à ceci:

    // 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;
        }

Le bug: la valeur du paramètre de requête est le code du magasin, (dans mon cas de, enou fr). Les clés du tableau retourné par app->getStores()sont les ID de magasin numériques . C'est pourquoi if (!empty($stores[$fromStore])) {échoue toujours.

Une fois ce bogue corrigé, un autre bogue apparaît plus tard dans la même méthode (je pense seulement en 1.8):

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

L'URL de base des objets de requête est toujours l'URL de base Magento, sans le code de magasin. À la $currentStore->getBaseUrl()place, il corrige également ce bogue.

Une fois ces deux problèmes résolus, le sélecteur de langue fonctionne correctement. Voici une extension qui fait exactement cela pour Magento 1.8 (CE): https://github.com/Vinai/VinaiKopp_StoreUrlRewrites

Dans Magento 1.7, le problème pourrait être quelque chose de différent. Je pensais toujours que j'ajouterais cette réponse, juste au cas où Google amènerait quelqu'un d'autre ici qui exécute la version 1.8 ou plus récente.

Vinai
la source
pensez-vous que le correctif que j'ai mis en œuvre est sûr?
partir de
Pour être honnête, je n'ai pas cherché la cause du problème en 1.7. Implémenter un correctif sans comprendre exactement ce qui cause le comportement est toujours risqué.
Vinai
désolé de rouvrir cette discussion après 2 ans mais je suis à nouveau sur ce bug ... sur 1.9.1 le problème est avec la condition if $ this -> _ rewrite-> getId () ... essentiellement pour la deuxième vue de magasin magento manage pour charger une réécriture et donc il ne déclenche pas la redirection ... cependant cette réécriture a le mauvais id_path (l'id du produit est +1) donc il charge un 404
Fra
4

En fait, j'ai trouvé une solution de contournement pour ce problème sur Magento 1.7.0.2 si vous exécutez Magento 1.8 regarde l'explication détaillée de Vinai:

Il semble qu'une partie du problème est liée au contrôleur de demande Mage_Core_Controller_Request_Http.

Si vous regardez à la ligne 161, il y a cette condition:

                elseif ($storeCode !== '') {
                    $this->setActionName('noRoute');
                }

Commentant cela, corrigez l'erreur 404 lorsque je passe à un autre magasin dans une page de catégorie / produit.

Cependant, pour une raison inconnue, le code de magasin est manquant dans l'URL de réponse, mais cela ne pose plus de problème car les deux URL fonctionnent maintenant:

  • MAGEDOMAIN / sony-vaio-vgn-txn27n-b-11-1-notebook-pc-french.html
  • MAGEDOMAIN / sony-vaio-vgn-txn27n-b-11-1-notebook-pc.html

Il n'est pas encore clair pour moi si le commentaire de cette condition peut causer un autre problème

Fra
la source
Je peux également confirmer que cela fonctionne pour moi - chaque fois que je passe à une autre langue lors de la visualisation d'un produit, j'obtiens un 404. Cela le corrige et fait comme vous l'avez dit, omettre le code du magasin de l'URL, ce qui est étrange. Je ne peux pas imaginer que c'est la meilleure solution car éditer le contrôleur de base comme celui-ci ne peut pas être bon, je me demandais si vous aviez déjà trouvé une autre solution?
waffl
vous n'avez pas besoin de modifier un fichier principal, vous pouvez créer votre propre module et réécrire cette classe / méthode.
Fra
1
Mage_Core_Controller_Request_Httpne peut pas être réécrit dans un module.
benmarks
4

Quelques informations mises à jour pour Magento 1.9.1

Le bug signalé par @Vinai semble résolu de toute façon dans cette version pour une autre raison, la fonctionnalité est toujours cassée (pour les produits configurables)

Le vrai problème est probablement ici, Mage_Catalog_Model_Resource_Urlmais je n'ai pas le temps et je ne veux pas toucher une partie aussi délicate du noyau.

Explication d'une solution de contournement:

Le point d'entrée est toujours cette classe Mage_Core_Model_Url_Rewrite_Request et en particulier la méthode_rewriteDb()

Comment ça _rewriteDb()marche:

  1. D'abord, il essaie de charger la demande pour le magasin actuel

(139): $this->_rewrite->loadByRequestPath($requestCases);

  1. alors si je ne le trouve pas (pas d'id) et a un ___from_storeparamètre

(142): if (!$this->_rewrite->getId() && $fromStore) {

  1. essayez de charger une réécriture pour ___from_store:

(152): $this->_rewrite->setStoreId($fromStoreId)->loadByRequestPath($requestCases);

  1. s'il le trouve, il utilise le id_pathpour charger celui du magasin courant:

(159): $this->_rewrite->setStoreId($currentStore->getId())->loadByIdPath($this->_rewrite->getIdPath());

Tout semble bien mais il y a un problème dans les données url_rewrite et donc avec la fonctionnalité d'index (au moins pour les produits configurables):

  • même si nous changeons de magasin et que le nouveau magasin a une URL différente, une réécriture à la ligne 139 est chargée.

Le problème est que cette réécriture pointe vers le mauvais id_path(au lieu de pointer vers l'ID de produit configurable, elle pointe vers l'un de ses ID de produit simple)

Maintenant, une solution consiste à supprimer la !$this->_rewrite->getId()condition et donc magento essaie de trouver une redirection toujours quand il y a un $fromstoreparamètre

  • Le mieux serait de corriger l' catalog_urlindex et de supprimer la mauvaise réécriture qu'il crée.

Voici le code de la solution rapide (vous devrez créer un module et réécrire la Mage_Core_Model_Url_Rewrite_Requestclasse par vous-même):

protected function _rewriteDb()
    {
        if (null === $this->_rewrite->getStoreId() || false === $this->_rewrite->getStoreId()) {
            $this->_rewrite->setStoreId($this->_app->getStore()->getId());
        }

        $requestCases = $this->_getRequestCases();
        $fromStore = $this->_request->getQuery('___from_store');

        if ($fromStore) {
            $stores = $this->_app->getStores(false, true);
            if (!empty($stores[$fromStore])) {
                /** @var $store Mage_Core_Model_Store */
                $store = $stores[$fromStore];
                $fromStoreId = $store->getId();
            } else {
                return parent::_rewriteDb();
            }

            $this->_rewrite->setStoreId($fromStoreId)->loadByRequestPath($requestCases);
            if (!$this->_rewrite->getId()) {
                return parent::_rewriteDb();
            }

            // Load rewrite by id_path
            $currentStore = $this->_app->getStore();
            $this->_rewrite->setStoreId($currentStore->getId())->loadByIdPath($this->_rewrite->getIdPath());

            $this->_setStoreCodeCookie($currentStore->getCode());

            $targetUrl = $currentStore->getBaseUrl() . $this->_rewrite->getRequestPath();
            $this->_sendRedirectHeaders($targetUrl, true);
        }

        if (!$this->_rewrite->getId()) {
            return parent::_rewriteDb();
        }

        $this->_request->setAlias(Mage_Core_Model_Url_Rewrite::REWRITE_REQUEST_PATH_ALIAS,
            $this->_rewrite->getRequestPath());
        $this->_processRedirectOptions();

        return true;
    }
Fra
la source
3

La clé URL est un attribut. Vous pouvez le modifier à partir de: Catalogue -> Attributs -> Gérer les attributs . Recherchez url_key et cliquez dessus. Modifier l'attribut url_key

Modifiez la portée et enregistrez.

Vous pouvez maintenant avoir différentes clés URL pour les produits sur chaque vue de magasin.

FlorinelChis
la source
J'ai mis à jour la question, votre réponse est bonne mais cela ne fonctionne pas
Fra
lorsque vous changez de magasin, vous devez atterrir sur la page d'accueil de ce magasin et non sur la page du produit.
FlorinelChis
L'endroit où vous atterrissez est le même où vous commencez à partir de : si vous êtes sur une page de catégorie , vous devez atterrir sur la même page dans les différentes langues
Fra
1

Vous souhaitez donc modifier l'URL de chaque vue de magasin?

À l'heure actuelle, vous avez modifié l'URL du produit à l'échelle de score pour que votre magasin français soit différent de votre magasin anglais? Et lorsque vous basculez entre les deux, vous obtenez un 404. Ce serait un comportement attendu.

Magento ne stockera pas différentes réécritures d'URL pour les autres vues de magasin. Ainsi, lorsque vous accédez /french/product1au magasin français, l'URL correspondra dans le tableau et se chargera. Mais lorsque vous le frappez dans le magasin anglais, il n'y aura pas de correspondance et donc 404.

Il semble que vous ayez besoin de simplement "Ajouter des codes de magasin à l'URL" - ce qui laissera vos clés d'URL seules, mais préfixez toutes les URL respectives avec votre code de magasin. Cela devrait alors permettre à votre commutateur de magasin de fonctionner.

Ben Lessani - Sonassi
la source
1
comme confirmé par Vinai, c'est un bug
Fra