<?xml version="1.0" encoding="utf-8"?> 
<rss version="2.0"
  xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"
  xmlns:atom="http://www.w3.org/2005/Atom">

<channel>

<title>Блог Антона Кима: заметки с тегом OpenCart 3</title>
<link>https://antonkim.ru/blog/tags/opencart-3/</link>
<description>Чему жизнь меня научила</description>
<author>Антон Ким</author>
<language>ru</language>
<generator>E2 (v3849; Aegea)</generator>

<itunes:owner>
<itunes:name>Антон Ким</itunes:name>
<itunes:email></itunes:email>
</itunes:owner>
<itunes:subtitle>Чему жизнь меня научила</itunes:subtitle>
<itunes:image href="" />
<itunes:explicit></itunes:explicit>

<item>
<title>OpenCart: как на странице товара вывести SKU и UPC</title>
<guid isPermaLink="false">81</guid>
<link>https://antonkim.ru/blog/all/sku-and-upc/</link>
<pubDate>Fri, 17 Jul 2020 05:49:36 +0000</pubDate>
<author>Антон Ким</author>
<comments>https://antonkim.ru/blog/all/sku-and-upc/</comments>
<description>
&lt;p&gt;Эти значения вводятся в админке, но на странице товара не отображаются. А иногда нужно, чтобы отображались.&lt;/p&gt;
&lt;h2&gt;Что делать&lt;/h2&gt;
&lt;ol start="1"&gt;
&lt;li&gt;Открываем &lt;tt&gt;сайт/catalog/controller/product/product.php&lt;/tt&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="2"&gt;
&lt;li&gt;Находим код (~240 строка):&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;$data['model'] = $product_info['model'];&lt;/code&gt;&lt;/pre&gt;&lt;ol start="3"&gt;
&lt;li&gt;После вставляем:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;$data['sku'] = $product_info['sku'];
$data['upc'] = $product_info['upc'];&lt;/code&gt;&lt;/pre&gt;&lt;ol start="4"&gt;
&lt;li&gt;Сохраняем, обновляем кэш.&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="5"&gt;
&lt;li&gt;Открываем &lt;tt&gt;сайт/catalog/view/theme/тема/template/product/product.twig&lt;/tt&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="6"&gt;
&lt;li&gt;Находим место для выведения и вписываем:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;{{ sku }}
{{ upc }}&lt;/code&gt;&lt;/pre&gt;&lt;ol start="7"&gt;
&lt;li&gt;Сохраняем, обновляем кэш.&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="8"&gt;
&lt;li&gt;Готово.&lt;/li&gt;
&lt;/ol&gt;
</description>
</item>

