Buscar este blog

sábado, 27 de abril de 2013

Versión óptima para eliminar ID's de producto

Lo único que debéis de tener en cuenta al realizar esta modificación es que no tengáis nombre de productos repetidos.

Haced copia de seguridad de los archivos que se van a modificar ANTES DE REALIZAR NINGUNA MODIFICACIÓN.

Para versión de Prestashop 1.4.8.2

Archivos a modificar:
  • /prestashop/.htaccess
    • Si no encontráis este archivo debéis ir al panel de administración de prestashop en el backend -> Herramientas -> Generadores y hacer click en "Generar el archivo .Htaccess"
    • En caso de que al realizar esto siga sin aparecer, la explicación es que se encuentra oculto. Buscad en internet como mostrar archivos ocultos -> Normalmente con botón derecho en la carpeta, propiedades y mostrar archivos ocultos se soluciona.
  • /prestashop/classes/Link.php
  • /prestashop/controllers/ProductController.php
Entramos en faena:


Modificaciones en Link.php
  • Ir a función: public function getProductLink
  • Modificamos suprimiendo lo que está en negrita o comentarlo usando // ó /* */
  • public function getProductLink($id_product, $alias = NULL, $category = NULL, $ean13 = NULL, $id_lang = NULL)
    {
    global $cookie;
    if (is_object($id_product))
    {
    $link = '';
    if ($this->allow == 1)
    {
    $link .= (_PS_BASE_URL_.__PS_BASE_URI__.$this->getLangLink((int)$id_lang));
    if (isset($id_product->category) AND !empty($id_product->category) AND $id_product->category != 'home')
    $link .= $id_product->category.'/';
    else
    $link .= '';
    $link .= (int)$id_product->id.'-';
    if (is_array($id_product->link_rewrite))
    $link.= $id_product->link_rewrite[(int)$cookie->id_lang];
    else 
      $link.= $id_product->link_rewrite;
    if ($id_product->ean13)
    $link .='-'.$id_product->ean13;
    else
    $link .= '';

    $link .= '.html';
    }
    else 
    {
    $link .= (_PS_BASE_URL_.__PS_BASE_URI__.'product.php?id_product='.(int)$id_product->id);
    }
    return $link;
    }
    else if ($alias)
    {
    $link = '';
    if ($this->allow == 1)
    {
    $link .= (_PS_BASE_URL_.__PS_BASE_URI__.$this->getLangLink((int)$id_lang));
    if ($category AND $category != 'home')
    $link .= $category.'/';
    else 
      $link .= '';
     
    $link .= (int)$id_product.'-'.$alias;
    if ($ean13) 
    $link .='-'.$ean13;
    else 
    $link .= '';
    $link .= '.html';
    }
    else
    $link .=(_PS_BASE_URL_.__PS_BASE_URI__.'product.php?id_product='.(int)$id_product);
    return $link;
    }
    else
    return _PS_BASE_URL_.__PS_BASE_URI__.'product.php?id_product='.(int)$id_product;
    }
