<?xml version="1.0"?>
<rss version="2.0"><channel><title/><link>https://opencart.club/blogs/blog/1-opencart-diy-beri-i-delay/</link><description><![CDATA[<p>
	Очень часто магазину необходим новый функционал, но не хочется ставить готовый модуль с избыточным функционалом, а сделать всё своими руками.
</p>

<p>
	Постараюсь описать решения просто и пошагово. Надеюсь данная информация поможет владельцам магазинов и разработчикам
</p>
]]></description><language>ru</language><item><title>&#x423;&#x441;&#x442;&#x430;&#x43D;&#x43E;&#x432;&#x43A;&#x430; OpenCart 3 &#x447;&#x435;&#x440;&#x435;&#x437; ISPmanager - &#x427;&#x430;&#x441;&#x442;&#x44C; 1</title><link>https://opencart.club/blogs/entry/12-ustanovka-opencart-3-cherez-ispmanager-chast-1/</link><description><![CDATA[<p>
	<br><strong>Введение</strong><br>
	В данной статье содержится пошаговая инструкция для чистой установки OpenCart 3 club edition.<br>
	Будет использоваться vps/vds хостинг с панелью ISPmanager. Это одна из самых распространённых панелей управления для веб‑серверов. <br>
	 <br><strong>Добавляем новый сайт в панели ISPmanager</strong>
</p>

<p>
	<img alt="screen_001.png" class="ipsImage ipsImage_thumbnailed" data-fileid="2362" data-ratio="51.58" data-unique="qdmq02597" style="height: auto;" width="1200" data-src="https://opencart.club/uploads/monthly_2022_12/screen_001.png.827ef5993c1e5421bcdc64592577e0b7.png" src="https://opencart.club/applications/core/interface/js/spacer.png"></p>

<p>
	 
</p>

<p>
	Заполняем следующие поля:<br>
	1) Доменное имя<br>
	2) Режим работы PHP и версию PHP (В данном случае сразу выбран предпочтительный режим Nginx + PHP-FPM)<br>
	3) Выбираем "Создать новую базу"<br>
	4) Указываем имя новой БД и пользователя<br>
	5) Генерируем пароль<br>
	Сразу сохраните себе данные подключения к БД: Имя базы, логин пользователя и пароль. Эти данные нам понадобятся при установке.
</p>

<p>
	После этого нажимаем кнопку "Создать".
</p>

<p>
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="2363" href="https://opencart.club/uploads/monthly_2022_12/screen_002.png.f36ba4e50321934de0241472afba73e4.png" rel=""><img alt="screen_002.png" class="ipsImage ipsImage_thumbnailed" data-fileid="2363" data-ratio="104.46" data-unique="b9k25tgbh" style="height: auto;" width="718" data-src="https://opencart.club/uploads/monthly_2022_12/screen_002.thumb.png.2e272ab16e133ade14071a5e6fa99211.png" src="https://opencart.club/applications/core/interface/js/spacer.png"></a>
</p>

<p>
	 
</p>

<p>
	Следующим шагом будет предложено выпустить бесплатный Let’s Encrypt SSL-сертификат.<br>
	На данном шаге можно ничего не менять и нажать "Выпустить".<br>
	При необходимости, можно будет изменить SSL-сертификат сайта позже.
</p>

<p>
	<img alt="screen_003.png" class="ipsImage ipsImage_thumbnailed" data-fileid="2364" data-ratio="83.11" data-unique="aqsh8s4cr" style="height: auto;" width="758" data-src="https://opencart.club/uploads/monthly_2022_12/screen_003.png.41a3cb5e53b8f2a01b941ceede733484.png" src="https://opencart.club/applications/core/interface/js/spacer.png"></p>

<p>
	 
</p>

<p>
	Теперь ваш сайт уже будет доступен, хоть он ещё и пустой.
</p>

<p>
	<img alt="screen_004.png" class="ipsImage ipsImage_thumbnailed" data-fileid="2365" data-ratio="69.38" data-unique="sfg2cotp3" style="height: auto;" width="467" data-src="https://opencart.club/uploads/monthly_2022_12/screen_004.png.d58604c942377a8ed9f5b0c849f19414.png" src="https://opencart.club/applications/core/interface/js/spacer.png"></p>

<p>
	 
</p>

<p>
	 
</p>

<p>
	<strong>Копируем дистрибутив OpenCart 3 club edition на сервер</strong><br>
	Скопировать файлы дистрибутива на сервер можно через любой ftp клиент.<br>
	Но для этого нужно настроить в панели ftp доступ. Чтобы не усложнять и не увеличивать объём материала, в данной статье мы рассмотрим вариант загрузки файлов на сервер средствами панели ISPmanager.
</p>

<p>
	В первую очередь, чтобы избежать частой ошибки с правами доступа к файлам, нам лучше войти под пользователем www-root перед заливкой файлов.<br>
	Для этого идём в раздел "Пользователи". Выбираем пользователя "www-root" и нажимаем кнопку "Войти под пользователем".
</p>

<p>
	<img alt="screen_005.png" class="ipsImage ipsImage_thumbnailed" data-fileid="2366" data-ratio="46.00" data-unique="xeimno6pk" style="height: auto;" width="1200" data-src="https://opencart.club/uploads/monthly_2022_12/screen_005.png.7a35a23c2a76dddf492c7603aa91d1b2.png" src="https://opencart.club/applications/core/interface/js/spacer.png"></p>

<p>
	 
</p>

<p>
	В правом верхнем углу мы будем видеть текущего пользователя "www-root". <br>
	При необходимости, мы можем кликнуть на имени пользователя и выбрать "Вернуться в root".
</p>

<p>
	<img alt="screen_006.png" class="ipsImage ipsImage_thumbnailed" data-fileid="2367" data-ratio="69.77" data-unique="hy3xgrykq" style="height: auto;" width="397" data-src="https://opencart.club/uploads/monthly_2022_12/screen_006.png.f39afb1ed66a58d0d8f24b8bc826fdce.png" src="https://opencart.club/applications/core/interface/js/spacer.png"></p>

<p>
	 
</p>

<p>
	Для заливки дистрибутива OpenCart на сервер нам нужно перейти в раздел "Менеджер файлов".<br>
	В менеджере файлов переходим в папку "www" двойным кликом мышки по выделенной области.
</p>

<p>
	<img alt="screen_007.png" class="ipsImage ipsImage_thumbnailed" data-fileid="2368" data-ratio="59.75" data-unique="bjmromwxf" style="height: auto;" width="1200" data-src="https://opencart.club/uploads/monthly_2022_12/screen_007.png.0b2da5b6b08174fa6ada234cd214f6e9.png" src="https://opencart.club/applications/core/interface/js/spacer.png"></p>

<p>
	 
</p>

