URL товаров модулей Новинки, Рекомендуемые, Поиск, Сравнение товаров

Суть проблемы: Opencart формирует неправильный SEO URL в указанных модулях. URL товара в категории: «http://site.com/categoriya/tovar». URL товара в модулях: «http://site.com/tovar».

Соответственно, возникают дубли страниц, ругаются сеошники и т.д. Исправим эту проблему. Причем, исправим с минимальными затратами — я встречал решения, которые генерируют много лишних запросов в базу данных, а Opencart итак далек от идеала в этом плане. Также, сделаем так, чтобы путь формировался правильно независимо от уровня вложенности категорий.

Почему возникает эта проблема.
В категориях url товара формируется следующим образом:

$this->url->link('product/product', 'path=' . $this->request->get['path'] . '&product_id=' . $result['product_id'] . $url)

а в модулях:

$this->url->link('product/product', 'product_id=' . $result['product_id'])

Как видно, в модулях отсутствует параметр path — который и дополняет url алиасами категорий.

План действий такой: — в модель добавим метод, который будет принимать массив id товаров, для которых необходимо сформировать правильные урлы, а возвращать метод будет массив, где ключами будут id товаров, а значениями — необходимый path (этим мы обеспечим универсальность метода); — в модулях сформируем массив id товаров, вызовем метод и добавим в формирование ссылки параметр path.

Пишем метод в модели

Если посмотрим что, представляет собой параметр path, мы увидим, что это id категорий, разделенные подчеркиванием — например, 2_10. Такое и будем формировать в методе.
Идем в /catalog/model/catalog/product.php, добавляем метод

	public function getProductsPath(array $products_ids) {//for latest, fitured... etc
		if(empty($products_ids)) return;
 
		$category_parent = array();
		$query = $this->db->query("SELECT category_id, parent_id FROM " . DB_PREFIX . "category");
		foreach ($query->rows as $result) {
			$category_parent[$result['category_id']] = $result['parent_id'];
		}
 
		$products_path = array();
		$query = $this->db->query("SELECT product_id, category_id FROM " . DB_PREFIX . "product_to_category WHERE product_id IN (" . implode(', ', $products_ids) . ")");
 
		foreach ($query->rows as $result) {
			$products_path[$result['product_id']] = $result['category_id'];
 
			$has_parent  = true;
			$cur_category = $result['category_id'];
			while($has_parent){
				if(!empty($category_parent[$cur_category])){
					$cur_category = $category_parent[$cur_category];
					$products_path[$result['product_id']] = $cur_category . '_' . $products_path[$result['product_id']];
				}else{
					$has_parent = false;
				}
			}
 
		}
		return $products_path;
	}

Как видим, метод делает всего 2 нетяжелых запроса в БД

Правим контроллер

Я напишу на примере модуля «Новинки», остальные модули правятся аналогично.
Идем в /catalog/controller/extension/module/latest.php

Получаем массив id товаров

Перед началом цикла формирования товаров

if ($results) {
	foreach ($results as $result) {

добавляем строку

$products_ids = array();

В цикле перед строкой

$data['products'][] = array(

добавляем

$products_ids[] = $result['product_id'];

Формируем правильный URL

Комментируем строку формирования URL в цикле

//'href'        => $this->url->link('product/product', 'product_id=' . $result['product_id'])

и перед выводом результата

return $this->load->view('extension/module/latest', $data);

получаем массив путей товаров и формируем новые урлы — добавляем

if(!empty($products_ids)){
	$products_path = $this->model_catalog_product->getProductsPath($products_ids);
	foreach($data['products'] as $k => $v){
		$data['products'][$k]['href'] =	$this->url->link('product/product', 'path=' . $products_path[$v['product_id']] . '&product_id=' . $v['product_id']);
	}
}

Все, теперь у нас правильные URL. Если что-то не понятно, пишите aktual@aktual.com.ua, постараюсь помочь.

Категория: OpenCart
Comments are disabled