<item>
<title>OpenCart: как добавить фильтр по артикулу в админке</title>
<guid isPermaLink="false">80</guid>
<link>https://antonkim.ru/blog/all/sku-filter/</link>
<pubDate>Fri, 17 Jul 2020 05:01:13 +0000</pubDate>
<author>Антон Ким</author>
<comments>https://antonkim.ru/blog/all/sku-filter/</comments>
<description>
&lt;p&gt;В стандартном фильтре в админке нельзя «фильтровать» товары по артикулу. Когда у вас тысячи товаров, такой фильтр в разы ускоряет поиск конкретного товара.&lt;/p&gt;
&lt;h2&gt;Что делать&lt;/h2&gt;
&lt;ol start="1"&gt;
&lt;li&gt;Открываем &lt;tt&gt;сайт/admin/controller/catalog/product.php&lt;/tt&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="2"&gt;
&lt;li&gt;Находим код (~227 строка):&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;protected function getList() {&lt;/code&gt;&lt;/pre&gt;&lt;ol start="3"&gt;
&lt;li&gt;После фигурной скобки вставляем:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;if (isset($this-&amp;gt;request-&amp;gt;get['filter_sku'])) {
	$filter_sku = $this-&amp;gt;request-&amp;gt;get['filter_sku'];
} else {
	$filter_sku = '';
}
$data['filter_sku'] = $filter_sku;&lt;/code&gt;&lt;/pre&gt;&lt;ol start="4"&gt;
&lt;li&gt;В том же файле находим (~276 строка):&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;$url = ''&lt;/code&gt;&lt;/pre&gt;&lt;ol start="5"&gt;
&lt;li&gt;После вставляем:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;if (isset($this-&amp;gt;request-&amp;gt;get['filter_sku'])) {
	$url .= '&amp;amp;filter_sku=' . $this-&amp;gt;request-&amp;gt;get['filter_sku'];
}&lt;/code&gt;&lt;/pre&gt;&lt;ol start="6"&gt;
&lt;li&gt;В том же файле находим (~324 строка):&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;$filter_data = array(&lt;/code&gt;&lt;/pre&gt;&lt;ol start="7"&gt;
&lt;li&gt;После скобки вставляем:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;'filter_sku' =&amp;gt; isset($filter_sku) ? $filter_sku : '',&lt;/code&gt;&lt;/pre&gt;&lt;ol start="8"&gt;
&lt;li&gt;Сохраняем, обновляеем кэш.&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="9"&gt;
&lt;li&gt;Открываем &lt;tt&gt;сайт/admin/model/catalog/product.php&lt;/tt&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="10"&gt;
&lt;li&gt;Находим код (~361 строка):&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;if (!empty($data['filter_name'])) {
	$sql .= &amp;quot; AND pd.name LIKE '&amp;quot; . $this-&amp;gt;db-&amp;gt;escape($data['filter_name']) . &amp;quot;%'&amp;quot;;
}&lt;/code&gt;&lt;/pre&gt;&lt;ol start="11"&gt;
&lt;li&gt;После него вставляем:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;if (isset($this-&amp;gt;request-&amp;gt;get['filter_sku']) &amp;amp;&amp;amp; !empty($data['filter_sku'])) {
	$sql .= &amp;quot; AND p.sku = '&amp;quot; . $this-&amp;gt;db-&amp;gt;escape($data['filter_sku']) . &amp;quot;'&amp;quot;;
}&lt;/code&gt;&lt;/pre&gt;&lt;ol start="12"&gt;
&lt;li&gt;Сохраняем, обновляем кэш.&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="13"&gt;
&lt;li&gt;Открываем &lt;tt&gt;сайт/admin/view/template/catalog/product_list.twig&lt;/tt&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="14"&gt;
&lt;li&gt;Находим код (~68 строка):&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;&amp;lt;div class=&amp;quot;form-group&amp;quot;&amp;gt;
	&amp;lt;label class=&amp;quot;control-label&amp;quot; for=&amp;quot;input-quantity&amp;quot;&amp;gt;{{ entry_quantity }}&amp;lt;/label&amp;gt;
	&amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;filter_quantity&amp;quot; value=&amp;quot;{{ filter_quantity }}&amp;quot; id=&amp;quot;input-quantity&amp;quot; class=&amp;quot;form-control&amp;quot; /&amp;gt;
&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;ol start="15"&gt;
&lt;li&gt;После него вставляем:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;&amp;lt;div class=&amp;quot;form-group&amp;quot;&amp;gt;
	&amp;lt;label class=&amp;quot;control-label&amp;quot; for=&amp;quot;input-sku&amp;quot;&amp;gt;Артикул&amp;lt;/label&amp;gt;
	&amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;filter_sku&amp;quot; value=&amp;quot;{{ filter_sku }}&amp;quot; id=&amp;quot;input-sku&amp;quot; class=&amp;quot;form-control&amp;quot; /&amp;gt;
&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;ol start="16"&gt;
&lt;li&gt;В том же файле находим (~227 строка):&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;var filter_status = $('select[name=\'filter_status\']').val();&lt;/code&gt;&lt;/pre&gt;&lt;ol start="17"&gt;
&lt;li&gt;После него вставляем:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;var filter_sku = $('input[name=\'filter_sku\']').val();

if (filter_sku) {
	url += '&amp;amp;filter_sku=' + encodeURIComponent(filter_sku);
}&lt;/code&gt;&lt;/pre&gt;&lt;ol start="18"&gt;
&lt;li&gt;Сохраняем, обновляем кэш.&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="19"&gt;
&lt;li&gt;Готово.&lt;/li&gt;
&lt;/ol&gt;
</description>
</item>

<item>
<title>OpenCart: как отключить кнопку покупки, когда товара нет в наличии</title>
<guid isPermaLink="false">79</guid>
<link>https://antonkim.ru/blog/all/buy-button-disabled/</link>
<pubDate>Thu, 16 Jul 2020 10:15:05 +0000</pubDate>
<author>Антон Ким</author>
<comments>https://antonkim.ru/blog/all/buy-button-disabled/</comments>
<description>
&lt;p&gt;Когда товара нет в наличии, его, по умолчанию, можно добавить в корзину. В таком сценарии нет необходимости.&lt;/p&gt;
&lt;h2&gt;Что делать&lt;/h2&gt;
&lt;ol start="1"&gt;
&lt;li&gt;Открываем &lt;tt&gt;сайт/catalog/controller/product/product.php&lt;/tt&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="2"&gt;
&lt;li&gt;Находим код (~251 строка):&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;if ($product_info['quantity'] &amp;lt;= 0) {
	$data['stock'] = $product_info['stock_status'];
} elseif ($this-&amp;gt;config-&amp;gt;get('config_stock_display')) {
	$data['stock'] = $product_info['quantity'];
} else {
	$data['stock'] = $this-&amp;gt;language-&amp;gt;get('text_instock');
}&lt;/code&gt;&lt;/pre&gt;&lt;ol start="3"&gt;
&lt;li&gt;Перед ним добавляем:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;$data['stock_quantity'] = $product_info['quantity'];
$data['text_out_of_stock'] = $product_info['stock_status'];&lt;/code&gt;&lt;/pre&gt;&lt;ol start="4"&gt;
&lt;li&gt;В том же файле находим (~436 строка):&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;$data['products'][] = array(
…
);&lt;/code&gt;&lt;/pre&gt;&lt;ol start="5"&gt;
&lt;li&gt;После скобки добавляем:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;'quantity' =&amp;gt; $result['quantity'],
'text_out_of_stock' =&amp;gt; $result['stock_status'],&lt;/code&gt;&lt;/pre&gt;&lt;ol start="6"&gt;
&lt;li&gt;Сохраняем, обновляем кэш.&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="7"&gt;
&lt;li&gt;Открываем &lt;tt&gt;сайт/catalog/theme/тема/template/product/product.twig&lt;/tt&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="8"&gt;
&lt;li&gt;Находим код:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;&amp;lt;button type=&amp;quot;button&amp;quot; id=&amp;quot;button-cart&amp;quot; data-loading-text=&amp;quot;{{ text_loading }}&amp;quot; class=&amp;quot;btn button-cart&amp;quot;&amp;gt;{{ button_cart }}&amp;lt;/button&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;В завимости от темы, код может отличаться, но &lt;tt&gt;button-cart&lt;/tt&gt; остаётся константой.&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="9"&gt;
&lt;li&gt;Заменяем его на:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;{% if stock_quantity &amp;lt; 1 %} 
    &amp;lt;button type=&amp;quot;button&amp;quot; id=&amp;quot;button-outstock&amp;quot; disabled=&amp;quot;disabled&amp;quot; data-loading-text=&amp;quot;{{ text_loading }}&amp;quot; class=&amp;quot;btn button-cart&amp;quot;&amp;gt;&amp;lt;i class=&amp;quot;fa fa-exclamation-triangle&amp;quot;&amp;gt;&amp;lt;/i&amp;gt; {{ text_out_of_stock }}&amp;lt;/button&amp;gt;
{% else %}
    &amp;lt;button type=&amp;quot;button&amp;quot; id=&amp;quot;button-cart&amp;quot; data-loading-text=&amp;quot;{{ text_loading }}&amp;quot; class=&amp;quot;btn button-cart&amp;quot;&amp;gt;{{ button_cart }}&amp;lt;/button&amp;gt;
{% endif %}&lt;/code&gt;&lt;/pre&gt;&lt;ol start="10"&gt;
&lt;li&gt;В том же файле находим:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;&amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;quantity&amp;quot; value=&amp;quot;{{ minimum }}&amp;quot; size=&amp;quot;2&amp;quot; id=&amp;quot;input-quantity&amp;quot; class=&amp;quot;form-control&amp;quot; /&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;ol start="11"&gt;
&lt;li&gt;Заменяем его на:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;{% if stock_quantity &amp;gt; 1 %} 
    &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;quantity&amp;quot; value=&amp;quot;{{ minimum }}&amp;quot; size=&amp;quot;2&amp;quot; id=&amp;quot;input-quantity&amp;quot; class=&amp;quot;form-control&amp;quot; /&amp;gt;
{% endif %}&lt;/code&gt;&lt;/pre&gt;&lt;ol start="12"&gt;
&lt;li&gt;В том же файле находим:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;&amp;lt;label class=&amp;quot;control-label&amp;quot; for=&amp;quot;input-quantity&amp;quot;&amp;gt;{{ entry_qty }}&amp;lt;/label&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;ol start="13"&gt;
&lt;li&gt;Заменяем его на:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;{% if stock_quantity &amp;gt; 1 %} 
    &amp;lt;label class=&amp;quot;control-label&amp;quot; for=&amp;quot;input-quantity&amp;quot;&amp;gt;{{ entry_qty }}&amp;lt;/label&amp;gt;
{% endif %}&lt;/code&gt;&lt;/pre&gt;&lt;ol start="14"&gt;
&lt;li&gt;Сохраняем, обновляем кэш.&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="15"&gt;
&lt;li&gt;Готово. На странице товара, когда его не будет в наличии, кнопка «Купить» станет неактивной.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Возникает вопрос. Вот мы отключили кнопку на странице товара. Славно. Но как быть, если кнопка есть ещё и в категориях, поиске, страницах производителей?&lt;/p&gt;
&lt;p&gt;Всё зависит от конкретной темы. Но шаги остаются теми же, — меняются только редактируемые файлы. Например, &lt;tt&gt;category.php&lt;/tt&gt;, &lt;tt&gt;manufacturer.php&lt;/tt&gt;, &lt;tt&gt;search.php&lt;/tt&gt; и пр.&lt;/p&gt;
</description>
</item>

<item>
<title>OpenCart: как скрыть товары, которых нет в наличии</title>
<guid isPermaLink="false">74</guid>
<link>https://antonkim.ru/blog/all/hide-goods/</link>
<pubDate>Fri, 26 Jun 2020 06:02:44 +0000</pubDate>
<author>Антон Ким</author>
<comments>https://antonkim.ru/blog/all/hide-goods/</comments>
<description>
&lt;p&gt;Чтобы были доступны и по ссылке, и в поисковиках.&lt;/p&gt;
&lt;h2&gt;В чём проблема&lt;/h2&gt;
&lt;p&gt;Представим, что у нас много тысяч товаров на сайте. Многих уже нет в наличии. Но они по-прежнему отображаются и в поиске сайта, и в категориях, и на страницах производителей. А мы знаем, что их больше не будет и они просто так «висят».&lt;/p&gt;
&lt;h2&gt;Что делать&lt;/h2&gt;
&lt;ol start="1"&gt;
&lt;li&gt;Открыть &lt;kbd&gt;сайт/catalog/model/catalog/product.php&lt;/kbd&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="2"&gt;
&lt;li&gt;Открыть поиск и найти все условия:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;AND p.status = '1'&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;Это условие отвечает за показ товара, когда он включён.&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="3"&gt;
&lt;li&gt;Заменить все найденные условия (кроме одного ↓) на:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;AND p.status = '1' AND p.stock_status_id != '5'&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;Это условие, при котором товар не будет отображаться: включён и нет в наличии.&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="4"&gt;
&lt;li&gt;Не заменять условие в самом начале файла:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;public function getProduct($product_id) {
…
}&lt;/code&gt;&lt;/pre&gt;&lt;ol start="5"&gt;
&lt;li&gt;Сохранить, обновить кэш.&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="6"&gt;
&lt;li&gt;Готово. Товары, которых нет в наличии, не отображаются, но доступны по прямой ссылке и отображаются в поисковиках.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Другой вариант&lt;/h2&gt;
&lt;p&gt;Допустим, что товара нет в наличии временно. И нам нужно, чтобы его видели на сайте. Тогда можно всё немного переиграть.&lt;/p&gt;
&lt;h2&gt;Что делать&lt;/h2&gt;
&lt;ol start="1"&gt;
&lt;li&gt;В том же файле открыть поиск и найти те же условия.&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="2"&gt;
&lt;li&gt;Заменить их (также, кроме одного) на:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;AND p.status = '1' AND p.minimum != '0'&lt;/code&gt;&lt;/pre&gt;&lt;ol start="3"&gt;
&lt;li&gt;Сохранить, обновить кэш.&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="4"&gt;
&lt;li&gt;Готово. Товары, которых нет в наличии, будут отображаться как обычно. Но товары, у которых минимальное количество будет равно нулю, отображаться не будут. Для них можно создать и отдельный статус, например «Снят с производства».&lt;/li&gt;
&lt;/ol&gt;
</description>
</item>

<item>
<title>OpenCart: автогенерация сопутствующих товаров</title>
<guid isPermaLink="false">73</guid>
<link>https://antonkim.ru/blog/all/automatic-related-products/</link>
<pubDate>Fri, 26 Jun 2020 02:07:37 +0000</pubDate>
<author>Антон Ким</author>
<comments>https://antonkim.ru/blog/all/automatic-related-products/</comments>
<description>
&lt;p&gt;Все сопутствующие товары, по умолчанию, добавляются вручную. Когда на сайте тысячи товаров, это становится проблемой.&lt;/p&gt;
&lt;h2&gt;Что делать&lt;/h2&gt;
&lt;ol start="1"&gt;
&lt;li&gt;Открываем &lt;tt&gt;сайт/catalog/model/catalog/product.php&lt;/tt&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="2"&gt;
&lt;li&gt;Находим код (~392 строка):&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;$query = $this-&amp;gt;db-&amp;gt;query(&amp;quot;SELECT * FROM &amp;quot; . DB_PREFIX . &amp;quot;product_related pr LEFT JOIN &amp;quot; . DB_PREFIX . &amp;quot;product p ON (pr.related_id = p.product_id) LEFT JOIN &amp;quot; . DB_PREFIX . &amp;quot;product_to_store p2s ON (p.product_id = p2s.product_id) WHERE pr.product_id = '&amp;quot; . (int)$product_id . &amp;quot;' AND p.status = '1' AND p.date_available &amp;lt;= NOW() AND p2s.store_id = '&amp;quot; . (int)$this-&amp;gt;config-&amp;gt;get('config_store_id') . &amp;quot;'&amp;quot;);&lt;/code&gt;&lt;/pre&gt;&lt;ol start="3"&gt;
&lt;li&gt;Заменяем его на:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;$query = $this-&amp;gt;db-&amp;gt;query(&amp;quot;SELECT *, (p.product_id) AS related_id FROM
  &amp;quot; . DB_PREFIX . &amp;quot;product_to_category p2c 
    LEFT JOIN &amp;quot; . DB_PREFIX . &amp;quot;product p ON (p2c.product_id = p.product_id)
    LEFT JOIN &amp;quot; . DB_PREFIX . &amp;quot;product_to_store p2s ON (p.product_id = p2s.product_id)
  WHERE 
    p2c.category_id IN (SELECT p2c2.category_id FROM &amp;quot; . DB_PREFIX . &amp;quot;product_to_category p2c2 WHERE p2c2.product_id = &amp;quot; . (int) $product_id . &amp;quot;)
      AND p.product_id &amp;lt;&amp;gt; &amp;quot; . (int) $product_id . &amp;quot;
      AND p.status = '1'
      AND p.stock_status_id != '5'
      AND p.date_available &amp;lt;= NOW()
      AND p2s.store_id = '&amp;quot; . (int)$this-&amp;gt;config-&amp;gt;get('config_store_id') . &amp;quot;'
    ORDER BY RAND() ASC
  LIMIT 0,8&amp;quot;);&lt;/code&gt;&lt;/pre&gt;&lt;ol start="4"&gt;
&lt;li&gt;Сохраняем, обновляем кэш.&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="5"&gt;
&lt;li&gt;Готово.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Сопутствующие товары начнут генерироваться случайным образом — из подкатегорий родительской категории. И только те, которые есть в наличии.&lt;/p&gt;
</description>
</item>

<item>
<title>OpenCart: как защитить админку</title>
<guid isPermaLink="false">72</guid>
<link>https://antonkim.ru/blog/all/admin-protection/</link>
<pubDate>Thu, 25 Jun 2020 17:26:34 +0000</pubDate>
<author>Антон Ким</author>
<comments>https://antonkim.ru/blog/all/admin-protection/</comments>
<description>
&lt;p&gt;Админка, по умолчанию, находится по адресу сайт.ру/admin. Это проблема.&lt;/p&gt;
&lt;h2&gt;Что делать&lt;/h2&gt;
&lt;ol start="1"&gt;
&lt;li&gt;Открываем &lt;tt&gt;сайт/admin/controller/common/login.php&lt;/tt&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="2"&gt;
&lt;li&gt;Находим код:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;$this-&amp;gt;load-&amp;gt;language('common/login');&lt;/code&gt;&lt;/pre&gt;&lt;ol start="3"&gt;
&lt;li&gt;После него вставляем:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;$pass = null;
if (!isset($_GET[PASS_KEY]) || $_GET[PASS_KEY] != PASS) {
    $this-&amp;gt;response-&amp;gt;redirect('http://'.$_SERVER['HTTP_HOST'].&amp;quot;/&amp;quot;);
}
else {
    $pass = '&amp;amp;'.PASS_KEY.'='.PASS;
}&lt;/code&gt;&lt;/pre&gt;&lt;ol start="4"&gt;
&lt;li&gt;Находим код:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;$data['action'] = $this-&amp;gt;url-&amp;gt;link('common/login', '', true);&lt;/code&gt;&lt;/pre&gt;&lt;ol start="5"&gt;
&lt;li&gt;Заменяем его на:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;$data['action'] = $this-&amp;gt;url-&amp;gt;link('common/login', '', true).$pass;&lt;/code&gt;&lt;/pre&gt;&lt;ol start="6"&gt;
&lt;li&gt;Открываем &lt;tt&gt;сайт/admin/config.php&lt;/tt&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="7"&gt;
&lt;li&gt;После тега &lt;&amp;#63;php, на новой строке, вставляем:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;define('PASS_KEY', 'ключ');
define('PASS', 'пароль');&lt;/code&gt;&lt;/pre&gt;&lt;ol start="8"&gt;
&lt;li&gt;Заменяем ключ, например, на &lt;tt&gt;access&lt;/tt&gt;, а пароль на &lt;tt&gt;hellohacker&lt;/tt&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="9"&gt;
&lt;li&gt;Сохраняем, обновляем кэш.&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="10"&gt;
&lt;li&gt;Готово.&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="11"&gt;
&lt;li&gt;Админка будет находиться по адресу &lt;tt&gt;сайт.ру/admin?access=hellohacker&lt;/tt&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="12"&gt;
&lt;li&gt;Если адрес ввести неверно, произойдёт переадресация на главную страницу.&lt;/li&gt;
&lt;/ol&gt;
</description>
</item>

<item>
<title>OpenCart: как минифицировать HTML</title>
<guid isPermaLink="false">71</guid>
<link>https://antonkim.ru/blog/all/html-minification/</link>
<pubDate>Mon, 04 May 2020 16:49:45 +0000</pubDate>
<author>Антон Ким</author>
<comments>https://antonkim.ru/blog/all/html-minification/</comments>
<description>
&lt;p&gt;Для более быстрой загрузки страниц.&lt;/p&gt;
&lt;h2&gt;Что делать&lt;/h2&gt;
&lt;ol start="1"&gt;
&lt;li&gt;Открываем &lt;tt&gt;сайт/system/library/response.php&lt;/tt&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="2"&gt;
&lt;li&gt;Находим код (~108 строка):&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;public function output() {
	if ($this-&amp;gt;output) {
		$output = $this-&amp;gt;level ? $this-&amp;gt;compress($this-&amp;gt;output, $this-&amp;gt;level) : $this-&amp;gt;output;
		
		if (!headers_sent()) {
			foreach ($this-&amp;gt;headers as $header) {
				header($header, true);
			}
		}
		
		echo $output;
	}
}&lt;/code&gt;&lt;/pre&gt;&lt;ol start="3"&gt;
&lt;li&gt;Заменяем на:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;public function output() {
 
if ($this-&amp;gt;output) {
    $this-&amp;gt;output = preg_replace(&amp;quot;/(\n)+/&amp;quot;, &amp;quot;\n&amp;quot;, $this-&amp;gt;output);
    $this-&amp;gt;output = preg_replace(&amp;quot;/\r\n+/&amp;quot;, &amp;quot;\n&amp;quot;, $this-&amp;gt;output);
    $this-&amp;gt;output = preg_replace(&amp;quot;/\n(\t)+/&amp;quot;, &amp;quot;\n&amp;quot;, $this-&amp;gt;output);
    $this-&amp;gt;output = preg_replace(&amp;quot;/\n(\ )+/&amp;quot;, &amp;quot;\n&amp;quot;, $this-&amp;gt;output);
    $this-&amp;gt;output = preg_replace(&amp;quot;/\&amp;gt;(\n)+&amp;lt;/&amp;quot;, '&amp;gt;&amp;lt;', $this-&amp;gt;output);
    $this-&amp;gt;output = preg_replace(&amp;quot;/\&amp;gt;\r\n&amp;lt;/&amp;quot;, '&amp;gt;&amp;lt;', $this-&amp;gt;output);
}

if ($this-&amp;gt;output) {
	$output = $this-&amp;gt;level ? $this-&amp;gt;compress($this-&amp;gt;output, $this-&amp;gt;level) : $this-&amp;gt;output;
	
	if (!headers_sent()) {
		foreach ($this-&amp;gt;headers as $header) {
			header($header, true);
		}
	}
	
	echo $output;
}
}&lt;/code&gt;&lt;/pre&gt;&lt;ol start="4"&gt;
&lt;li&gt;Сохраняем, обновляем кэш.&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="5"&gt;
&lt;li&gt;Готово.&lt;/li&gt;
&lt;/ol&gt;
</description>
</item>

<item>
<title>OpenCart: как сделать сортировку атрибутов по порядку сортировки</title>
<guid isPermaLink="false">70</guid>
<link>https://antonkim.ru/blog/all/attribute-sorting/</link>
<pubDate>Mon, 04 May 2020 16:46:27 +0000</pubDate>
<author>Антон Ким</author>
<comments>https://antonkim.ru/blog/all/attribute-sorting/</comments>
<description>
&lt;p&gt;Потратил кучу времени на поиски решения, а оно оказалось до смешного простым.&lt;/p&gt;
&lt;h2&gt;В чём проблема&lt;/h2&gt;
&lt;p&gt;Вот мы создали группу атрибутов. Затем создали атрибуты, привязали к группе атрибутов, задали порядок сортировки. На сайте всё отображается нормально — согласно порядку сортировки. В админке же — всё сортируется по названиям, и это очень сбивает.&lt;/p&gt;
&lt;h2&gt;Что делать&lt;/h2&gt;
&lt;ol start="1"&gt;
&lt;li&gt;Открываем &lt;tt&gt;сайт/admin/model/catalog/attribute.php&lt;/tt&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="2"&gt;
&lt;li&gt;Находим код (~53 строка):&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;if (isset($data['sort']) &amp;amp;&amp;amp; in_array($data['sort'], $sort_data)) {
	$sql .= &amp;quot; ORDER BY &amp;quot; . $data['sort'];
} else {
	$sql .= &amp;quot; ORDER BY attribute_group, ad.name&amp;quot;;
}&lt;/code&gt;&lt;/pre&gt;&lt;ol start="3"&gt;
&lt;li&gt;Изменяем последнюю строку:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;$sql .= &amp;quot; ORDER BY attribute_group, a.sort_order, ad.name&amp;quot;;&lt;/code&gt;&lt;/pre&gt;&lt;ol start="4"&gt;
&lt;li&gt;То есть, по умолчанию, в карточке товара в админке, стоит сортировка по названию. Мы же сделали по порядку сортировки, а затем по названию.&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="5"&gt;
&lt;li&gt;Сохраняем, обновляем кэш.&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="6"&gt;
&lt;li&gt;Готово.&lt;/li&gt;
&lt;/ol&gt;
</description>
</item>

<item>
<title>OpenCart: автогеренация тайтла</title>
<guid isPermaLink="false">69</guid>
<link>https://antonkim.ru/blog/all/title-autogenerate/</link>
<pubDate>Mon, 27 Apr 2020 16:40:17 +0000</pubDate>
<author>Антон Ким</author>
<comments>https://antonkim.ru/blog/all/title-autogenerate/</comments>
<description>
&lt;p&gt;Чтобы получилось вот так:&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://antonkim.ru/blog/pictures/generate-title.gif" width="1000" height="410" alt="" /&gt;
&lt;/div&gt;
&lt;p&gt;При этом, чтобы иметь возможность отдельно редактировать сам тайтл.&lt;/p&gt;
&lt;h2&gt;Что делать&lt;/h2&gt;
&lt;ol start="1"&gt;
&lt;li&gt;Открываем &lt;tt&gt;сайт/admin/view/template/catalog/product_form.twig&lt;/tt&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="2"&gt;
&lt;li&gt;Находим код (~67 строка):&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;&amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;product_description[{{ language.language_id }}][meta_title]&amp;quot; value=&amp;quot;{{ product_description[language.language_id] ? product_description[language.language_id].meta_title }}&amp;quot; placeholder=&amp;quot;{{ entry_meta_title }}&amp;quot; id=&amp;quot;input-meta-title{{ language.language_id }}&amp;quot; class=&amp;quot;form-control&amp;quot; /&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;ol start="3"&gt;
&lt;li&gt;После него вставляем:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;
$(function() {
  var $name_input = $(&amp;quot;input[name='product_description[{{ language.language_id }}][name]']&amp;quot;);
  var $meta_title = $(&amp;quot;input[name='product_description[{{ language.language_id }}][meta_title]']&amp;quot;);

  $name_input.keyup(function() {
  $meta_title.val($name_input.val());
  });
});
&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;ol start="4"&gt;
&lt;li&gt;Сохраняем, обновляем кэш.&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="5"&gt;
&lt;li&gt;Готово.&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="6"&gt;
&lt;li&gt;Можно пойти дальше. Например, чтобы после названия автоматически генерировалось «купить в „магазине“».&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="7"&gt;
&lt;li&gt;Изменяем одну строку:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;$meta_title.val($name_input.val() + 'Тут какой-то текст');&lt;/code&gt;&lt;/pre&gt;&lt;ol start="8"&gt;
&lt;li&gt;Готово — 2.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Ту же самую процедуру можно провернуть и с категориями.&lt;/p&gt;
&lt;p&gt;Спасибо за помощь &lt;a href="https://usnko.pp.ua/?utm_source=antonkim.com&amp;utm_medium=article"&gt;Ярославу Усенко&lt;/a&gt;.&lt;/p&gt;
</description>
</item>

<item>
<title>OpenCart: как сделать сортировку товаров по наличию</title>
<guid isPermaLink="false">68</guid>
<link>https://antonkim.ru/blog/all/sort-by-availability/</link>
<pubDate>Sun, 26 Apr 2020 16:30:06 +0000</pubDate>
<author>Антон Ким</author>
<comments>https://antonkim.ru/blog/all/sort-by-availability/</comments>
<description>
&lt;p&gt;И в магазине, и в админке.&lt;/p&gt;
&lt;h2&gt;В чём проблема&lt;/h2&gt;
&lt;p&gt;По умолчанию, все товары в категориях, страницах производителей, поиске — сортируются по названиям в алфавитном порядке. И даже те товары, которых нет в наличии, могут отображаться в начале списка. А когда таких товаров много — это становится проблемой.&lt;/p&gt;
&lt;h2&gt;Что делать&lt;/h2&gt;
&lt;ol start="1"&gt;
&lt;li&gt;Открываем &lt;tt&gt;сайт/catalog/model/catalog/product.php&lt;/tt&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="2"&gt;
&lt;li&gt;Находим код (~168 строка):&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;if (isset($data['sort']) &amp;amp;&amp;amp; in_array($data['sort'], $sort_data)) {
	if ($data['sort'] == 'pd.name' || $data['sort'] == 'p.model') {
		$sql .= &amp;quot; ORDER BY LCASE(&amp;quot; . $data['sort'] . &amp;quot;)&amp;quot;;
	} elseif ($data['sort'] == 'p.price') {
		$sql .= &amp;quot; ORDER BY (CASE WHEN special IS NOT NULL THEN special WHEN discount IS NOT NULL THEN discount ELSE p.price END)&amp;quot;;
	} else {
		$sql .= &amp;quot; ORDER BY &amp;quot; . $data['sort'];
	}
} else {
	$sql .= &amp;quot; ORDER BY p.sort_order&amp;quot;;
}&lt;/code&gt;&lt;/pre&gt;&lt;ol start="3"&gt;
&lt;li&gt;Заменяем его на:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;if (isset($data['sort']) &amp;amp;&amp;amp; in_array($data['sort'], $sort_data)) {
    if ($data['sort'] == 'pd.name' || $data['sort'] == 'p.model') {
        $sql .= &amp;quot; ORDER BY p.stock_status_id DESC, LCASE(&amp;quot; . $data['sort'] . &amp;quot;)&amp;quot;;
    } elseif ($data['sort'] == 'p.price') {
        $sql .= &amp;quot; 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)&amp;quot;;
    } else {
        $sql .= &amp;quot; ORDER BY p.stock_status_id DESC, &amp;quot; . $data['sort'];
    }
} else {
    $sql .= &amp;quot; ORDER BY p.stock_status_id DESC, p.sort_order&amp;quot;;
}&lt;/code&gt;&lt;/pre&gt;&lt;ol start="4"&gt;
&lt;li&gt;Сохраняем, обновляем кэш.&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="5"&gt;
&lt;li&gt;Готово. Товары будут сортироваться по наличию. Товаров, которых нет в наличии, будут отображаться в конце списка.&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="6"&gt;
&lt;li&gt;Можно сортировать и по количеству, а уже затем по наличию. Для этого заменяем на:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;if (isset($data['sort']) &amp;amp;&amp;amp; in_array($data['sort'], $sort_data)) {
    if ($data['sort'] == 'pd.name' || $data['sort'] == 'p.model') {
        $sql .= &amp;quot; ORDER BY p.quantity DESC, p.stock_status_id DESC, LCASE(&amp;quot; . $data['sort'] . &amp;quot;)&amp;quot;;
    } elseif ($data['sort'] == 'p.price') {
        $sql .= &amp;quot; 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)&amp;quot;;
    } else {
        $sql .= &amp;quot; ORDER BY p.quantity DESC, p.stock_status_id DESC, &amp;quot; . $data['sort'];
    }
} else {
    $sql .= &amp;quot; ORDER BY p.quantity DESC, p.stock_status_id DESC, p.sort_order&amp;quot;;
}&lt;/code&gt;&lt;/pre&gt;&lt;ol start="7"&gt;
&lt;li&gt;Можно использовать разные комбинации: сортировать по стоимости, рейтингу, дате добавления. Нужно лишь подменить значения в коде выше. Вот они:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;$sort_data = array(
    'pd.name',
    'p.model',
    'p.quantity',
    'p.price',
    'rating',
    'p.sort_order',
    'p.date_added'
);&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Как сделать в админке&lt;/h2&gt;
&lt;ol start="1"&gt;
&lt;li&gt;Открываем сайт/admin/model/catalog/product.php.&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="2"&gt;
&lt;li&gt;Делаем тоже самое, что и наверху.&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="3"&gt;
&lt;li&gt;Готово.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;По теме&lt;/h2&gt;
&lt;p&gt;&lt;a href="http://old.code.mu/sql/order-by.html"&gt;Сортировка данных в SQL (ORDER BY&lt;/a&gt;).&lt;/p&gt;
</description>
</item>