<p>
	Там мы увидим уже созданную папку с названием домена вашего сайта. В примере это "mysite.ru".
</p>

<p>
	<img alt="screen_008.png" class="ipsImage ipsImage_thumbnailed" data-fileid="2369" data-ratio="48.67" data-unique="firlmehyq" style="height: auto;" width="1200" data-src="https://opencart.club/uploads/monthly_2022_12/screen_008.png.c2a2651519881df201077086c0530ed3.png" src="https://opencart.club/applications/core/interface/js/spacer.png"></p>

<p>
	 
</p>

<p>
	Заходим в эту папку и приступаем к заливке дистрибутива OpenCart 3 club edition на сервер.<br>
	Для этого нажимаем кнопку "Загрузить"
</p>

<p>
	<img alt="screen_009.png" class="ipsImage ipsImage_thumbnailed" data-fileid="2370" data-ratio="48.67" data-unique="6z40w1zxj" style="height: auto;" width="1200" data-src="https://opencart.club/uploads/monthly_2022_12/screen_009.png.9098bd7c1b83147b4aaeed33ebfa7bff.png" src="https://opencart.club/applications/core/interface/js/spacer.png"></p>

<p>
	 
</p>

<p>
	Дальше нажимаем "Выберите файл" и указываем путь к архиву дистрибутива.<br>
	Актуальную версию сборки OpenCart 3 club edition можно скачать [тут].
</p>

<p>
	<img alt="screen_010.png" class="ipsImage ipsImage_thumbnailed" data-fileid="2371" data-ratio="56.07" data-unique="sfdaa0ea8" style="height: auto;" width="749" data-src="https://opencart.club/uploads/monthly_2022_12/screen_010.png.0ac89eff2af233b014feac37ab20fbd8.png" src="https://opencart.club/applications/core/interface/js/spacer.png"></p>

<p>
	 
</p>

<p>
	После выбора пути к архиву нажимаем кнопку "Загрузить".
</p>

<p>
	<img alt="screen_011.png" class="ipsImage ipsImage_thumbnailed" data-fileid="2372" data-ratio="56.07" data-unique="rjiz6dupz" style="height: auto;" width="749" data-src="https://opencart.club/uploads/monthly_2022_12/screen_011.png.54caf1fbdab2ae1111073ff58a7401e6.png" src="https://opencart.club/applications/core/interface/js/spacer.png"></p>

<p>
	 
</p>

<p>
	После завершения загрузки получаем следующую картину:
</p>

<p>
	<img alt="screen_012.png" class="ipsImage ipsImage_thumbnailed" data-fileid="2373" data-ratio="47.67" data-unique="smo3ylf9y" style="height: auto;" width="1200" data-src="https://opencart.club/uploads/monthly_2022_12/screen_012.png.435d1dc55cac4e2a7a65d757238f3e10.png" src="https://opencart.club/applications/core/interface/js/spacer.png"></p>

<p>
	 
</p>

<p>
	Теперь нам необходимо распаковать архив в текущую папку.<br>
	Для этого выделяем загруженный архив. Далее кликаем на меню "Архив" и нажимаем "Извлечь".
</p>

<p>
	<img alt="screen_013.png" class="ipsImage ipsImage_thumbnailed" data-fileid="2374" data-ratio="47.67" data-unique="fx3gbpghr" style="height: auto;" width="1200" data-src="https://opencart.club/uploads/monthly_2022_12/screen_013.png.ecc5cf5e0481defec120f3e6c82bcba7.png" src="https://opencart.club/applications/core/interface/js/spacer.png"></p>

<p>
	 
</p>

<p>
	На следующем шаге нам ничего не нужно менять. Просто нажимаем кнопку "Распаковать".
</p>

<p>
	 
</p>

<p>
	<img alt="screen_014.png" class="ipsImage ipsImage_thumbnailed" data-fileid="2385" data-ratio="59.25" data-unique="8smn08b1m" style="height: auto;" width="1200" data-src="https://opencart.club/uploads/monthly_2022_12/screen_014.png.66f4dd8b21afc22db9efc06f9ba6d6eb.png" src="https://opencart.club/applications/core/interface/js/spacer.png"></p>

<p>
	 
</p>

<p>
	После распаковки мы получим следующую картину:
</p>

<p>
	<img alt="screen_015.png" class="ipsImage ipsImage_thumbnailed" data-fileid="2376" data-ratio="59.25" data-unique="fftbzfcee" style="height: auto;" width="1200" data-src="https://opencart.club/uploads/monthly_2022_12/screen_015.png.c4f7d210182296a38218164428244214.png" src="https://opencart.club/applications/core/interface/js/spacer.png"></p>

<p>
	 
</p>

<p>
	В данной ситуации есть очень неудобный момент, что все нужные нам файлы дистрибутива лежат в папке upload, а все лежащие в корневой папке файлы нам не нужны.<br>
	Если вы опытный пользователь ПК, то вы можете перепаковать архив у себя на компьютере и залить на хостинг архив только с содержимым папки upload.<br>
	Но, для примера, рассмотрим вариант, как решить данный вопрос без перепаковки архива на локальном компьютере. Это также поможет вам немного улучшить навыки работы в панели управления ISPmanager.
</p>

<p>
	Для начала нам необходимо удалить всё ненужное в корневой папке, кроме папки upload.<br>
	Для этого выделяем всё ненужное, потом нажимаем на меню "Редактировать", и "Удалить". Потом подтверждаем удаление во всплывающем диалоге.
</p>

<p>
	<img alt="screen_016.png" class="ipsImage ipsImage_thumbnailed" data-fileid="2377" data-ratio="59.50" data-unique="4c5ugabf8" style="height: auto;" width="1200" data-src="https://opencart.club/uploads/monthly_2022_12/screen_016.png.a66107b8d3e042b5109fee1e2f37ede7.png" src="https://opencart.club/applications/core/interface/js/spacer.png"></p>

<p>
	 
</p>

<p>
	Дальше заходим в папку upload (два раза кликнув мышкой на названии папки).<br>
	Выбираем всё содержимое папки и нажимаем кнопку "Копировать".
</p>

<p>
	<img alt="screen_017.png" class="ipsImage ipsImage_thumbnailed" data-fileid="2378" data-ratio="59.50" data-unique="vs7e2gccp" style="height: auto;" width="1200" data-src="https://opencart.club/uploads/monthly_2022_12/screen_017.png.c633ea423f4b9d392c6e4af092e80dcc.png" src="https://opencart.club/applications/core/interface/js/spacer.png"></p>

<p>
	 
</p>

<p>
	Теперь очень внимательно выполняем последовательность действий: 
</p>

<ul><li>
		выбрать корневую папку с сайтом (она будет подсвечена)
	</li>
	<li>
		поставить галочку "Перенести файлы"
	</li>
	<li>
		поставить галочку "Перейти в выбранный каталог"
	</li>
	<li>
		нажать кнопку "Копировать"
	</li>
