Iván Ros Navarro Posted October 30, 2015 Share Posted October 30, 2015 (edited) Buenos días, Prestashop está mejorando mucho en optimización SEO, pero todavía está un poco verde en algunos aspectos y, a pesar de no ser un experto en SEO, se me ha dado la necesidad de redirigir productos que están descatalogados a su categoría y no a un producto en específico, dado que pueden darse casos en los que un artículo puede no ser lo suficientemente parecido a otro para "suplantarlo" y, creo más conveniente que sea el propio cliente el que elija otro artículo dentro de la misma categoría que el artículo descatalogado. Pues bien, aquí tenéis un pequeño aporte que puede servirle a algunos. En el archivo /controllers/front/ProductController.php, sobre la línea 108 hay que comentar o eliminar esta línea para los casos en los que no tenga un artículo asociado no establezca la redirección 404 y quede la redirección 301 if (!$this->product->id_product_redirected || $this->product->id_product_redirected == $this->product->id) $this->product->redirect_type = '404'; y cambiadla por este código para que cuando no tenga redirección 301 ni 302 sea 404 if ($this->product->redirect_type != '301' && $this->product->redirect_type != '302') $this->product->redirect_type = '404'; Con esto hecho, vamos a la línea 112, donde tenemos este código en la función "public function init()": switch ($this->product->redirect_type) { case '301': header('HTTP/1.1 301 Moved Permanently'); header('Location: '.$this->context->link->getProductLink($this->product->id_product_redirected)); exit; break; case '302': header('HTTP/1.1 302 Moved Temporarily'); header('Cache-Control: no-cache'); header('Location: '.$this->context->link->getProductLink($this->product->id_product_redirected)); exit; break; case '404': default: header('HTTP/1.1 404 Not Found'); header('Status: 404 Not Found'); $this->errors[] = Tools::displayError('This product is no longer available.'); break; } Cambiamos el caso 301 para que quede de la siguiente forma: case '301': if ($this->product->id_product_redirected){ header('HTTP/1.1 301 Moved Permanently'); header('Location: '.$this->context->link->getProductLink($this->product->id_product_redirected)); } else { header('HTTP/1.1 301 Moved Permanently'); header('Location: '.$this->context->link->getCategoryLink($this->product->id_category_default)); } exit; break; Comprobamos si tenemos producto relacionado ("id_product_redirected"). Si no tenemos producto relacionado, lo redirigimos a la categoría del producto obteniendo el link con "getCategoryLink" y especificando el Id de la categoría del producto con "id_category_default". Es muy sencillo pero como buen novato tardé bastante en realizarlo. Se puede hacer lo mismo en el 302 si se necesita. Aún así me falta perfeccionarlo para que incluya un mensaje que informe al cliente de que el producto está descatalogado y que se le muestra una serie de artículos de su misma categoría. Cuando lo tenga os lo pondré también, aunque si hay alguien que dé con la solución antes que yo y lo pone, agradecido. Espero os sirva. Un saludo, Iván Ros EDITO: Como bien ha dicho ventura, esto es mejor hacerlo mediante override. Aquí lo tenéis, el archivo sería /override/controllers/front/ProductController.php. Recordad eliminar el archivo /cache/class_index.php después de la modificación para asegurarnos de que coja bien el override. <?php class ProductController extends ProductControllerCore { /** * Initialize product controller * @see FrontController::init() */ public function init() { parent::init(); if ($id_product = (int)Tools::getValue('id_product')) $this->product = new Product($id_product, true, $this->context->language->id, $this->context->shop->id); if (!Validate::isLoadedObject($this->product)) { header('HTTP/1.1 404 Not Found'); header('Status: 404 Not Found'); $this->errors[] = Tools::displayError('Product not found'); } else { $this->canonicalRedirection(); /* * If the product is associated to the shop * and is active or not active but preview mode (need token + file_exists) * allow showing the product * In all the others cases => 404 "Product is no longer available" */ if (!$this->product->isAssociatedToShop() || !$this->product->active) { if (Tools::getValue('adtoken') == Tools::getAdminToken('AdminProducts'.(int)Tab::getIdFromClassName('AdminProducts').(int)Tools::getValue('id_employee')) && $this->product->isAssociatedToShop()) { // If the product is not active, it's the admin preview mode $this->context->smarty->assign('adminActionDisplay', true); } else { $this->context->smarty->assign('adminActionDisplay', false); if ($this->product->redirect_type != '301' && $this->product->redirect_type != '302') $this->product->redirect_type = '404'; switch ($this->product->redirect_type) { case '301': if ($this->product->id_product_redirected){ header('HTTP/1.1 301 Moved Permanently'); header('Location: '.$this->context->link->getProductLink($this->product->id_product_redirected)); } else { header('HTTP/1.1 301 Moved Permanently'); header('Location: '.$this->context->link->getCategoryLink($this->product->id_category_default)); } exit; break; case '302': header('HTTP/1.1 302 Moved Temporarily'); header('Cache-Control: no-cache'); header('Location: '.$this->context->link->getProductLink($this->product->id_product_redirected)); exit; break; case '404': default: header('HTTP/1.1 404 Not Found'); header('Status: 404 Not Found'); $this->errors[] = Tools::displayError('This product is no longer available.'); break; } } } elseif (!$this->product->checkAccess(isset($this->context->customer->id) && $this->context->customer->id ? (int)$this->context->customer->id : 0)) { header('HTTP/1.1 403 Forbidden'); header('Status: 403 Forbidden'); $this->errors[] = Tools::displayError('You do not have access to this product.'); } else { // Load category $id_category = false; if (isset($_SERVER['HTTP_REFERER']) && $_SERVER['HTTP_REFERER'] == Tools::secureReferrer($_SERVER['HTTP_REFERER']) // Assure us the previous page was one of the shop && preg_match('~^.*(?<!\/content)\/([0-9]+)\-(.*[^\.])|(.*)id_(category|product)=([0-9]+)(.*)$~', $_SERVER['HTTP_REFERER'], $regs)) { // If the previous page was a category and is a parent category of the product use this category as parent category $id_object = false; if (isset($regs[1]) && is_numeric($regs[1])) $id_object = (int)$regs[1]; elseif (isset($regs[5]) && is_numeric($regs[5])) $id_object = (int)$regs[5]; if ($id_object) { $referers = array($_SERVER['HTTP_REFERER'],urldecode($_SERVER['HTTP_REFERER'])); if (in_array($this->context->link->getCategoryLink($id_object), $referers)) $id_category = (int)$id_object; elseif (isset($this->context->cookie->last_visited_category) && (int)$this->context->cookie->last_visited_category && in_array($this->context->link->getProductLink($id_object), $referers)) $id_category = (int)$this->context->cookie->last_visited_category; } } if (!$id_category || !Category::inShopStatic($id_category, $this->context->shop) || !Product::idIsOnCategoryId((int)$this->product->id, array('0' => array('id_category' => $id_category)))) $id_category = (int)$this->product->id_category_default; $this->category = new Category((int)$id_category, (int)$this->context->cookie->id_lang); if (isset($this->context->cookie) && isset($this->category->id_category) && !(Module::isInstalled('blockcategories') && Module::isEnabled('blockcategories'))) $this->context->cookie->last_visited_category = (int)$this->category->id_category; } } } } Edited October 30, 2015 by Gorhaen (see edit history) Link to comment Share on other sites More sharing options...
eljose2 Posted October 30, 2015 Share Posted October 30, 2015 Gran aporte, sí señor. Link to comment Share on other sites More sharing options...
ventura Posted October 30, 2015 Share Posted October 30, 2015 Es un tipo de modificacion que es conveniente realizar mediante override del ProductController.php Link to comment Share on other sites More sharing options...
Iván Ros Navarro Posted October 30, 2015 Author Share Posted October 30, 2015 (edited) Por eso mencionaba lo de novato. Gracias ventura, la verdad es que sí es preferible hacerlo mediante override. Voy a hacerlo en mi página. Edited October 30, 2015 by Gorhaen (see edit history) Link to comment Share on other sites More sharing options...
Eusebio100 Posted October 30, 2015 Share Posted October 30, 2015 Creo que estaría bien ponerlo en el foro y listado de aportes. Link to comment Share on other sites More sharing options...
Yika Posted January 17, 2016 Share Posted January 17, 2016 Buenas noches, no sé si será por la versión de prestashop, ya que tengo la 1.6.1.4 pero ese archivo /override/controllers/front/ProductController.php. no lo tengo dentro de la carpeta, tengo otro que se llama OrderOpcController.php, como puedo hacerlo?, gracias de antemano y saludos Link to comment Share on other sites More sharing options...
Iván Ros Navarro Posted January 22, 2016 Author Share Posted January 22, 2016 Tienes que crearlo tú, se trata de un override, son modificaciones en Prestashop. Crea un archivo que se llame ProductController.php y copia y pega el contenido que menciono arriba en mi edición. Debería funcionarte Yika. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now