<item>
<title>OpenCart: как подключить LazyLoad</title>
<guid isPermaLink="false">67</guid>
<link>https://antonkim.ru/blog/all/opencart-lazyload/</link>
<pubDate>Fri, 24 Apr 2020 11:37:07 +0000</pubDate>
<author>Антон Ким</author>
<comments>https://antonkim.ru/blog/all/opencart-lazyload/</comments>
<description>
&lt;p&gt;На страницы товаров, в категориях, результаты поиска, страницы производителей.&lt;/p&gt;
&lt;h2&gt;Что это&lt;/h2&gt;
&lt;p&gt;Это ленивая загрузка изображений, которая ускоряет загрузку сайта.&lt;/p&gt;
&lt;h2&gt;Что делать&lt;/h2&gt;
&lt;p&gt;Примечание: для работы скрипта нужна подключённая библиотека jquery.&lt;/p&gt;
&lt;ol start="1"&gt;
&lt;li&gt;Скачать &lt;a href="https://antonkim.ru/blog/download/lazyload.min.js" download&gt;lazyload.min.js&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="2"&gt;
&lt;li&gt;Можно подключить и ссылкой:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;&amp;lt;script src=&amp;quot;https://cdn.jsdelivr.net/npm/vanilla-lazyload@15.1.1/dist/lazyload.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;ol start="3"&gt;
&lt;li&gt;Загрузить файл в &lt;tt&gt;catalog/view/javascript/&lt;/tt&gt;. Или куда удобно.&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="4"&gt;
&lt;li&gt;Подключить в &lt;tt&gt;header.twig&lt;/tt&gt; в своей теме.&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="5"&gt;
&lt;li&gt;В &lt;tt&gt;footer.twig&lt;/tt&gt;, перед закрывающим тегом &lt;tt&gt;body&lt;/tt&gt;, вставить:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;&amp;lt;script&amp;gt;
var lazyLoadInstance = new LazyLoad({
    elements_selector: &amp;quot;.lazy&amp;quot;
});
&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;ol start="6"&gt;
&lt;li&gt;Переходим в &lt;tt&gt;сайт/catalog/view/тема/product/category.twig&lt;/tt&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="7"&gt;
&lt;li&gt;К каждому тегу img добавляем класс lazy, а вместо src — data-src. Вот так:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;&amp;lt;img class=&amp;quot;lazy&amp;quot; data-src=&amp;quot;ссылка на изображение&amp;quot; alt=&amp;quot;&amp;quot;&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;ol start="8"&gt;
&lt;li&gt;Тоже самое нужно проделать в файлах &lt;tt&gt;product.twig&lt;/tt&gt;, &lt;tt&gt;search.twig&lt;/tt&gt;, &lt;tt&gt;manufacturer_info.twig&lt;/tt&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="9"&gt;
&lt;li&gt;Сохраняем, обновляем кэш.&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="10"&gt;
&lt;li&gt;Готово.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;У скрипта много настроек и возможностей, взгляните &lt;a href="https://github.com/verlok/lazyload"&gt;на гитхабе&lt;/a&gt;.&lt;/p&gt;
</description>
</item>