</ul><p>
	<img alt="screen_018.png" class="ipsImage ipsImage_thumbnailed" data-fileid="2379" data-ratio="59.50" data-unique="ngfzd5zmp" style="height: auto;" width="1200" data-src="https://opencart.club/uploads/monthly_2022_12/screen_018.png.60047b4b7ef5932db45d8382db5452d9.png" src="https://opencart.club/applications/core/interface/js/spacer.png"></p>

<p>
	 
</p>

<p>
	Осталось сделать небольшие шаги, и можно будет приступать непосредственно к установке OpenCart 3 club edition.<br>
	Нам нужно удалить теперь уже пустой каталог upload. Выделяем его и удаляем способом, описанным выше.
</p>

<p>
	Далее нам необходимо переименовать два конфигурационых файла. Меняем название файла "config-dist.php" на "config.php".<br>
	И повторяем то же самое с файлом "config-dist.php" в папке "admin".<br>
	Для этого можно при наведении словить иконку карандаша и кликнуть для изменения имени.
</p>

<p>
	<img alt="screen_019.png" class="ipsImage ipsImage_thumbnailed" data-fileid="2380" data-ratio="58.39" data-unique="gh7iw4xk8" style="height: auto;" width="423" data-src="https://opencart.club/uploads/monthly_2022_12/screen_019.png.ed05db8a7c63ef8ed19c16901c3c9af2.png" src="https://opencart.club/applications/core/interface/js/spacer.png"></p>

<p>
	 
</p>

<p>
	Можно изменить имя и другим способом, чтобы не ловить небольшую иконку мышкой.<br>
	Выделяем файл "config-dist.php", кликаем на меню "Редактировать" и выбираем "Атрибуты".
</p>

<p>
	<img alt="screen_020.png" class="ipsImage ipsImage_thumbnailed" data-fileid="2381" data-ratio="59.92" data-unique="0s9bmhbhy" style="height: auto;" width="1200" data-src="https://opencart.club/uploads/monthly_2022_12/screen_020.png.ffd7f41597d572a70f2ca7310bdfe97a.png" src="https://opencart.club/applications/core/interface/js/spacer.png"></p>

<p>
	 
</p>

<p>
	В поле "Имя" меняем имя файла на "config.php" и жмём кнопку "Сохранить".
</p>

<p>
	<img alt="screen_021.png" class="ipsImage ipsImage_thumbnailed" data-fileid="2382" data-ratio="59.92" data-unique="kjjy9tv1j" style="height: auto;" width="1200" data-src="https://opencart.club/uploads/monthly_2022_12/screen_021.png.f790397755cbba78c35ff8e360033bad.png" src="https://opencart.club/applications/core/interface/js/spacer.png"></p>

<p>
	 
</p>

<p>
	В итоге мы получаем такой список файлов:
</p>

<p>
	<img alt="screen_022.png" class="ipsImage ipsImage_thumbnailed" data-fileid="2383" data-ratio="59.50" data-unique="ok6x9ztly" style="height: auto;" width="1200" data-src="https://opencart.club/uploads/monthly_2022_12/screen_022.png.cb03a2c3547bf20421cc0d4f94f2635b.png" src="https://opencart.club/applications/core/interface/js/spacer.png"></p>

<p>
	 
</p>

<p>
	Далее заходим в папку "admin" и повторяем смену названия для файла "config-dist.php" в этой папке.<br>
	После этого содержимое папки "admin" должно выглядеть так:
</p>

<p>
	<img alt="screen_023.png" class="ipsImage ipsImage_thumbnailed" data-fileid="2384" data-ratio="59.50" data-unique="egn3iw1sl" style="height: auto;" width="1200" data-src="https://opencart.club/uploads/monthly_2022_12/screen_023.png.ce04c75ff096581f48904cd0b79bb534.png" src="https://opencart.club/applications/core/interface/js/spacer.png"></p>

<p>
	 
</p>

<p>
	<strong>Финиш</strong>
</p>

<p>
	Всё. На этом все наши действия в панели управления выполнены. Для начала установки переходим на наш сайт "http://mysite.ru/" и выполняем установку OpenCart 3 club edition.<br>
	В следующей статье будет рассмотрен процесс непосредственно установки самой CMS.
</p>

<p>
	 
</p>

<p>
	Очень полезная рекомендация: Не оставляйте на ftp ненужные файлы, бекапы, архивы с дистрибутивами и прочее. Держите файлы вашего сайта в чистоте и порядке, чтобы избежать ненужных проблем в будущем.<br>
	 
</p>
]]></description><guid isPermaLink="false">12</guid><pubDate>Wed, 14 Dec 2022 09:47:25 +0000</pubDate></item><item><title>&#x41F;&#x440;&#x438;&#x43B;&#x438;&#x43F;&#x430;&#x44E;&#x449;&#x430;&#x44F; &#x43F;&#x430;&#x43D;&#x435;&#x43B;&#x44C; &#x432; &#x442;&#x43E;&#x432;&#x430;&#x440;&#x435; &#x441; &#x43A;&#x430;&#x440;&#x442;&#x438;&#x43D;&#x43A;&#x43E;&#x439;, &#x43D;&#x430;&#x437;&#x432;&#x430;&#x43D;&#x438;&#x435;&#x43C;, &#x446;&#x435;&#x43D;&#x43E;&#x439; &#x438; &#x43A;&#x43D;&#x43E;&#x43F;&#x43A;&#x43E;&#x439; &#x43F;&#x43E;&#x43A;&#x443;&#x43F;&#x43A;&#x438;</title><link>https://opencart.club/blogs/entry/3-prilipayuschaya-panel-v-tovare-s-kartinkoy-nazvaniem-cenoy-i-knopkoy-pokupki/</link><description><![CDATA[<p>
	При покупке товаров в интернет-магазинах, большинство клиентов изучают товар более подробно, просматривая характеристики и описание, пролистывая при этом карточку товара. И когда после изучения всех необходимых подробностей клиент готов купить товар, кнопка покупки уже находится далеко за пределами экрана, что заставляет совершать покупателя дополнительные действия по поиску данной кнопки, чтобы иметь возможность добавить товар в корзину.
</p>

<p>
	 
</p>

<p>
	Эту задачу своим клиентам вы можете упростить, сделав на странице товара небольшую прилипающую панель с названием товара, ценой и кнопкой добавления в корзину, которая будет появляться при исчезновении стационарной кнопки покупки за пределами экрана.
</p>

<p>
	 
</p>

<p>
	<img alt="diy_002_preview1.png" class="ipsImage ipsImage_thumbnailed" data-fileid="432" data-ratio="32.74" data-unique="jwg6pm724" style="height: auto;" width="391" data-src="https://opencart.club/uploads/monthly_2022_05/diy_002_preview1.png.d2f70c859f0970b7131567bbb73b579a.png" src="https://opencart.club/applications/core/interface/js/spacer.png"></p>

