404 en el conmutador de tienda con clave de URL de alcance de vista de tienda de producto

13

De forma predeterminada, URL Keyla página del producto tiene un alcance global.

EDITAR: Según lo sugerido por FlorinelChis, el alcance puede ser cambios en Administrar atributos. Sin embargo, esto rompe el comportamiento del conmutador de vista de la tienda.

Esto se ha probado en 1.7.0.2 con datos de muestras y "Agregar código de tienda a URL" habilitado :

  1. editar un producto y establecer una url diferente para una tienda en particular (francés)
  2. Re-indexar
  3. Abra la página del producto en el sitio en la vista de la tienda en inglés
  4. Cambie a francés: tendrá la URL de la página que contiene /French/
  5. Vuelva al inglés -> error de página 404 (la URL pierde el código de la tienda /default/

    ¿Cómo hacer que funcione correctamente con la vista de tienda / cambio de idioma?

Detalles:

  • URL para inglés: /default/sony-vaio-vgn-txn27n-b-11-1-notebook-pc.html
  • URL para francés: /french/sony-vaio-vgn-txn27n-b-11-1-notebook-pc-french.html

Si estoy en el sitio de inglés en esta página -> /default/sony-vaio-vgn-txn27n-b-11-1-notebook-pc.html

Luego cambio al francés:

Obtuve esta URL ( se pierde el código de la tienda ):
MAGEDOMAIN/sony-vaio-vgn-txn27n-b-11-1-notebook-pc-french.html

Entonces, Magento reescribió la URL correctamente, pero por alguna razón perdió el código de la tienda

Referencia:

Por supuesto, esto está relacionado con /core/model/store.phpy /core/model/url/rewrite.php, y en particular con esos métodos:

Mage_Core_Model_Url_Rewrite::rewrite
Mage_Core_Model_Store::getCurrentUrl

ACTUALIZAR

Si está en 1.9.1 @Vinai, la corrección no funcionará, verifique la nueva respuesta que he agregado

Fra
fuente
¿Qué versión de Magento estás usando?
FlorinelChis
Magento 1.7.0.2
Fra
Tim, estoy probando algunas respuestas y las aceptaré después de confirmar que están funcionando.
Fra

Respuestas:

12

El problema es un error en el modelo Mage_Core_Model_Url_Rewrite_Request(Magento 1.8) y Mage_Core_Model_Url_Rewrite(versiones anteriores).

La sección del código central en 1.8 se ve así:

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

El error: el valor del parámetro de consulta es el código de la tienda, (en mi caso de, eno fr). Las claves de la matriz devueltas app->getStores()son los identificadores numéricos de la tienda. Por eso if (!empty($stores[$fromStore])) {siempre falla.

Una vez que se corrige ese error, otro error se vuelve aparente más adelante en el mismo método (creo que solo en 1.8):

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

La url base de los objetos de solicitud siempre es Magento base_url, sin el código de la tienda. Usando en su $currentStore->getBaseUrl()lugar, también corrige ese error.

Una vez que se solucionan esos dos problemas, el conmutador de idiomas funciona bien. Aquí hay una extensión que hace exactamente eso para Magento 1.8 (CE): https://github.com/Vinai/VinaiKopp_StoreUrlRewrites

En Magento 1.7, el problema podría ser algo diferente. Todavía pensé que agregaría esta respuesta, en caso de que Google traiga a alguien más que esté ejecutando 1.8 o más reciente.

Vinaí
fuente
¿Crees que la solución que he implementado es segura?
Fra
Para ser sincero, no he investigado la causa del problema en 1.7. Implementar una solución sin comprender exactamente qué está causando el comportamiento siempre es arriesgado.
Vinai
lo siento, reabrí esta discusión después de 2 años, pero estoy nuevamente en este error ... en 1.9.1 el problema es con la condición if $ this -> _ rewrite-> getId () ... básicamente para la segunda vista de la tienda magento manage cargar una reescritura y, por lo tanto, no desencadena la redirección ... sin embargo, esta reescritura tiene la ruta de acceso incorrecta (la identificación del producto es +1), por lo que carga un 404
Fra
4

En realidad, encontré una solución para este problema en Magento 1.7.0.2 si está ejecutando Magento 1.8 mira a la explicación detallada de Vinai:

Parece que parte del problema está relacionado con el controlador de solicitud Mage_Core_Controller_Request_Http.

Si observa la línea 161, existe esta condición:

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

Al comentarlo, corrijo el error 404 cuando cambio a una tienda diferente en una categoría / páginas de productos.

Sin embargo, por alguna razón desconocida, en algún momento se pierde el código de la tienda en la Url de respuesta, pero esto ya no causa problemas ya que ambas url funcionan ahora:

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

Todavía no me queda claro si el comentario de esta condición puede causar otro problema

Fra
fuente
Puedo confirmar que esto también funciona para mí: cada vez que cambio a otro idioma cuando veo un producto, obtengo un 404. Esto lo corrigió y, como dijiste, omite el código de la tienda de la URL, lo cual es extraño. No puedo imaginar que esta sea la mejor solución ya que editar el controlador central de esta manera no puede ser bueno, me preguntaba si alguna vez terminaste encontrando otra solución.
waffl
no necesita editar ningún archivo principal, puede crear su propio módulo y reescribir esa clase / método.
Fra
1
Mage_Core_Controller_Request_Httpno se puede reescribir en un módulo.
Benmarks
4

Alguna información actualizada para Magento 1.9.1

El error que @Vinai señaló parece estar resuelto en esta versión de todos modos por otra razón, la funcionalidad aún está rota (para productos configurables)

El problema real probablemente esté aquí, Mage_Catalog_Model_Resource_Urlsin embargo, no tengo tiempo y no quiero tocar una parte tan delicada del núcleo.

Explicación para una solución alternativa:

El punto de entrada es siempre esta clase Mage_Core_Model_Url_Rewrite_Request y, en particular, el método_rewriteDb()

Cómo _rewriteDb()funciona:

  1. Primero intenta cargar la solicitud para la tienda actual

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

  1. entonces si no puedo encontrarlo (sin id) y tiene un ___from_storeparámetro

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

  1. intente cargar una reescritura para ___from_store:

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

  1. si lo encuentra, use el id_pathpara cargar el de la tienda actual:

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

Todo se ve bien, sin embargo, hay un problema en los datos de url_rewrite y, por lo tanto, con la funcionalidad de índice (al menos para productos configurables):

  • incluso si estamos cambiando de tienda y la nueva tienda tiene una URL diferente, se carga una reescritura en la línea 139.

El problema es que esta reescritura apunta al error id_path(en lugar de apuntar a la identificación del producto configurable, apunta a una de su identificación de producto simple)

Ahora, una solución es eliminar la !$this->_rewrite->getId()condición y, por lo tanto, magento intenta encontrar una redirección siempre que haya un $fromstoreparámetro

  • Lo mejor sería arreglar el catalog_urlíndice y eliminar la reescritura incorrecta que crea.

Aquí el código para la solución rápida (necesitará crear un módulo y reescribir la Mage_Core_Model_Url_Rewrite_Requestclase usted mismo):

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
fuente
3

La clave de URL es un atributo. Puede editarlo desde: Catálogo -> Atributos -> Administrar atributos . Buscar url_key y haga clic en él. Editar atributo url_key

Cambiar el alcance y guardar.

Ahora puede tener diferentes claves de URL para productos en cada vista de la tienda.

FlorinelChis
fuente
He actualizado la pregunta, su respuesta es buena pero no funciona
Fra
cuando cambia de tienda, debe aterrizar en la página de inicio de esa tienda, no en la página del producto.
FlorinelChis
El lugar donde aterrizas es el mismo desde donde comienzas: si estás en una página de categoría, debes aterrizar en la misma página en el idioma diferente
Fra
1

¿Entonces quieres cambiar la URL para cada vista de tienda?

En la actualidad, ¿modificó la URL del producto en el alcance de la puntuación para que su tienda francesa sea diferente a su tienda inglesa? Y cuando cambias entre los dos, obtienes un 404. Este sería un comportamiento esperado.

Magento no almacenará diferentes reescrituras de URL para otras vistas de la tienda. Entonces, cuando ingresas /french/product1a la tienda francesa, la URL coincidirá en la tabla y se cargará. Pero cuando lo golpeas en la tienda en inglés, no habrá coincidencias y, por lo tanto, 404.

Parece que lo que necesita es simplemente "Agregar códigos de tienda a la URL", lo que dejará sus claves de URL solas, pero prefijará todas las URL respectivas con su código de tienda. Esto debería permitir que su conmutador de tienda funcione.

Ben Lessani - Sonassi
fuente
1
según lo confirmado por Vinai, esto es un error
Fra