Алексей Костюк

Автоматический 301 редирект при изменение URL в категории товары Opencart 3

Что-то я разошелся на посты про Opencart. Слишком долго я работаю с этой CMS и появляются много задач.

На сегодня задача сделать автоматический 301 редирект при изменении ссылки в категории товара во вкладке seo, то есть в ручном режиме.  Решение тестировалось на Opencart 3.0.3.8.

Создание таблицы в базе данных.

Переходим в phpmyadmin в хостинге вашего сайта, выбираем базу и во вкладке SQL выполняем запрос на создание таблицы oc_redirects:

CREATE TABLE `oc_redirects` (
  `redirect_id` INT(11) NOT NULL AUTO_INCREMENT,
  `from` VARCHAR(255) NOT NULL,
  `to` VARCHAR(255) NOT NULL,
  PRIMARY KEY (`redirect_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

Изменение контроллера категории в админке.

Теперь нужно внести код, который будет при изменении seo ссылки,  в настройке категории, записывать данные в новую таблицу, которую создали выше.

Открываем файл admin/controller/catalog/category.php и меняем метод public function edit():

public function edit() {
		$this->load->language('catalog/category');
		$this->document->setTitle($this->language->get('heading_title'));
		$this->load->model('catalog/category');
		if (($this->request->server['REQUEST_METHOD'] == 'POST') && $this->validateForm()) {
		$category_id = (int)$this->request->get['category_id'];
		$this->load->model('design/seo_url');
		$old_keywords = [];
		$seo_rows = $this->model_design_seo_url->getSeoUrlsByQuery('category_id=' . $category_id);
		foreach ($seo_rows as $row) {
			$old_keywords[$row['store_id']][$row['language_id']] = $row['keyword'];
		}
		$this->model_catalog_category->editCategory($category_id, $this->request->post);
			if (!empty($this->request->post['category_seo_url'])) {
			$parent_path = $this->getCategoryParentPath($category_id, 0, 1);
			foreach ($this->request->post['category_seo_url'] as $store_id => $languages) {
				foreach ($languages as $language_id => $new_keyword) {
					$old_keyword = isset($old_keywords[$store_id][$language_id]) ? $old_keywords[$store_id][$language_id] : '';
					if ($old_keyword && $old_keyword != $new_keyword) {
						$old_full = ltrim($parent_path . '/' . $old_keyword, '/');
						$new_full = ltrim($parent_path . '/' . $new_keyword, '/');
						$this->db->query("
							INSERT INTO " . DB_PREFIX . "redirects
							SET `from` = '" . $this->db->escape($old_full) . "',
								`to`   = '" . $this->db->escape($new_full) . "'
						");
					}
				}
			}
		} 
		$this->session->data['success'] = $this->language->get('text_success');
		$url = '';
		if (isset($this->request->get['sort'])) {
				$url .= '&sort=' . $this->request->get['sort'];
		}
		if (isset($this->request->get['order'])) {
				$url .= '&order=' . $this->request->get['order'];
			}
			if (isset($this->request->get['page'])) {
				$url .= '&page=' . $this->request->get['page'];
			}
			$this->response->redirect($this->url->link('catalog/category', 'user_token=' . $this->session->data['user_token'] . $url, true));
		}
		$this->getForm();
	}

Изменение контроллера формирования seo ссылок.

Внесём код в catalog/controller/startup/seo_url.php, который будет брать данные из таблицы oc_redirects и создавать 301 редирект. В начале метода index() выставляем код:

$request_uri = trim(parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH), '/');
$query = $this->db->query("SELECT `to` FROM " . DB_PREFIX . "redirects WHERE `from` = '" . $this->db->escape($request_uri) . "'");
if ($query->num_rows) {
	header("HTTP/1.1 301 Moved Permanently");
	header("Location: " . HTTP_SERVER . $query->row['to']);
	exit();
}

Адаптация 301 редиректа если вы сделали изменения из моего предыдущего поста - "SEO URL уже занят в категории товара Opencart 3".

Можете пропустить этот пункт. 301 редирект не сработает, если вы разрешили дубликаты seo ссылок из моего поста. Для этого в контроллере seo_url.php нужно заменить код:

if (!$hit) {
    $this->request->get['route'] = 'error/not_found';
    break;
}

На этот:

if (!$hit) {
			$redirect = $this->db->query("
				SELECT `to` FROM " . DB_PREFIX . "redirects
				WHERE `from` = '" . $this->db->escape(utf8_strtolower(implode('/', $parts))) . "'
				LIMIT 1
			");
			if ($redirect->num_rows) {
				$this->response->redirect(
					HTTP_SERVER . ltrim($redirect->row['to'], '/'),
					301
				);
				return;
			}
			$this->request->get['route'] = 'error/not_found';
			break;
		}

Применить изменения

После всех изменений переходим Модули/Расширения ->Модификаторы и нажимаем на кнопку обновить.

Теперь нужно протестировать и открыть в настройках категорию и изменить seo url

Сохранить изменения и перейти в phpmyadmin, чтобы убедиться записались ли данные в таблицу oc_redirects:

Как видите данные есть. Чтобы проверить 301 редирект нужно перейти по старой ссылке и она должна перенаправить на новую. Можете воспользоваться чекером.

Вот и всё. Ваш SEOшник будет в не себе от счастья. Удачных проектов!

0
1
0
0
0
Алексей Костюк
Привет Username! Я Алексей Костюк
16 лет занимаюсь тем, что помогаю людям создавать сайты и дизайн, настраивать рекламу, продвигать проекты в Интернете. Я создал этот блог, чтобы делиться своим опытом и мыслями, а если вы хотите, то можете меня поддержать, это поможет мне создавать больше полезных статей для вас.