<p>
	<br>
	Данное нововведение вполне может повлиять на конверсию для вашего интернет-магазина на OpenCart, конечно же, в сторону её увеличения.
</p>

<p>
	Посмотреть готовый пример такой реализации можно <a href="https://ocs3020.mpn-oc.org/canon-eos-5d#tab-description" rel="external nofollow" target="_blank">по ссылке</a>.<br>
	Как только кнопка покупки уходит за верхнюю границу экрана, внизу показывается прилипающая панель с необходимыми данными.
</p>

<div class="ipsSpoiler" data-ipsspoiler="">
	<div class="ipsSpoiler_header">
		<span>Спойлер</span>
	</div>

	<div class="ipsSpoiler_contents ipsClearfix" data-gramm="false">
		<p>
			<img alt="diy_002_preview2.png" class="ipsImage ipsImage_thumbnailed" data-fileid="433" data-ratio="27.33" data-unique="w38qpb3h4" style="height: auto;" width="849" data-src="https://opencart.club/uploads/monthly_2022_05/diy_002_preview2.png.f7d6aacb2f84551023e24b8afdd74217.png" src="https://opencart.club/applications/core/interface/js/spacer.png"></p>
	</div>
</div>

<p>
	 
</p>

<p>
	В данной статье будут описаны основные шаги по созданию такого функционала своими руками. Ссылку на готовый пример в виде модуля для OpenCart3 вы сможете найти в конце статьи.<br>
	При желании, адаптировать модификатор для других версий OpenCart не составит особого труда.
</p>

<p>
	 
</p>

<p>
	Приступим к созданию.
</p>

<p>
	Для начала в файле шаблона <strong>catalog/view/theme/default/template/product/product.twig</strong> добавим сразу после строки:
</p>

<pre class="ipsCode" id="ips_uid_5053_8">{{ header }}</pre>

<p>
	HTML блок со всеми необходимыми нам данными:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_5053_10" style=""><span class="tag">&lt;div</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"psp-wrap"</span><span class="pln"> </span><span class="atn">id</span><span class="pun">=</span><span class="atv">"product-sticky-panel"</span><span class="tag">&gt;</span><span class="pln">
  </span><span class="tag">&lt;div</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"container"</span><span class="tag">&gt;</span><span class="pln">
    </span><span class="tag">&lt;div</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"psp-content"</span><span class="tag">&gt;</span><span class="pln">
      ...
    </span><span class="tag">&lt;/div&gt;</span><span class="pln">
  </span><span class="tag">&lt;/div&gt;</span><span class="pln">
</span><span class="tag">&lt;/div&gt;</span></pre>

<p>
	<br>
	Код сокращён для наглядности. Полный исходный код можно посмотреть по ссылке в конце статьи.
</p>

<p>
	 
</p>

<p>
	Теперь нам нужно добавить необходимые стили.<br>
	Для начала сделаем нашу панель прилипающей. Для этого будем использовать position: sticky (заодно пропишем нужные правила для позиционирования нашей панели)
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_5053_12" style=""><span class="pln">.psp-wrap { position: sticky; top: 0; left: 0; right: 0; z-index: 999; }</span></pre>

<p>
	 
</p>

<p>
	С такими стилями наша панель будет отображаться всегда, а при скроле будет прилипать к верху экрана.<br>
	Такая реализация не совсем подходит для поставленной цели. Поэтому скроем нашу панель по умолчанию:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_5053_14" style=""><span class="pln">.psp-wrap:not(.active) { display: none; }</span></pre>

<p>
	<br><span style="color:#c0392b;"><strong>!ВНИМАНИЕ!</strong></span> В исходном коде модуля-примера все стили помещаются в &lt;head&gt; страницы. Если стили будут переноситься в css файл, то стиль скрытия надо обязательно оставить в секции &lt;head&gt;, иначе наша панель будет видна, пока не подгрузится файл стилей, а это увеличит совокупное смещение макета (CLS), что соответственно снизит оценку PageSpeed.
</p>

<p>
	 
</p>

<p>
	Теперь наша панель скрыта.
</p>

<p>
	Дело остаётся за небольшим скриптом, который добавит нужный класс active для нашей панели в от момент, когда кнопка покупки спрячется за верхней границей экрана.<br>
	Задача довольно простая, поэтому её лучше решить без использования jQuery. Для данной задачи нам также не нужно активное отслеживание событий onscroll, поэтому здесь как нельзя лучше подойдёт Intersection Observer API. Подробный разбор скрипта в этой статье не приводится, т.к. в интернете хватает документации и примеров по использованию данного API.
</p>

<p>
	<br>
	Действия по отслеживанию будут выполняться вот таким скриптом:
</p>

<pre class="ipsCode" id="ips_uid_5053_16">document.addEventListener('DOMContentLoaded', () =&gt; {
  let target = document.querySelector('#button-cart');
  let psp = document.querySelector('#product-sticky-panel');
  target &amp;&amp; psp &amp;&amp; new IntersectionObserver(([e]) =&gt; psp.classList.toggle('active', e.boundingClientRect.y &lt; 0), {
    threshold:1.0
  }).observe(target);
});</pre>

<p>
	 
</p>

<p>
	Полный код этой несложной модификации можно скачать вот тут:
</p>
<iframe allowfullscreen="" class="ipsEmbed_finishedLoading" data-embedauthorid="26" data-embedcontent="" data-embedid="embed194861078" scrolling="no" src="https://opencart.club/applications/core/interface/index.html" style="overflow: hidden; height: 488px; max-width: 500px;" data-embed-src="https://opencart.club/files/file/96-prilipayuschaya-panel-v-tovare-s-kartinkoy-nazvaniem-cenoy-i-knopkoy-pokupki/?do=embed"></iframe>]]></description><guid isPermaLink="false">3</guid><pubDate>Mon, 09 May 2022 00:00:00 +0000</pubDate></item><item><title>&#x41D;&#x430;&#x441;&#x442;&#x440;&#x43E;&#x439;&#x43A;&#x430; NGINX &#x432; &#x440;&#x435;&#x436;&#x438;&#x43C;&#x435; PHP-FPM &#x434;&#x43B;&#x44F; &#x440;&#x430;&#x431;&#x43E;&#x442;&#x44B; OpenCart</title><link>https://opencart.club/blogs/entry/2-nastroyka-nginx-v-rezhime-php-fpm-dlya-raboty-opencart/</link><description><![CDATA[<p>
	Веб сервер nginx позволяет работать в разных режимах, как с использованием интерпретатора php, так и без.<br>
	Для работы <strong>OpenCart</strong> лучше выбирать оптимальный режим работы <strong>php-fpm</strong>. Многих данный режим пугает тем, что в данном случае<br>
	файл <strong>htaccess</strong> напрочь игнорируется и все необходимые настройки нужно вносить в конфиг <strong>nginx</strong>.<br>
	Но в этом нет ничего сверх сложного. Конфигурационный файл - это обычный текстовый файл на сервере, который <br>
	подчиняется определённым правилам. И по данному поводу можно найти много готовых описаний и инструкций.