<item>
<title>OpenCart: как исправить баг с адаптивность в админке</title>
<guid isPermaLink="false">66</guid>
<link>https://antonkim.ru/blog/all/opencart-responsive-bug/</link>
<pubDate>Fri, 24 Apr 2020 11:24:30 +0000</pubDate>
<author>Антон Ким</author>
<comments>https://antonkim.ru/blog/all/opencart-responsive-bug/</comments>
<description>
&lt;p&gt;И начать нормально жить.&lt;/p&gt;
&lt;h2&gt;В чём проблема&lt;/h2&gt;
&lt;p&gt;Не знаю как у других, но когда я заходил в админку, было вот так:&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://antonkim.ru/blog/pictures/opencart-admin-1.jpg" width="393" height="851" alt="" /&gt;
&lt;/div&gt;
&lt;p&gt;Приходилось включать десктоп режим, что не вызывало восторга.&lt;/p&gt;
&lt;p&gt;Потратил много времени прежде чем найти решение. А оно — до смешного простое.&lt;/p&gt;
&lt;h2&gt;Что делать&lt;/h2&gt;
&lt;ol start="1"&gt;
&lt;li&gt;Открываем &lt;tt&gt;сайт/admin/system/tweak.ocmod.xml&lt;/tt&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="2"&gt;
&lt;li&gt;Находим код (~13 строка):&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;&amp;lt;operation&amp;gt;
	&amp;lt;search&amp;gt;&amp;lt;![CDATA[
	{% for link in links %}
	]]&amp;gt;&amp;lt;/search&amp;gt;
	&amp;lt;add position=&amp;quot;before&amp;quot;&amp;gt;&amp;lt;![CDATA[
	&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;view/javascript/jquery/translit.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;

	&amp;lt;style&amp;gt;
	#column-left {width: 260px !important;}
	#column-left + #content {margin-left: 260px !important;}
	.bimage {margin:0;}
	&amp;lt;/style&amp;gt;
	]]&amp;gt;&amp;lt;/add&amp;gt;