Modificaciones en FrontController.php

  • Ir a la función public function preProcess()
  • Después de la variable global $cart añadís:
          $resultado = Db::getInstance()->getValue('
SELECT id_product
FROM `'._DB_PREFIX_.'product_lang`
WHERE `link_rewrite`="'.Tools::getValue('name').'"');
  • Justo después se encuentra la siguiente línea:
                                         if ($id_product = (int)Tools::getValue('id_product'))
  • Esta se sustituye por la siguiente:
                                         if ($id_product = $resultado)

Modificaciones en .htaccess

  • Buscar estas líneas: Nota. Lo que hay marcado en rojo diferirá de lo que tengáis en vuestro propio .htaccess y debéis de tenerla en cuenta porque esto no se modifica. Sólo vamos a modificar la parte en negrita
RewriteRule ^([0-9]+)\-[a-zA-Z0-9-]*\.html /prestashop/product.php?id_product=$1 [QSA,L]
RewriteRule ^[a-zA-Z0-9-]*/([0-9]+)\-[a-zA-Z0-9-]*\.html /prestashop/product.php?id_product=$1 [QSA,L]
  • Por las siguientes: Nota. Sólo se ha modificado la parte en negrita.
RewriteRule ^([a-zA-Z0-9-]*)\.html /prestashop/product.php?name=$1 [QSA,L]
RewriteRule ^[a-zA-Z0-9-]*/([a-zA-Z0-9-]*)\.html /prestashop/product.php?name=$1 [QSA,L]

Con esto ya debe funcionar, pero, si da algún tipo de error, tenéis que ir a las siguientes carpetas y borrar todo lo que hay en ellas (salvo el archivo index.php)

  • prestashop/tools/smarty/cache
  • prestashop/tools/smarty/compile
La explicación es que en esas carpetas se encuentran los archivos compilados y algunas variables. Esto se hace para que el sitio vaya más rápido. El que quiera saber bien de que va: http://www.prestashop.com/en/top-tips


Dudas?? Comentarios?? 


Si necesitas ayuda escribe a través del formulario de contacto en la parte derecha.
Nota: Antes de acceder al formulario aparecerá un anuncio, que en 5 segundos podrás cerrar.

14 comentarios:

  1. Gracias por tu artículo; me ha servido de referencia para intentar obtener en v1.4.10.0 una url de producto del tipo:
    http://mitienda.com/es/categoria/supplier_reference-nombre-p-id.html
    Es decir, llevar la id al final antecedida por una p y poner antes del nombre el supplier reference.
    Para ello he hecho las siguientes modificaciones:
    En Link.php:

    public function getProductLink($id_product, $alias = null, $category = null, $supplier_reference = null, $ean13 = null, $id_lang = null)
    {
    global $cookie;

    if (is_object($id_product))
    {
    $link = '';
    if ($this->allow == 1)
    {
    $link .= _PS_BASE_URL_.__PS_BASE_URI__.$this->getLangLink((int)$id_lang);

    if (isset($id_product->category) && !empty($id_product->category) && $id_product->category != 'home')
    $link .= $id_product->category.'/';

    if ($id_product->supplier_reference)
    $link .= $id_product->supplier_reference.'-';

    $link .= (is_array($id_product->link_rewrite) ? $id_product->link_rewrite[(int)$cookie->id_lang] : $id_product->link_rewrite).'-p-'.(int)$id_product->id;

    $link .= '.html';
    }
    else
    $link .= _PS_BASE_URL_.__PS_BASE_URI__.'product.php?id_product='.(int)$id_product->id;

    return $link;
    }
    elseif ($alias)
    {
    $link = '';
    if ($this->allow == 1)
    {
    $link .= _PS_BASE_URL_.__PS_BASE_URI__.$this->getLangLink((int)$id_lang);

    if ($category && $category != 'home')
    $link .= $category.'/';

    if ($supplier_reference)
    $link .= $supplier_reference.'-';

    $link .= $alias.'-p-'.(int)$id_product;

    $link .= '.html';
    }
    else
    $link .= _PS_BASE_URL_.__PS_BASE_URI__.'product.php?id_product='.(int)$id_product;

    return $link;
    }
    else
    return _PS_BASE_URL_.__PS_BASE_URI__.'product.php?id_product='.(int)$id_product;
    }

    y en .htaccess:

    RewriteRule ^([a-z]{2})/[a-zA-Z0-9-]*/[a-zA-Z0-9-]*-p-([0-9]+).html /product.php?id_product=$2&isolang=$1 [QSA,L]
    RewriteRule ^([a-z]{2})/[a-zA-Z0-9-]*-p-([0-9]+).html /product.php?id_product=$2&isolang=$1 [QSA,L]
    RewriteRule ^[a-zA-Z0-9-]*-p-([0-9]+).html /product.php?id_product=$1 [QSA,L]
    RewriteRule ^[a-zA-Z0-9-]*/[a-zA-Z0-9-]*-p-([0-9]+).html /product.php?id_product=$1 [QSA,L]

    Funciona bien pero me aparece el problema de que si quiero cambiar de idioma desde la página del producto no me deja; me vuelve a saltar en el idioma que estaba. He podido observar que, por ejemplo, estando en el producto http://elrincondebabu.com/es/munecas-paola-reina/302-carla-golfista-p-17.html
    Si veo el link que muestra el hover sobre uno de los idiomas es http://elrincondebabu.com/es/poupees-paola-reina/carla-golfeuse-p-17.html es decir, cambia el idioma en categoría y nombre, pone el id como yo quiero pero no cambia a /fr ni aparece la reference_supplier. Supongo que el fallo está en que me falta algo de código en lo referente a la reference_supplier, pero como no domino de esto, no tengo idea de qué puede ser. Te agradecería me echaras una mano. Muchas gracias,
    Santi
    P.D: Si navegas por la tienda para analizar el problema, ten en cuenta que les he puesto reference_supplier a pocos artículos (sobre todo lo tienen los de la categoría Paola Reina).

    ResponderEliminar
    Respuestas
    1. Encontré la solución: me sobraba el $ean13 = null (que sustituyo por $supplier_reference = null en la declaración de la función.
      Aún así, el hover sigue sin mostrar el supplier_reference aunque luego sí aparece en la url.
      Gracias de todas maneras por tu artículo,
      Santi

      Eliminar
    2. Me alegro mucho que te haya ayudado a resolver tu problema.

      Si necesitas algo no dudes en escribir e intentaré ayudarte.

      Eliminar
  2. Hola! Funcionará para la version 1.5.3?
    Gracias!

    ResponderEliminar
  3. Sí, no la he probado pero creo que sí funcionará. Dentro de unas semanas terminaré un módulo para que sea más fácil y eficiente para todos hacer esta modificación.

    ResponderEliminar
  4. El tema es que mi link.php no se parece al que tu pones aquí y no se que debo tocar, no lo encuentro, te lo pongo aquí a ver si me puedes ayudar, hay un monton de dispatcher, gracias por adelantado:
    public function getProductLink($product, $alias = null, $category = null, $ean13 = null, $id_lang = null, $id_shop = null, $ipa = 0, $force_routes = false)
    {
    $dispatcher = Dispatcher::getInstance();

    if (!$id_lang)
    $id_lang = Context::getContext()->language->id;

    if (!$id_shop)
    $shop = Context::getContext()->shop;
    else
    $shop = new Shop($id_shop);

    $url = 'http://'.$shop->domain.$shop->getBaseURI().$this->getLangLink($id_lang);

    if (!is_object($product))
    {
    if (is_array($product) && isset($product['id_product']))
    $product = new Product($product['id_product'], false, $id_lang);
    else if (is_numeric($product) || !$product)
    $product = new Product($product, false, $id_lang);
    else
    throw new PrestaShopException('Invalid product vars');
    }

    // Set available keywords
    $params = array();
    $params['id'] = $product->id;
    $params['rewrite'] = (!$alias) ? $product->getFieldByLang('link_rewrite') : $alias;
    $params['ean13'] = (!$ean13) ? $product->ean13 : $ean13;
    $params['meta_keywords'] = Tools::str2url($product->getFieldByLang('meta_keywords'));
    $params['meta_title'] = Tools::str2url($product->getFieldByLang('meta_title'));

    if ($dispatcher->hasKeyword('product_rule', $id_lang, 'manufacturer'))
    $params['manufacturer'] = Tools::str2url($product->isFullyLoaded ? $product->manufacturer_name : Manufacturer::getNameById($product->id_manufacturer));

    if ($dispatcher->hasKeyword('product_rule', $id_lang, 'supplier'))
    $params['supplier'] = Tools::str2url($product->isFullyLoaded ? $product->supplier_name : Supplier::getNameById($product->id_supplier));

    if ($dispatcher->hasKeyword('product_rule', $id_lang, 'price'))
    $params['price'] = $product->isFullyLoaded ? $product->price : Product::getPriceStatic($product->id, false, null, 6, null, false, true, 1, false, null, null, null, $product->specificPrice);

    if ($dispatcher->hasKeyword('product_rule', $id_lang, 'tags'))
    $params['tags'] = Tools::str2url($product->getTags($id_lang));

    if ($dispatcher->hasKeyword('product_rule', $id_lang, 'category'))
    $params['category'] = Tools::str2url($product->category);

    if ($dispatcher->hasKeyword('product_rule', $id_lang, 'reference'))
    $params['reference'] = Tools::str2url($product->reference);

    if ($dispatcher->hasKeyword('product_rule', $id_lang, 'categories'))
    {
    $params['category'] = (!$category) ? $product->category : $category;
    $cats = array();
    foreach ($product->getParentCategories() as $cat)
    if (!in_array($cat['id_category'], array(1, 2)))//remove root and home category from the URL
    $cats[] = $cat['link_rewrite'];
    $params['categories'] = implode('/', $cats);
    }
    $anchor = $ipa ? $product->getAnchor($ipa) : '';

    return $url.$dispatcher->createUrl('product_rule', $id_lang, $params, $force_routes, $anchor);

    ResponderEliminar
  5. Tienes razón Marta. En esta versión de prestashop han modificado las funciones que generan la URL. Supongo que querrás arreglarlo cuanto antes para tu web, pero ¿Tienes mucha prisa? Puedo tenerlo hecho para finales de la semana que viene. Si me retrasara te avisaría.

    ResponderEliminar
  6. Pues te lo agradecería infinito!!! y puedo esperar, aún queda bastante que hacer

    ResponderEliminar
    Respuestas
    1. Hola!! Has podido mirarlo?
      Mil gracias

      Eliminar
    2. No, todavía no, cuando lo tenga lo verás publicado en la web. Lo haré lo antes posible.

      Eliminar
    3. Ok gracias!!!
      Ando como loca con este tema...

      Eliminar
  7. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  8. Buenas, y si tengo la versión 1.6 qué puedo hacer?
    Gracias! :)

    ResponderEliminar
    Respuestas
    1. No lo tenemos actualizado a esta versión 1.6.1.3
      Lo tenemos programado para revisarlo pero no podemos concretarte una fecha. Si quieres envíanos email a software.softwild@gmail.com y te avisaremos personalmente en cuanto lo realicemos.

      Gracias y perdona las molestias

      Eliminar

Gracias por comentar.

Si has realizado alguna consulta, responderemos lo antes posible. Gracias