</p>

<p>
	<br>
	Данная статья не претендует на уникальность, а просто представляет краткую выжимку по настройкам, учитывая особенности <br>
	работы с движком <strong>OpenCart</strong> и сборками на его основе.
</p>

<p>
	 
</p>

<p>
	Для удобства будут приводится примеры настройки с использованием панели ISPmanager.<br>
	Основные настройки будут касаться секции location, и зависимость описания от используемой панели будет минимальной.
</p>

<p>
	 
</p>

<p>
	Для начала переведём nginx в режим работы <strong>php-fpm</strong>. Для этого в панели сделаем следующие настройки разделе <strong>WWW-домены</strong> для <br>
	нужного сайта:
</p>

<p>
	1. Выбираем в списке нужный сайт, если их несколько, и жмём кнопку "Изменить".<br>
	2. Находим настройки PHP и настраиваем следующим образом:<br><img alt="diy003_001.png" class="ipsImage ipsImage_thumbnailed" data-fileid="264" data-ratio="41.56" data-unique="3hxsudx6q" style="height: auto;" width="409" data-src="https://opencart.club/uploads/monthly_2022_04/diy003_001.png.7476545a113a3dd22adc4f72293cf592.png" src="https://opencart.club/applications/core/interface/js/spacer.png"></p>

<p>
	Обратите внимание, что версия <strong>php</strong> у вас может отличаться. При необходимости, можно эту версию изменить на нужную, но этот вопрос выходит за рамки данной статьи.
</p>

<p>
	После сохранения настроек будет работать почти всё, что и раньше. Если в настройках <strong>OpenCart</strong> отключены ЧПУ ссылки, то всё будет работать, как<br>
	и работало до переключения режима работы.<br>
	Теперь можно приступать к непосредственной настройке самого конфигурационного файла nginx для текущего сайта.<br>
	Для этого в списке www доменов находим нужный нам и нажимаем справа на иконку с тремя точками. В выпадающем меню выбираем<br>
	пункт "Конфиг":
</p>

<div class="ipsSpoiler" data-ipsspoiler="">
	<div class="ipsSpoiler_header">
		<span>Спойлер</span>
	</div>

	<div class="ipsSpoiler_contents ipsClearfix" data-gramm="false">
		<p>
			<img alt="diy003_002.png" class="ipsImage ipsImage_thumbnailed" data-fileid="265" data-ratio="43.33" data-unique="j84kr7mwp" style="height: auto;" width="1200" data-src="https://opencart.club/uploads/monthly_2022_04/diy003_002.png.e60108cca27060c0d3fad69e7e370d3b.png" src="https://opencart.club/applications/core/interface/js/spacer.png"></p>
	</div>
</div>

<p>
	 
</p>

<p>
	Вот примерный конфигурационный файл, который будет создан у вас по умолчанию:
</p>