&amp;lt;/operation&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;ol start="3"&gt;
&lt;li&gt;Удаляем из него вот эту часть:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;&amp;lt;style&amp;gt;
#column-left {width: 260px !important;}
#column-left + #content {margin-left: 260px !important;}
.bimage {margin:0;}
&amp;lt;/style&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;ol start="4"&gt;
&lt;li&gt;Сохраняем, обновляем кэш.&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="5"&gt;
&lt;li&gt;Готово.&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="6"&gt;
&lt;li&gt;Результат:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://antonkim.ru/blog/pictures/opencart-admin-3.jpg" width="393" height="851" alt="" /&gt;
&lt;div class="e2-text-caption"&gt;Человеческий вид&lt;/div&gt;
&lt;/div&gt;
</description>
</item>

<item>
<title>OpenCart: как сделать нормальную разметку в исходном коде редактора товаров</title>
<guid isPermaLink="false">65</guid>
<link>https://antonkim.ru/blog/all/source-code-in-editor/</link>
<pubDate>Thu, 23 Apr 2020 11:15:41 +0000</pubDate>
<author>Антон Ким</author>
<comments>https://antonkim.ru/blog/all/source-code-in-editor/</comments>
<description>
&lt;p&gt;Двумя строчками кода.&lt;/p&gt;
&lt;h2&gt;В чём проблема&lt;/h2&gt;
&lt;p&gt;Когда вы заходите в исходный код описания, всё выглядит вот так:&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://antonkim.ru/blog/pictures/source-code-in-editor-3.png" width="1920" height="969" alt="" /&gt;
&lt;div class="e2-text-caption"&gt;Всё в одну строку, с прокруткой, без нормальной разметки&lt;/div&gt;
&lt;/div&gt;
&lt;h2&gt;Что делать&lt;/h2&gt;
&lt;ol start="1"&gt;
&lt;li&gt;Открываем скрипт &lt;tt&gt;сайт/admin/view/javascript/summernote/opencart.js&lt;/tt&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="2"&gt;
&lt;li&gt;Находим код:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;$(element).summernote({
    lang: $(this).attr('data-lang'),
    disableDragAndDrop: true,
    height: 500,
    emptyPara: '',
    codemirror: { // codemirror options
        mode: 'text/html',
        htmlMode: true,
        lineNumbers: true,
        theme: 'monokai'
	},&lt;/code&gt;&lt;/pre&gt;&lt;ol start="3"&gt;
&lt;li&gt;После строки &lt;tt&gt;lineNumbers&lt;/tt&gt; вставляем:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;lineWrapping: true,&lt;/code&gt;&lt;/pre&gt;&lt;ol start="4"&gt;
&lt;li&gt;Это уберёт прокрутку, и разметка начнёт переноситься на новые строки.&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="5"&gt;
&lt;li&gt;После строки &lt;tt&gt;emptyPara&lt;/tt&gt; вставляем:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;prettifyHtml: true,&lt;/code&gt;&lt;/pre&gt;&lt;ol start="6"&gt;
&lt;li&gt;Это превратит кашу с разметкой в человеческий вид.&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="7"&gt;
&lt;li&gt;Сохраняем, обновляем кэш.&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="8"&gt;
&lt;li&gt;Готово.&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="9"&gt;
&lt;li&gt;Результат на выходе:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://antonkim.ru/blog/pictures/source-code-in-editor-4.png" width="1920" height="969" alt="" /&gt;
&lt;/div&gt;
</description>
</item>

<item>
<title>OpenCart: как отключить форматирование при копировании</title>
<guid isPermaLink="false">64</guid>
<link>https://antonkim.ru/blog/all/remove-text-formatting/</link>
<pubDate>Wed, 22 Apr 2020 10:38:36 +0000</pubDate>
<author>Антон Ким</author>
<comments>https://antonkim.ru/blog/all/remove-text-formatting/</comments>
<description>
&lt;p&gt;Когда вы копируете откуда-то текст, он копируется целиком — вместе со стилями источника. Есть два решения.&lt;/p&gt;
&lt;p&gt;Первое — копировать и вставлять не через &lt;nobr&gt;&lt;kbd&gt;Ctrl + V&lt;/kbd&gt;&lt;/nobr&gt;, а через &lt;nobr&gt;&lt;kbd&gt;Ctrl + Shift + V&lt;/kbd&gt;&lt;/nobr&gt;. Второе — отключить форматирование при копировании вообще.&lt;/p&gt;
&lt;h2&gt;Что делать&lt;/h2&gt;
&lt;ol start="1"&gt;
&lt;li&gt;Открываем &lt;tt&gt;сайт/admin/view/javascript/summernote/opencart.js&lt;/tt&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="2"&gt;
&lt;li&gt;Находим код:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;$(element).summernote({
    lang: $(this).attr('data-lang'),
    disableDragAndDrop: true,
    height: 400,
    emptyPara: '',
    codemirror: { // codemirror options
        mode: 'text/html',
        htmlMode: true,
        lineNumbers: true,
        theme: 'monokai'
    },&lt;/code&gt;&lt;/pre&gt;&lt;ol start="3"&gt;
&lt;li&gt;После него вставляем:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;callbacks: {
    onPaste: function(e) {
        var bufferText = ((e.originalEvent || e).clipboardData || window.clipboardData).getData('Text');
        e.preventDefault();
        setTimeout(function() {
            document.execCommand('insertText', false, bufferText);
            }, 10);
        }
},&lt;/code&gt;&lt;/pre&gt;&lt;ol start="4"&gt;
&lt;li&gt;Сохраняем, обновляем кэш.&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="5"&gt;
&lt;li&gt;Готово.&lt;/li&gt;
&lt;/ol&gt;
</description>
</item>

<item>
<title>OpenCart: как сделать видео адаптивным по умолчанию</title>
<guid isPermaLink="false">63</guid>
<link>https://antonkim.ru/blog/all/embed-responsive-video/</link>
<pubDate>Wed, 22 Apr 2020 10:31:14 +0000</pubDate>
<author>Антон Ким</author>
<comments>https://antonkim.ru/blog/all/embed-responsive-video/</comments>
<description>
&lt;p&gt;Не залезая в исходный код редактора товаров.&lt;/p&gt;
&lt;h2&gt;В чём проблема&lt;/h2&gt;
&lt;p&gt;Когда вы вставляете видео с ютюба (кнопка «Видео»), оно имеет размеры 640х360. Чтобы сделать его адаптивным, приходится лезть в код и дополнять его. Это неудобно и неприятно.&lt;/p&gt;
&lt;h2&gt;Что делать&lt;/h2&gt;
&lt;p&gt;Примечание: у меня по умолчанию установлен редактор summernote, поэтому инструкция для него.&lt;/p&gt;
&lt;ol start="1"&gt;
&lt;li&gt;Открываем &lt;tt&gt;сайт/admin/view/javascript/summernote/summernote.js&lt;/tt&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="2"&gt;
&lt;li&gt;Находим код (~6372 строка):&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;$video.addClass('note-video-clip');

return $video[0];&lt;/code&gt;&lt;/pre&gt;&lt;ol start="3"&gt;
&lt;li&gt;Заменяем его на:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;var $embed;
var $embed = $('&amp;lt;div&amp;gt;').addClass('embed-responsive').addClass('embed-responsive-16by9');

$video.addClass('note-video-clip').addClass('embed-responsive-item');
$video.appendTo($embed);

return $embed[0];&lt;/code&gt;&lt;/pre&gt;&lt;ol start="4"&gt;
&lt;li&gt;Сохраняем, обновляем кэш.&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="5"&gt;
&lt;li&gt;Теперь при добавлении видео оно сразу будет адаптивным.&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="6"&gt;
&lt;li&gt;Это не всё. Добавим возможность включать полноэкранный режим.&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="7"&gt;
&lt;li&gt;В этом же файле находим код (~6327 строка):&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;var $video;
if (ytMatch &amp;amp;&amp;amp; ytMatch[1].length === 11) {
    var youtubeId = ytMatch[1];
    $video = $('&amp;lt;iframe&amp;gt;')
        .attr('frameborder', 0)
        .attr('src', '//www.youtube.com/embed/' + youtubeId)
        .attr('width', '640').attr('height', '360');&lt;/code&gt;&lt;/pre&gt;&lt;ol start="8"&gt;
&lt;li&gt;После последнего &lt;tt&gt;.attr&lt;/tt&gt; добавляем:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;.attr('allowfullscreen', '');&lt;/code&gt;&lt;/pre&gt;&lt;ol start="9"&gt;
&lt;li&gt;Сохраняем, обновляем кэш.&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="10"&gt;
&lt;li&gt;Готово.&lt;/li&gt;
&lt;/ol&gt;
</description>
</item>


</channel>
</rss>