OpenCart: как скрыть товары, которых нет в наличии

Чтобы были доступны и по ссылке, и в поисковиках.

В чём проблема

Представим, что у нас много тысяч товаров на сайте. Многих уже нет в наличии. Но они по-прежнему отображаются и в поиске сайта, и в категориях, и на страницах производителей. А мы знаем, что их больше не будет и они просто так «висят».

Что делать

  1. Открыть сайт/catalog/model/catalog/product.php.
  1. Открыть поиск и найти все условия:
AND p.status = '1'
  • Это условие отвечает за показ товара, когда он включён.
  1. Заменить все найденные условия (кроме одного ↓) на:
AND p.status = '1' AND p.stock_status_id != '5'
  • Это условие, при котором товар не будет отображаться: включён и нет в наличии.
  1. Не заменять условие в самом начале файла:
public function getProduct($product_id) {
…
}
  1. Сохранить, обновить кэш.
  1. Готово. Товары, которых нет в наличии, не отображаются, но доступны по прямой ссылке и отображаются в поисковиках.

Другой вариант

Допустим, что товара нет в наличии временно. И нам нужно, чтобы его видели на сайте. Тогда можно всё немного переиграть.

Что делать

  1. В том же файле открыть поиск и найти те же условия.
  1. Заменить их (также, кроме одного) на:
AND p.status = '1' AND p.minimum != '0'
  1. Сохранить, обновить кэш.
  1. Готово. Товары, которых нет в наличии, будут отображаться как обычно. Но товары, у которых минимальное количество будет равно нулю, отображаться не будут. Для них можно создать и отдельный статус, например «Снят с производства».
 Нет комментариев    54   10 дн   OpenCart 3

OpenCart: автогенерация сопутствующих товаров

Все сопутствующие товары, по умолчанию, добавляются вручную. Когда на сайте тысячи товаров, это становится проблемой.

Что делать

  1. Открываем сайт/catalog/model/catalog/product.php.
  1. Находим код (~392 строка):
$query = $this->db->query("SELECT * FROM " . DB_PREFIX . "product_related pr LEFT JOIN " . DB_PREFIX . "product p ON (pr.related_id = p.product_id) LEFT JOIN " . DB_PREFIX . "product_to_store p2s ON (p.product_id = p2s.product_id) WHERE pr.product_id = '" . (int)$product_id . "' AND p.status = '1' AND p.date_available <= NOW() AND p2s.store_id = '" . (int)$this->config->get('config_store_id') . "'");
  1. Заменяем его на:
$query = $this->db->query("SELECT *, (p.product_id) AS related_id FROM
  " . DB_PREFIX . "product_to_category p2c 
    LEFT JOIN " . DB_PREFIX . "product p ON (p2c.product_id = p.product_id)
    LEFT JOIN " . DB_PREFIX . "product_to_store p2s ON (p.product_id = p2s.product_id)
  WHERE 
    p2c.category_id IN (SELECT p2c2.category_id FROM " . DB_PREFIX . "product_to_category p2c2 WHERE p2c2.product_id = " . (int) $product_id . ")
      AND p.product_id <> " . (int) $product_id . "
      AND p.status = '1'
      AND p.stock_status_id != '5'
      AND p.date_available <= NOW()
      AND p2s.store_id = '" . (int)$this->config->get('config_store_id') . "'
    ORDER BY RAND() ASC
  LIMIT 0,8");
  1. Сохраняем, обновляем кэш.
  1. Готово.

Сопутствующие товары начнут генерироваться случайным образом — из подкатегорий родительской категории. И только те, которые есть в наличии.

 Нет комментариев    51   10 дн   OpenCart 3

OpenCart: как защитить админку

Админка, по умолчанию, находится по адресу сайт.ру/admin. Это проблема.

Что делать

  1. Открываем сайт/admin/controller/common/login.php.
  1. Находим код:
$this->load->language('common/login');
  1. После него вставляем:
$pass = null;
if (!isset($_GET[PASS_KEY]) || $_GET[PASS_KEY] != PASS) {
    $this->response->redirect('http://'.$_SERVER['HTTP_HOST']."/");
}
else {
    $pass = '&'.PASS_KEY.'='.PASS;
}
  1. Находим код:
$data['action'] = $this->url->link('common/login', '', true);
  1. Заменяем его на:
$data['action'] = $this->url->link('common/login', '', true).$pass;
  1. Открываем сайт/admin/config.php.
  1. После тега <?php, на новой строке, вставляем:
define('PASS_KEY', 'ключ');
define('PASS', 'пароль');
  1. Заменяем ключ на, например, access, а пароль на hellohacker.
  1. Сохраняем, обновляем кэш.
  1. Готово.
  1. Админка будет находиться по адресу сайт.ру/admin?access=hellohacker.
  1. Если адрес ввести неверно, произойдёт переадресация на главную страницу.
 2 комментария    49   10 дн   OpenCart 3

OpenCart: как минифицировать HTML

Для более быстрой загрузки страниц.

Что делать

  1. Открываем сайт/system/library/response.php.
  1. Находим код (~108 строка):
public function output() {
	if ($this->output) {
		$output = $this->level ? $this->compress($this->output, $this->level) : $this->output;
		
		if (!headers_sent()) {
			foreach ($this->headers as $header) {
				header($header, true);
			}
		}
		
		echo $output;
	}
}
  1. Заменяем на:
public function output() {
 
if ($this->output) {
    $this->output = preg_replace("/(\n)+/", "\n", $this->output);
    $this->output = preg_replace("/\r\n+/", "\n", $this->output);
    $this->output = preg_replace("/\n(\t)+/", "\n", $this->output);
    $this->output = preg_replace("/\n(\ )+/", "\n", $this->output);
    $this->output = preg_replace("/\>(\n)+</", '><', $this->output);
    $this->output = preg_replace("/\>\r\n</", '><', $this->output);
}

if ($this->output) {
	$output = $this->level ? $this->compress($this->output, $this->level) : $this->output;
	
	if (!headers_sent()) {
		foreach ($this->headers as $header) {
			header($header, true);
		}
	}
	
	echo $output;
}
}
  1. Сохраняем, обновляем кэш.
  1. Готово.
 Нет комментариев    18   2 мес   OpenCart 3

OpenCart: как сделать сортировку атрибутов по порядку сортировки

Потратил кучу времени на поиски решения, а оно оказалось до смешного простым.

В чём проблема

Вот мы создали группу атрибутов. Затем создали атрибуты, привязали к группе атрибутов, задали порядок сортировки. На сайте всё отображается нормально — согласно порядку сортировки. В админке же — всё сортируется по названиям, и это очень сбивает.

Что делать

  1. Открываем сайт/admin/model/catalog/attribute.php.
  1. Находим код (~53 строка):
if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
	$sql .= " ORDER BY " . $data['sort'];
} else {
	$sql .= " ORDER BY attribute_group, ad.name";
}
  1. Изменяем последнюю строку:
$sql .= " ORDER BY attribute_group, a.sort_order, ad.name";
  1. То есть, по умолчанию, в карточке товара в админке, стоит сортировка по названию. Мы же сделали по порядку сортировки, а затем по названию.
  1. Сохраняем, обновляем кэш.
  1. Готово.
 Нет комментариев    9   2 мес   OpenCart 3

OpenCart: автогеренация тайтла

Чтобы получилось вот так:

При этом, чтобы иметь возможность отдельно редактировать сам тайтл.

Что делать

  1. Открываем сайт/admin/view/template/catalog/product_form.twig.
  1. Находим код (~67 строка):
<input type="text" name="product_description[{{ language.language_id }}][meta_title]" value="{{ product_description[language.language_id] ? product_description[language.language_id].meta_title }}" placeholder="{{ entry_meta_title }}" id="input-meta-title{{ language.language_id }}" class="form-control" />
  1. После него вставляем:
<script type="text/javascript">
$(function() {
  var $name_input = $("input[name='product_description[{{ language.language_id }}][name]']");
  var $meta_title = $("input[name='product_description[{{ language.language_id }}][meta_title]']");

  $name_input.keyup(function() {
  $meta_title.val($name_input.val());
  });
});
</script>
  1. Сохраняем, обновляем кэш.
  1. Готово.
  1. Можно пойти дальше. Например, чтобы после названия автоматически генерировалось «купить в „магазине“».
  1. Изменяем одну строку:
$meta_title.val($name_input.val() + 'Тут какой-то текст');
  1. Готово — 2.

Ту же самую процедуру можно провернуть и с категориями.

Спасибо за помощь Ярославу Усенко.

 Нет комментариев    8   2 мес   OpenCart 3

OpenCart: как сделать сортировку товаров по наличию

И в магазине, и в админке.

В чём проблема

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

Что делать

  1. Открываем сайт/catalog/model/catalog/product.php.
  1. Находим код (~168 строка):
if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
	if ($data['sort'] == 'pd.name' || $data['sort'] == 'p.model') {
		$sql .= " ORDER BY LCASE(" . $data['sort'] . ")";
	} elseif ($data['sort'] == 'p.price') {
		$sql .= " ORDER BY (CASE WHEN special IS NOT NULL THEN special WHEN discount IS NOT NULL THEN discount ELSE p.price END)";
	} else {
		$sql .= " ORDER BY " . $data['sort'];
	}
} else {
	$sql .= " ORDER BY p.sort_order";
}
  1. Заменяем его на:
if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
    if ($data['sort'] == 'pd.name' || $data['sort'] == 'p.model') {
        $sql .= " ORDER BY p.stock_status_id DESC, LCASE(" . $data['sort'] . ")";
    } elseif ($data['sort'] == 'p.price') {
        $sql .= " ORDER BY p.stock_status_id DESC, (CASE WHEN special IS NOT NULL THEN special WHEN discount IS NOT NULL THEN discount ELSE p.price END)";
    } else {
        $sql .= " ORDER BY p.stock_status_id DESC, " . $data['sort'];
    }
} else {
    $sql .= " ORDER BY p.stock_status_id DESC, p.sort_order";
}
  1. Сохраняем, обновляем кэш.
  1. Готово. Товары будут сортироваться по наличию. Товаров, которых нет в наличии, будут отображаться в конце списка.
  1. Можно сортировать и по количеству, а уже затем по наличию. Для этого заменяем на:
if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
    if ($data['sort'] == 'pd.name' || $data['sort'] == 'p.model') {
        $sql .= " ORDER BY p.quantity DESC, p.stock_status_id DESC, LCASE(" . $data['sort'] . ")";
    } elseif ($data['sort'] == 'p.price') {
        $sql .= " ORDER BY p.quantity DESC, p.stock_status_id DESC, (CASE WHEN special IS NOT NULL THEN special WHEN discount IS NOT NULL THEN discount ELSE p.price END)";
    } else {
        $sql .= " ORDER BY p.quantity DESC, p.stock_status_id DESC, " . $data['sort'];
    }
} else {
    $sql .= " ORDER BY p.quantity DESC, p.stock_status_id DESC, p.sort_order";
}
  1. Можно использовать разные комбинации: сортировать по стоимости, рейтингу, дате добавления. Нужно лишь подменить значения в коде выше. Вот они:
$sort_data = array(
    'pd.name',
    'p.model',
    'p.quantity',
    'p.price',
    'rating',
    'p.sort_order',
    'p.date_added'
);

Как сделать в админке

  1. Открываем сайт/admin/model/catalog/product.php.
  1. Делаем тоже самое, что и наверху.
  1. Готово.

По теме

Сортировка данных в SQL (ORDER BY).

 Нет комментариев    8   2 мес   OpenCart 3

OpenCart: как подключить LazyLoad

На страницы товаров, в категориях, результаты поиска, страницы производителей.

Что это

Это ленивая загрузка изображений, которая ускоряет загрузку сайта.

Что делать

Примечание: для работы скрипта нужна подключённая библиотека jquery.

  1. Скачать lazyload.min.js.
  1. Можно подключить и ссылкой:
<script src="https://cdn.jsdelivr.net/npm/vanilla-lazyload@15.1.1/dist/lazyload.min.js"></script>
  1. Загрузить файл в catalog/view/javascript/. Или куда удобно.
  1. Подключить в header.twig в своей теме.
  1. В footer.twig, перед закрывающим тегом body, вставить:
<script>
var lazyLoadInstance = new LazyLoad({
    elements_selector: ".lazy"
});
</script>
  1. Переходим в сайт/catalog/view/тема/product/category.twig.
  1. К каждому тегу img добавляем класс lazy, а вместо src — data-src. Вот так:
<img class="lazy" data-src="ссылка на изображение" alt="">
  1. Тоже самое нужно проделать в файлах product.twig, search.twig, manufacturer_info.twig.
  1. Сохраняем, обновляем кэш.
  1. Готово.

У скрипта много настроек и возможностей, взгляните на гитхабе.

 Нет комментариев    8   2 мес   OpenCart 3

OpenCart: как исправить баг с адаптивность в админке

И начать нормально жить.

В чём проблема

Не знаю как у других, но когда я заходил в админку, было вот так:

Приходилось включать десктоп режим, что не вызывало восторга.

Потратил много времени прежде чем найти решение. А оно — до смешного простое.

Что делать

  1. Открываем сайт/admin/system/tweak.ocmod.xml.
  1. Находим код (~13 строка):
<operation>
	<search><![CDATA[
	{% for link in links %}
	]]></search>
	<add position="before"><![CDATA[
	<script type="text/javascript" src="view/javascript/jquery/translit.js"></script>

	<style>
	#column-left {width: 260px !important;}
	#column-left + #content {margin-left: 260px !important;}
	.bimage {margin:0;}
	</style>
	]]></add>
</operation>
  1. Удаляем из него вот эту часть:
<style>
#column-left {width: 260px !important;}
#column-left + #content {margin-left: 260px !important;}
.bimage {margin:0;}
</style>
  1. Сохраняем, обновляем кэш.
  1. Готово.
  1. Результат:
Человеческий вид
 Нет комментариев    9   2 мес   OpenCart 3

OpenCart: как сделать исходный код в редакторе товаров с нормальной разметкой

Двумя строчками кода.

В чём проблема

Когда вы заходите в исходный код описания, всё выглядит вот так:

Всё в одну строку, с прокруткой, без нормальной разметки

Что делать

  1. Открываем скрипт сайт/admin/view/javascript/summernote/opencart.js.
  1. Находим код:
$(element).summernote({
    lang: $(this).attr('data-lang'),
    disableDragAndDrop: true,
    height: 500,
    emptyPara: '',
    codemirror: { // codemirror options
        mode: 'text/html',
        htmlMode: true,
        lineNumbers: true,
        theme: 'monokai'
	},
  1. После строки lineNumbers вставляем:
lineWrapping: true,
  1. Это уберёт прокрутку, и разметка начнёт переноситься на новые строки.
  1. После строки emptyPara вставляем:
prettifyHtml: true,
  1. Это превратит кашу с разметкой в человеческий вид.
  1. Сохраняем, обновляем кэш.
  1. Готово.
  1. Результат на выходе:
 Нет комментариев    9   2 мес   OpenCart 3
Ранее Ctrl + ↓