<div class="ipsSpoiler" data-ipsspoiler="">
	<div class="ipsSpoiler_header">
		<span>Спойлер</span>
	</div>

	<div class="ipsSpoiler_contents ipsClearfix" data-gramm="false">
		<pre class="ipsCode" id="ips_uid_1189_10">server {
    server_name test.ru www.test.ru;
    charset off;
    index index.php index.html;
    disable_symlinks if_not_owner from=$root_path;
    include /etc/nginx/vhosts-includes/*.conf;
    include /etc/nginx/vhosts-resources/test.ru/*.conf;
    access_log /var/www/httpd-logs/test.ru.access.log;
    error_log /var/www/httpd-logs/test.ru.error.log notice;
    ssi on;
    set $root_path /var/www/myoc/data/www/test.ru;
    root $root_path;
    location / {
        location ~ [^/]\.ph(p\d*|tml)$ {
            try_files /does_not_exists @php;
        }
        location ~* ^.+\.(jpg|jpeg|gif|png|svg|js|css|mp3|ogg|mpe?g|avi|zip|gz|bz2?|rar|swf)$ {
            expires 365d;
        }
    }
    location @php {
        fastcgi_index index.php;
        fastcgi_param PHP_ADMIN_VALUE "sendmail_path = /usr/sbin/sendmail -t -i -f webmaster@test.ru";
        fastcgi_pass unix:/var/www/php-fpm/myoc.sock;
        fastcgi_split_path_info ^((?U).+\.ph(?:p\d*|tml))(/?.+)$;
        try_files $uri =404;
        include fastcgi_params;
    }
    listen 8.8.8.8:80;
}
server {
    server_name test.ru www.test.ru;
    ssl_certificate "/var/www/httpd-cert/myoc/test.ru.crt";
    ssl_certificate_key "/var/www/httpd-cert/myoc/test.ru.key";
    ssl_ciphers EECDH:+AES256:-3DES:RSA+AES:!NULL:!RC4;
    ssl_prefer_server_ciphers on;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
    add_header Strict-Transport-Security "max-age=31536000;";
    ssl_dhparam /etc/ssl/certs/dhparam4096.pem;
    charset off;
    index index.php index.html;
    disable_symlinks if_not_owner from=$root_path;
    include /etc/nginx/vhosts-includes/*.conf;
    include /etc/nginx/vhosts-resources/test.ru/*.conf;
    access_log /var/www/httpd-logs/test.ru.access.log;
    error_log /var/www/httpd-logs/test.ru.error.log notice;
    ssi on;
    set $root_path /var/www/myoc/data/www/test.ru;
    root $root_path;
    listen 8.8.8.8:443 ssl http2;
    location / {
        location ~ [^/]\.ph(p\d*|tml)$ {
            try_files /does_not_exists @php;
        }
        location ~* ^.+\.(jpg|jpeg|gif|png|svg|js|css|mp3|ogg|mpe?g|avi|zip|gz|bz2?|rar|swf)$ {
            expires 365d;
        }
    }
    location @php {
        fastcgi_index index.php;
        fastcgi_param PHP_ADMIN_VALUE "sendmail_path = /usr/sbin/sendmail -t -i -f webmaster@test.ru";
        fastcgi_pass unix:/var/www/php-fpm/myoc.sock;
        fastcgi_split_path_info ^((?U).+\.ph(?:p\d*|tml))(/?.+)$;
        try_files $uri =404;
        include fastcgi_params;
    }
}</pre>
	</div>
</div>

<p>
	<br>
	В конфигурации у вас будет две секции <strong>server</strong>, если у вас включено защищённое соединение SSL (и оно должно быть обязательно включено).<br>
	Если у вас включен принудительный редирект с http на https, то можно редактировать только секцию <strong>server</strong> для https.<br>
	Определить её легко: в самом начале есть параметр с указанием сертификата ssl_certificate. Также в этой секции указан параметр <strong>listen</strong> с указанием порта 443:<br>
	 
</p>

<pre class="ipsCode" id="ips_uid_689_8">listen 8.8.8.8:443 ssl</pre>

<p>
	Но лучше делать настройки сразу в двух секциях <strong>server</strong>, чтобы не допустить механической ошибки.<br>
	На данный момент нас интересует вот эта часть конфигурационного файла:
</p>

<pre class="ipsCode" id="ips_uid_1189_17">location / {
    location ~ [^/]\.ph(p\d*|tml)$ {
        try_files /does_not_exists @php;
    }
    location ~* ^.+\.(jpg|jpeg|gif|png|svg|js|css|mp3|ogg|mpe?g|avi|zip|gz|bz2?|rar|swf)$ {
        expires 365d;
    }
}</pre>

<p>
	<br>
	Все дальнейшие изменения мы будем вносить внутри этой секции "location /".
</p>

<p>
	В первую очередь нам не хватает вот такой директивы:
</p>

<pre class="ipsCode" id="ips_uid_1189_14">if (!-e $request_filename){
    rewrite ^/(.+)$ /index.php?_route_=$1 last;
}</pre>

<p>
	<br>
	Данное условие очень простое: если сервер не может найти файл по указанному в запросе пути, то запрос будет переписан на вызов index.php, а в параметр _route_ будет передан запрашиваемый путь. Именно это и позволит корректно отрабатывать всем ЧПУ ссылкам движка.<br>
	Это правило является аналогом записи в файле htaccess:
</p>

<pre class="ipsCode" id="ips_uid_1189_43">RewriteRule ^([^?]*) index.php?_route_=$1 [L,QSA]</pre>

<p>
	<br>
	На этом можно было бы и закончить, но стоит внести ещё некоторые изменения для улучшения безопасности.
</p>

<p>
	Рассмотрим более внимательно вот эту секцию:
</p>

<pre class="ipsCode" id="ips_uid_1189_41">location ~ [^/]\.ph(p\d*|tml)$ {</pre>

<p>
	<br>
	Тут отбираются все все подходящие динамические файлы с типами <strong>.php</strong> (в том числе с числами в окончании) и <strong>.phtml</strong><br>
	Но у движка <strong>OpenCart</strong> в штатном режиме есть всего две точки входа для вызова <strong>php</strong> файлов через web окружение - это <strong>index.php</strong> и <strong>admin/index.php</strong><br>
	Есть ещё <strong>install/index.php</strong>, но она используется только при установке движка.<br>
	Учитывая данные обстоятельства, логично запретить прямое выполнение всех остальных <strong>php</strong> скриптов через web окружение, кроме указанных администратором.<br>
	Сделать это можно следующим образом:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_1189_23" style=""><span class="pln">location ~ ^/(index|admin/index|install/index)\.php {
    try_files /does_not_exists @php;
}</span></pre>

<p>
	<br>
	В скобках через разделитель "|" указываем все php скрипты, которые можно выполнять. После завершения установки можно будет сократить это список <br>
	до такого: <strong>(index|admin/index)</strong>
</p>

<p>
	<strong>ВНИМАНИЕ!!! Очень важный момент! </strong>После того, как убрали вызов интерпретатора php для всех файлов, кроме указанных, при попытке запроса любого другого php файла <span style="color:#d35400;"><strong>он будет отдан как обычный текстовый файл</strong></span>.<br>
	И при запросе <span ipsnoautolink="true">https://test.ru/config.php</span> любой желающий сможет получить содержимое вашего конфигурационного файла, где содержится доступ к БД.<br>
	Поэтому нам обязательно нужно запретить доступ для всех остальных файлов с расширением <strong>php</strong>. Ну и заодно к другим типам файлов, которые не<br>
	стоит отдавать по запросу извне. Сделать это можно простым правилом:
</p>

<pre class="ipsCode" id="ips_uid_1189_39">location ~* \.(php|log|tpl|txt|twig|xml|ini)$ {
    deny all;
}</pre>

<p>
	<br>
	В скобках через разделитель "|" указываем все расширения файлов, которые мы хотим запретить.<br>
	Но у нас есть несколько важных файлов, которые пока попали под запрет, например: <strong>robots.txt</strong> и <strong>sitemap.xml</strong>. Этот вопрос мы решим чуть позже.<br>
	А сейчас ещё немного запретов. Запретим открывать файлы, которые начинаются с точки, а также все файлы в папке <strong>system</strong>:
</p>

<pre class="ipsCode" id="ips_uid_1189_33">location ~ /\. {
    deny all;
}
location ~ ^/system/ {
    deny all;
}</pre>

<p>
	<br>
	Этих запретов вполне достаточно, чтобы сделать невозможным выполнение каких-либо несанкционированных скриптов. А также просмотр логов, текстовых и xml файлов.
</p>

<p>
	 
</p>

<p>
	Теперь нам необходимо открыть доступ к файлу robots.txt, для этого нам нужно такое правило:
</p>

<pre class="ipsCode" id="ips_uid_1189_35">location = /robots.txt {
    allow all;
}</pre>

<p>
	 
</p>

<p>
	Также пропишем разрешение на открытие sitemap.xml и rewrite правило:
</p>

<pre class="ipsCode" id="ips_uid_1189_37">location = /sitemap.xml {
    allow all;
    rewrite ^/(.*)$ /index.php?route=extension/feed/google_sitemap last;
}</pre>

<p>
	<br>
	Если вы используете сторонний модуль сайтмапа, то нужно указать соответствующий route для данного модуля.<br>
	Если у вас несколько файлов sitemap или вы используете фиды для выгрузки данных, то просто пропишите для них права по аналогии.
</p>

<p>
	В итоге мы должны получить вот такую секцию location:
</p>

<div class="ipsSpoiler" data-ipsspoiler="">
	<div class="ipsSpoiler_header">
		<span>Спойлер</span>
	</div>

	<div class="ipsSpoiler_contents ipsClearfix" data-gramm="false">
		<pre class="ipsCode" id="ips_uid_1189_45">location / {
    if (!-e $request_filename){
        rewrite ^/(.+)$ /index.php?_route_=$1 last;
    }

    location ~ ^/(index|admin/index)\.php {
        try_files /does_not_exists @php;
    }

    location = /sitemap.xml {
        allow all;
        rewrite ^/(.*)$ /index.php?route=extension/feed/google_sitemap last;
    }
    location = /robots.txt {
        allow all;
    }

    location ~ /\. {
        deny all;
    }
    location ~ ^/system/ {
        deny all;
    }
    location ~* \.(php|log|tpl|txt|twig|xml|ini)$ {
        deny all;
    }

    location ~* ^.+\.(jpg|jpeg|gif|png|svg|webp|js|css|mp3|ogg|mpe?g|avi|zip|gz|bz2?|rar|swf)$ {
        expires 365d;
    }
}</pre>
	</div>
</div>

<p>
	<br>
	Этих настроек достаточно для корректной работы движка <strong>OpenCart</strong>. И при этом данная конфигурация является безопасной с точки зрения выполнения <br>
	несанкционированных скриптов php через web окружение.
</p>

<p>
	После всех настроек обязательно проверьте правильность работы, сделав запросы по указанному чек-листу (test.ru замените на адрес вашего сайта):
</p>

<pre class="ipsCode" id="ips_uid_3668_7">https://test.ru/config.php
https://test.ru/admin/config.php
https://test.ru/admin/1.php
https://test.ru/admin/1.txt
https://test.ru/admin/1.log
https://test.ru/admin/1.xml
https://test.ru/system/modification.xml</pre>

<p>
	<br>
	Для всех этих ссылок вы должны получить ошибку "403 Forbidden", вне зависимости от того, есть файл по указанному пути на сервере, или нет.
</p>

<p>
	Также проверяем белый список:
</p>

<pre class="ipsCode" id="ips_uid_3668_9">https://test.ru/robots.txt
https://test.ru/sitemap.xml</pre>

<p>
	<br>
	Эти файлы не должны вызывать ошибок и вы должны корректно получать их содержимое.<br>
	Дополнительно стоит проверить все ваши дополнительные сайтмапы или фиды, если вы их добавляли.
</p>

<p>
	 
</p>

<p>
	Ещё раз повторюсь, что данная настройка является базовой, с небольшими правилами для улучшения безопасности.<br>
	Но даже уже при такой настройке вы в среднем получите выигрыш 100-200ms для параметра TTFB, по сравнению с остальными режимами работы.
</p>
]]></description><guid isPermaLink="false">2</guid><pubDate>Mon, 25 Apr 2022 14:02:00 +0000</pubDate></item><item><title>&#x410;&#x432;&#x442;&#x43E;&#x43C;&#x430;&#x442;&#x438;&#x447;&#x435;&#x441;&#x43A;&#x438;&#x439; &#x432;&#x44B;&#x432;&#x43E;&#x434; &#x442;&#x43E;&#x432;&#x430;&#x440;&#x43E;&#x432; &#x43A;&#x43E;&#x43B;&#x43B;&#x435;&#x43A;&#x446;&#x438;&#x438; &#x432; &#x440;&#x435;&#x43A;&#x43E;&#x43C;&#x435;&#x43D;&#x434;&#x443;&#x435;&#x43C;&#x44B;&#x435; &#x442;&#x43E;&#x432;&#x430;&#x440;&#x44B;</title><link>https://opencart.club/blogs/entry/1-avtomaticheskiy-vyvod-tovarov-kollekcii-v-rekomenduemye-tovary/</link><description><![CDATA[<p>
	Для различных типов товаров часто возникает необходимость вывести товары в рекомендуемые <strong>автоматически, по определённому критерию</strong>. Нередко товары группируются по коллекциям, но штатными средствами <strong>OpenCart</strong> нет возможности их корректно объединить и добавить автоматически друг к другу как рекомендуемые товары. 
</p>

<p>
	Эта небольшая доработка позволяет без дополнительных модулей реализовать вывод товаров коллекции в рекомендуемые автоматически, и избавляет вас от необходимости добавлять каждый товар друг к другу вручную.
</p>

<p>
	Данная доработка не затрагивает шаблоны, поэтому подходит для любой версии движка и сборки.
</p>

<p>
	 
</p>

<p>
	Для примера рассматривается вариант объединения в коллекции по совпадению поля EAN. 
</p>

<p>
	По принципу - если поле EAN не пустое, то выводим такие товары в рекомендуемые.
</p>

<p>
	 
</p>

<p>
	В файле <strong>catalog/controller/product/product.php</strong>
</p>

<p>
	Находим строку:
</p>

<pre class="ipsCode prettyprint lang-php prettyprinted" id="ips_uid_3101_7" style=""><span class="pln">$results </span><span class="pun">=</span><span class="pln"> $this</span><span class="pun">-&gt;</span><span class="pln">model_catalog_product</span><span class="pun">-&gt;</span><span class="pln">getProductRelated</span><span class="pun">(</span><span class="pln">$this</span><span class="pun">-&gt;</span><span class="pln">request</span><span class="pun">-&gt;</span><span class="kwd">get</span><span class="pun">[</span><span class="str">'product_id'</span><span class="pun">]);</span></pre>

<p>
	И заменяем её на это:
</p>

<pre class="ipsCode prettyprint lang-php prettyprinted" id="ips_uid_3101_11" style=""><span class="pln">$results </span><span class="pun">=</span><span class="pln"> $this</span><span class="pun">-&gt;</span><span class="pln">model_catalog_product</span><span class="pun">-&gt;</span><span class="pln">getProductRelatedCollection</span><span class="pun">(</span><span class="pln">$product_info</span><span class="pun">);</span></pre>

<p>
	 
</p>

<p>
	В файле <strong>catalog/model/catalog/product.php</strong>
</p>

<p>
	Перед строкой:
</p>

<pre class="ipsCode prettyprint lang-php prettyprinted" id="ips_uid_3101_13" style=""><span class="kwd">public</span><span class="pln"> </span><span class="kwd">function</span><span class="pln"> getProductRelated</span><span class="pun">(</span><span class="pln">$product_id</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span></pre>

<p>
	Добавляем:
</p>

<pre class="ipsCode prettyprint lang-php prettyprinted" id="ips_uid_3101_15" style=""><span class="kwd">public</span><span class="pln"> </span><span class="kwd">function</span><span class="pln"> getProductRelatedCollection</span><span class="pun">(</span><span class="pln">$product</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="com">// Поле товара, по которому идёт выборка коллекции</span><span class="pln">
    $collection_field </span><span class="pun">=</span><span class="pln"> </span><span class="str">'ean'</span><span class="pun">;</span><span class="pln">
    
    $product_data </span><span class="pun">=</span><span class="pln"> array</span><span class="pun">();</span><span class="pln">

    </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(!</span><span class="pln">empty</span><span class="pun">(</span><span class="pln">$product</span><span class="pun">[</span><span class="pln">$collection_field</span><span class="pun">]))</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
        $query </span><span class="pun">=</span><span class="pln"> $this</span><span class="pun">-&gt;</span><span class="pln">db</span><span class="pun">-&gt;</span><span class="pln">query</span><span class="pun">(</span><span class="str">"SELECT product_id FROM "</span><span class="pln"> </span><span class="pun">.</span><span class="pln"> DB_PREFIX </span><span class="pun">.</span><span class="pln"> </span><span class="str">"product WHERE product_id != '"</span><span class="pln"> </span><span class="pun">.</span><span class="pln"> </span><span class="pun">(</span><span class="kwd">int</span><span class="pun">)</span><span class="pln">$product</span><span class="pun">[</span><span class="str">'product_id'</span><span class="pun">]</span><span class="pln"> </span><span class="pun">.</span><span class="pln"> </span><span class="str">"' AND status = '1' AND `"</span><span class="pln"> </span><span class="pun">.</span><span class="pln"> $this</span><span class="pun">-&gt;</span><span class="pln">db</span><span class="pun">-&gt;</span><span class="pln">escape</span><span class="pun">(</span><span class="pln">$collection_field</span><span class="pun">)</span><span class="pln"> </span><span class="pun">.</span><span class="pln"> </span><span class="str">"` LIKE '"</span><span class="pln"> </span><span class="pun">.</span><span class="pln"> $this</span><span class="pun">-&gt;</span><span class="pln">db</span><span class="pun">-&gt;</span><span class="pln">escape</span><span class="pun">(</span><span class="pln">$product</span><span class="pun">[</span><span class="pln">$collection_field</span><span class="pun">])</span><span class="pln"> </span><span class="pun">.</span><span class="pln"> </span><span class="str">"' ORDER BY sort_order"</span><span class="pun">);</span><span class="pln">

        </span><span class="kwd">foreach</span><span class="pln"> </span><span class="pun">(</span><span class="pln">$query</span><span class="pun">-&gt;</span><span class="pln">rows </span><span class="kwd">as</span><span class="pln"> $result</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
            $product_data</span><span class="pun">[</span><span class="pln">$result</span><span class="pun">[</span><span class="str">'product_id'</span><span class="pun">]]</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> $this</span><span class="pun">-&gt;</span><span class="pln">getProduct</span><span class="pun">(</span><span class="pln">$result</span><span class="pun">[</span><span class="str">'product_id'</span><span class="pun">]);</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">

    </span><span class="kwd">return</span><span class="pln"> $product_data</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	 
</p>

<p>
	Если нужно выбирать товары только того же производителя, то функция должна выглядеть так:
</p>

<pre class="ipsCode prettyprint lang-php prettyprinted" id="ips_uid_3101_19" style=""><span class="kwd">public</span><span class="pln"> </span><span class="kwd">function</span><span class="pln"> getProductRelatedCollection</span><span class="pun">(</span><span class="pln">$product</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="com">// Поле товара, по которому идёт выборка коллекции</span><span class="pln">
    $collection_field </span><span class="pun">=</span><span class="pln"> </span><span class="str">'ean'</span><span class="pun">;</span><span class="pln">
    
    $product_data </span><span class="pun">=</span><span class="pln"> array</span><span class="pun">();</span><span class="pln">

    </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(!</span><span class="pln">empty</span><span class="pun">(</span><span class="pln">$product</span><span class="pun">[</span><span class="pln">$collection_field</span><span class="pun">]))</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
        $query </span><span class="pun">=</span><span class="pln"> $this</span><span class="pun">-&gt;</span><span class="pln">db</span><span class="pun">-&gt;</span><span class="pln">query</span><span class="pun">(</span><span class="str">"SELECT product_id FROM "</span><span class="pln"> </span><span class="pun">.</span><span class="pln"> DB_PREFIX </span><span class="pun">.</span><span class="pln"> </span><span class="str">"product WHERE product_id != '"</span><span class="pln"> </span><span class="pun">.</span><span class="pln"> </span><span class="pun">(</span><span class="kwd">int</span><span class="pun">)</span><span class="pln">$product</span><span class="pun">[</span><span class="str">'product_id'</span><span class="pun">]</span><span class="pln"> </span><span class="pun">.</span><span class="pln"> </span><span class="str">"' AND status = '1' AND manufacturer_id = '"</span><span class="pln"> </span><span class="pun">.</span><span class="pln"> </span><span class="pun">(</span><span class="kwd">int</span><span class="pun">)</span><span class="pln">$product</span><span class="pun">[</span><span class="str">'manufacturer_id'</span><span class="pun">]</span><span class="pln"> </span><span class="pun">.</span><span class="pln"> </span><span class="str">"' AND `"</span><span class="pln"> </span><span class="pun">.</span><span class="pln"> $this</span><span class="pun">-&gt;</span><span class="pln">db</span><span class="pun">-&gt;</span><span class="pln">escape</span><span class="pun">(</span><span class="pln">$collection_field</span><span class="pun">)</span><span class="pln"> </span><span class="pun">.</span><span class="pln"> </span><span class="str">"` LIKE '"</span><span class="pln"> </span><span class="pun">.</span><span class="pln"> $this</span><span class="pun">-&gt;</span><span class="pln">db</span><span class="pun">-&gt;</span><span class="pln">escape</span><span class="pun">(</span><span class="pln">$product</span><span class="pun">[</span><span class="pln">$collection_field</span><span class="pun">])</span><span class="pln"> </span><span class="pun">.</span><span class="pln"> </span><span class="str">"' ORDER BY sort_order"</span><span class="pun">);</span><span class="pln">

        </span><span class="kwd">foreach</span><span class="pln"> </span><span class="pun">(</span><span class="pln">$query</span><span class="pun">-&gt;</span><span class="pln">rows </span><span class="kwd">as</span><span class="pln"> $result</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
            $product_data</span><span class="pun">[</span><span class="pln">$result</span><span class="pun">[</span><span class="str">'product_id'</span><span class="pun">]]</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> $this</span><span class="pun">-&gt;</span><span class="pln">getProduct</span><span class="pun">(</span><span class="pln">$result</span><span class="pun">[</span><span class="str">'product_id'</span><span class="pun">]);</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">

    </span><span class="kwd">return</span><span class="pln"> $product_data</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	 
</p>

<p>
	Если у вас много товаров, то стоит зайти в <strong>phpMyAdmin</strong> и добавить индекс для поля <strong>EAN</strong>. Это ускорит выборку товаров для коллекции. Добавить индекс можно таким запросом:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_3101_21" style=""><span class="pln">ALTER TABLE </span><span class="str">`oc_product`</span><span class="pln"> ADD INDEX </span><span class="str">`ean`</span><span class="pln"> </span><span class="pun">(</span><span class="str">`ean`</span><span class="pun">)</span></pre>

<p>
	Обратите внимание на префикс '<em>oc_</em>', он у вас может отличаться или отсутствовать.
</p>
]]></description><guid isPermaLink="false">1</guid><pubDate>Sat, 23 Apr 2022 13:25:00 +0000</pubDate></item></channel></rss>
