<?xml version="1.0"?>
<rss version="2.0"><channel><title/><link>https://opencartforum.com/ru/blogs/229-blog-spectre/</link><description><![CDATA[<p>
	ololo
</p>]]></description><language>ru</language><item><title>&#x414;&#x435;&#x432; &#x43E;&#x43F;&#x435;&#x43D;&#x43A;&#x430;&#x440;&#x442; - &#x43A;&#x430;&#x43A; &#x441;&#x442;&#x430;&#x442;&#x44C; &#x43C;&#x443;&#x434;&#x430;&#x43A;&#x43E;&#x43C; &#x432;&#x43E; &#x432;&#x440;&#x435;&#x43C;&#x44F; &#x432;&#x43E;&#x439;&#x43D;&#x44B;</title><link>https://opencartforum.com/blogs/entry/516-dev-openkart-kak-stat-mudakom-vo-vremya-voyny/</link><description><![CDATA[<p>
	Все мы знаем что вокруг системы <abbr title="Бесплатная платформа для электронной коммерции с открытым исходным кодом"><abbr title="Бесплатная платформа для электронной коммерции с открытым исходным кодом">опенкарт</abbr></abbr> крутится огромное количество всяких чертей и мошенников, которые воруют у разработчиков модули и продают их типа на своих "легальных" площадках
</p>

<p>
	 
</p>

<p>
	Но вот эта ситуация прямо сильно меня возмутила
</p>

<p>
	 
</p>

<p>
	Есть такой сайтик <span>https://d***v-<abbr title="Бесплатная платформа для электронной коммерции с открытым исходным кодом">op****cart</abbr>.com/</span> во главе с каким-то мутным хером который пытался угрожать мне в личку что он выложит все мои модули
</p>

<p>
	 
</p>

<p>
	<img alt="image.png.a2ce1c7614dc4bdc6a52fdeeed89e04a.png" class="ipsImage ipsImage_thumbnailed" data-fileid="764290" data-ratio="36.00" style="width:400px;height:auto;" width="827" data-src="https://opencartforum.com/storage/attachment/monthly_2023_08/image.png.a2ce1c7614dc4bdc6a52fdeeed89e04a.png" src="https://opencartforum.com/applications/core/interface/js/spacer.png" />
</p>

<p>
	 
</p>

<p>
	Начинался с ломаного симпла, ну это хоть как-то можно оправдать во время войны мол русня стырим ниче страшного. Но потом стали тырить и уже все у своих, мне кажется что кто-то немного охренел
</p>

<p>
	 
</p>

<p>
	Ребятки даже открыли ФОП )
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted"><span class="pln">Сорокін Дмитро Ігорович
UA903220010000026004320073989
ИНН 3485102952</span></pre>

<p>
	 
</p>

<p>
	Чем продолжают копать себе ямку)
</p>

<p>
	 
</p>

<p>
	Также там трутся очень многие ребята с нашего форума, кстати сегодня там перекличка, ищут "крыс" кто рассказывает людям про то что это ссаные пираты и там нет ни одного легального дополнения
</p>

<p>
	 
</p>

<p>
	Кто-то любит экономить 200 грн и получить хз знает что, закодированное мутными херами и без поддержки
</p>

<p>
	 
</p>

<p>
	Самое интересное что некоторые модули там стоят дороже чем легальные от автора, но не суть
</p>

<p>
	самый топ
</p>

<p>
	это Новая Почта и Укрпочта от <a contenteditable="false" data-ipshover="" data-ipshover-target="https://opencartforum.com/profile/690716-prorab337/?do=hovercard" data-mentionid="690716" href="https://opencartforum.com/profile/690716-prorab337/" rel="">@Prorab337</a>
</p>

<p>
	Microdata pro от <a contenteditable="false" data-ipshover="" data-ipshover-target="https://opencartforum.com/profile/18336-exploits/?do=hovercard" data-mentionid="18336" href="https://opencartforum.com/profile/18336-exploits/" rel="">@Exploits</a>
</p>

<p>
	Примерно все модули от <a contenteditable="false" data-ipshover="" data-ipshover-target="https://opencartforum.com/profile/675243-chukcha/?do=hovercard" data-mentionid="675243" href="https://opencartforum.com/profile/675243-chukcha/" rel="">@chukcha</a>
</p>

<p>
	Некоторые модули от <a contenteditable="false" data-ipshover="" data-ipshover-target="https://opencartforum.com/profile/717101-sergetkach/?do=hovercard" data-mentionid="717101" href="https://opencartforum.com/profile/717101-sergetkach/" rel="">@SergeTkach</a>
</p>

<p>
	Мультиязык от <a contenteditable="false" data-ipshover="" data-ipshover-target="https://opencartforum.com/profile/13835-markimax/?do=hovercard" data-mentionid="13835" href="https://opencartforum.com/profile/13835-markimax/" rel="">@markimax</a>
</p>

<p>
	Ocfilter в личке от <a contenteditable="false" data-ipshover="" data-ipshover-target="https://opencartforum.com/profile/3043-soor/?do=hovercard" data-mentionid="3043" href="https://opencartforum.com/profile/3043-soor/" rel="">@SooR</a>
</p>

<p>
	 
</p>

<p>
	Список большой
</p>

<p>
	 
</p>

<p>
	 
</p>

<p>
	<img alt="image.png.1f7267bec72f08d48549fc7f02f58fb5.png" class="ipsImage ipsImage_thumbnailed" data-fileid="764289" data-ratio="49.60" style="width:500px;height:auto;" width="866" data-src="https://opencartforum.com/storage/attachment/monthly_2023_08/image.png.1f7267bec72f08d48549fc7f02f58fb5.png" src="https://opencartforum.com/applications/core/interface/js/spacer.png" />
</p>

<p>
	 
</p>

<p>
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="764291" href="https://opencartforum.com/storage/attachment/monthly_2023_08/image.png.609e7e6978b502d2d705fe50584b5b42.png" rel=""><img alt="image.thumb.png.bb4e3dcead6974e04bdd4e6c85b31a35.png" class="ipsImage ipsImage_thumbnailed" data-fileid="764291" data-ratio="230.77" style="height:auto;" width="325" data-src="https://opencartforum.com/storage/attachment/monthly_2023_08/image.thumb.png.bb4e3dcead6974e04bdd4e6c85b31a35.png" src="https://opencartforum.com/applications/core/interface/js/spacer.png" /></a>
</p>

<p>
	 
</p>

<p>
	 
</p>

<p>
	Всем кто хочет сэкономить рекомендую прочитать эту статью
</p>

<p>
	 
</p>
<iframe allowfullscreen="" data-embedauthorid="3518" data-embedcontent="" data-embedid="embed8030253043" scrolling="no" style="height:234px;max-width:500px;" data-embed-src="https://opencartforum.com/blogs/entry/104-otkuda-mozhno-kachat-moduli/?do=embed"></iframe>

<p>
	 
</p>

<p>
	 
</p>

<p>
	 
</p>

<p>
	 
</p>

<p>
	А что вы думаете по этому поводу? <img alt=":)" data-emoticon="" height="20" src="https://opencartforum.com/storage/smiles/emoticons/test_smile.png" srcset="https://opencartforum.com/storage/smiles/emoticons/smile@2x.png 2x" title=":)" width="20" />
</p>

<p>
	 
</p>

<p>
	 
</p>

<p>
	PS Некоторые козыри есть у нас в рукаве и до определенного момента мы их показывать не будем, но я рекомендую задуматься
</p>

<p>
	 
</p>

<p>
	 
</p>

<p>
	 
</p>

<p>
	 
</p>

<p>
	 
</p>

<p>
	 
</p>

<p>
	 
</p>
]]></description><guid isPermaLink="false">516</guid><pubDate>Fri, 18 Aug 2023 00:17:00 +0000</pubDate></item><item><title>&#x41A;&#x430;&#x43A; &#x43D;&#x430;&#x43F;&#x438;&#x441;&#x430;&#x442;&#x44C; OCMOD-&#x43C;&#x43E;&#x434;&#x438;&#x444;&#x438;&#x43A;&#x430;&#x442;&#x43E;&#x440; &#x447;&#x442;&#x43E;&#x431;&#x44B; &#x43E;&#x43D; &#x434;&#x430;&#x436;&#x435; &#x440;&#x430;&#x431;&#x43E;&#x442;&#x430;&#x43B; &#x438; &#x43D;&#x438;&#x447;&#x435;&#x433;&#x43E; &#x43D;&#x435; &#x441;&#x43B;&#x43E;&#x43C;&#x430;&#x442;&#x44C;</title><link>https://opencartforum.com/blogs/entry/401-kak-napisat-ocmod-modifikator-chtoby-on-dazhe-rabotal-i-nichego-ne-slomat/</link><description><![CDATA[<p>
	<strong>Сегодня мы разберем такую штуку как OCMOD-модификаторы, странно, но более-менее нормального мануала в сети нет, попробуем исправить этот недостаток так чтобы даже школьник понял как оно работает.</strong>
</p>

<p>
	 
</p>

<p>
	<strong>Какие-то неочевидные баги, особенности и приколы мы не будем рассматривать, оставим это удовольствие тем кто решит все-таки пойти дальше и писать свои модули <img alt=":)" data-emoticon="" height="20" src="https://opencartforum.com/storage/smiles/emoticons/test_smile.png" srcset="https://opencartforum.com/storage/smiles/emoticons/smile@2x.png 2x" title=":)" width="20" /> </strong>
</p>

<p>
	 
</p>

<p>
	Итак, OCMOD-модификатор это простой XML-файл, который изменяет PHP-файлы и/или tpl/twig- файлы шаблонов.
</p>

<p>
	 
</p>

<p>
	Вообще модификатор - это zip-архив с расширением ocmod.zip
</p>

<p>
	в нем могут быть
</p>

<p>
	папка upload - в которой файлы для загрузки на сервер
</p>

<p>
	файл install.xml - сам XML-модификатор который изменяет файлы
</p>

<p>
	файл install.php - php-файл который выполняется во время установки модификатора
</p>

<p>
	иногда install.sql - то же самое, только для запросов в бд
</p>

<p>
	 
</p>

<p>
	Это очень небезопасная штука и 90% вирусни на опенкарте - это следствие того что украли админку и загрузили опасные файлы прямо через установщик расширений, я бы отключал вообще этот функционал, а для модулей существуют методы install и uninstall
</p>

<p>
	 
</p>

<p>
	Но мы будем рассматривать только модификатор, который меняет код в файлах и будем называть его OCMOD-модификатором
</p>

<p>
	 
</p>

<p>
	 
</p>

<p>
	<strong>Как оно работает</strong>
</p>

<p>
	 
</p>

<p>
	Есть 2 варианта применить модификатор, первый - положить в папочку system файлик с расширением .ocmod.xml, второй - загрузить файл через установщик дополнений.
</p>

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

<p>
	 
</p>

<p>
	a) есть ограничение на размер файла (правится размером поля в бд, но можно все провтыкать);
</p>

<p>
	б) иногда их блокируют всякие modsecurity;
</p>

<p>
	в) просто тупо неудобно в браузере
</p>

<p>
	 
</p>

<p>
	Также нужно учитывать что порядок применения модификаторов таков - сначала применяются файлы из папки system по алфавиту, потом файлы из базы по названию или дате добавления
</p>

<p>
	 
</p>

<p>
	То есть что делать мы уже знаем, чтобы сделать модификатор нам надо сделать xml-файлик и положить его в папку system
</p>

<p>
	 
</p>

<p>
	Базовая структура OCMOD-файла такая
</p>

<pre class="ipsCode prettyprint lang-xml prettyprinted">
<span class="pun">&lt;?</span><span class="pln">xml version</span><span class="pun">=</span><span class="str">"1.0"</span><span class="pln"> encoding</span><span class="pun">=</span><span class="str">"utf-8"</span><span class="pun">?&gt;</span><span class="pln">
</span><span class="tag">&lt;modification&gt;</span><span class="pln">
</span><span class="tag">&lt;name&gt;</span><span class="pln">Name Of Mega Modification - название нашего супер модуля</span><span class="tag">&lt;/name&gt;</span><span class="pln">
</span><span class="tag">&lt;code&gt;</span><span class="pln">name_of_mega_modification - внутренний код модификатора</span><span class="tag">&lt;/code&gt;</span><span class="pln">
</span><span class="tag">&lt;version&gt;</span><span class="pln">1.0 2.3.x-3.0.x - можно написать версию файла, для каких версий подходит, ну так, чтоб понятно было</span><span class="tag">&lt;/version&gt;</span><span class="pln">
</span><span class="tag">&lt;author&gt;</span><span class="pln">spectre - ваш супер ник</span><span class="tag">&lt;/author&gt;</span><span class="pln">
</span><span class="tag">&lt;link&gt;</span><span class="pln">https://freelancer.od.ua/ - ваш суперсайт</span><span class="tag">&lt;/link&gt;</span><span class="pln">

Здесь будет основное колдунство 
  
</span><span class="tag">&lt;/modification&gt;</span></pre>

<p>
	 
</p>

<p>
	Как и в любом XML-файле все теги должны быть открыты и закрыты после содержания
</p>

<p>
	 
</p>

<p>
	Ну, раз мы уже начали делать модификатор, давайте придумаем что он будет делать и по дороге обратим внимание на то как можно делать в OCMOD а как не надо.
</p>

<p>
	 
</p>

<p>
	Вот прямо сразу вспомнилось что часто просят новички и спрашивают в какой код что нужно вставить чтобы если товар закончился на складе надпись на кнопке "купить" менялась на какую-то. Теперь у них будет возможность сделать это самостоятельно.
</p>

<p>
	 
</p>

<p>
	Сделаем радиокнопочку, которая будет включать и выключать наше творение, а также надпись на какую собственно будет заменяться кнопка "купить", обычную, не мультиязычную, когда научитесь писать модификаторы-  научитесь брать готовые части кода, благо в опенкарте уже есть все примеры)
</p>

<p>
	 
</p>

<p>
	 Делать будем на последней версии OcStore 2.3.0.2.4
</p>

<p>
	 
</p>

<p>
	Структура операции в OCMOD файле очень простая
</p>

<p>
	 
</p>

<pre class="ipsCode prettyprint lang-xml prettyprinted">
<span class="tag">&lt;file</span><span class="pln"> </span><span class="atn">path</span><span class="pun">=</span><span class="atv">"Путь к файлу"</span><span class="tag">&gt;</span><span class="pln"> 
	</span><span class="tag">&lt;operation</span><span class="pln"> </span><span class="atn">error</span><span class="pun">=</span><span class="atv">"действие при ошибке"</span><span class="tag">&gt;</span><span class="pln">
		</span><span class="tag">&lt;search&gt;</span><span class="pln">&lt;![CDATA[что ищем]]&gt;</span><span class="tag">&lt;/search&gt;</span><span class="pln">
		</span><span class="tag">&lt;add</span><span class="pln"> </span><span class="atn">position</span><span class="pun">=</span><span class="atv">"операция"</span><span class="tag">&gt;</span><span class="pln">&lt;![CDATA[ 
			что вставляем или меняем
		]]&gt;</span><span class="tag">&lt;/add&gt;</span><span class="pln">
	</span><span class="tag">&lt;/operation&gt;</span><span class="pln">
</span><span class="tag">&lt;/file&gt;</span></pre>

<p>
	 
</p>

<p>
	 
</p>

<p>
	Путь к файлу, который мы будем модифицировать
</p>

<p>
	 
</p>

<p>
	<strong>Можно написать несколько путей через |</strong>
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted">
<span class="tag">&lt;file</span><span class="pln"> </span><span class="atn">path</span><span class="pun">=</span><span class="atv">"catalog/controller/common/home.php|catalog/controller/common/column_left.php"</span><span class="tag">&gt;</span><span class="pln"> </span></pre>

<p>
	 
</p>

<p>
	<strong>В пути можно использовать звездочки и скобочки</strong>
</p>

<p>
	* - это любой символ в пути
</p>

<p>
	{} - это набор файлов, подробнее опишу дальше
</p>

<p>
	 
</p>

<p>
	Сейчас мы делаем админку для нашего модификатора и нам понадобятся файлы
</p>

<p>
	 
</p>

<p>
	admin/controller/setting/setting.php
</p>

<p>
	admin/view/template/setting/setting.tpl
</p>

<p>
	 
</p>

<p>
	 
</p>

<p>
	т.е. операция примет вид
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted">
<span class="tag">&lt;file</span><span class="pln"> </span><span class="atn">path</span><span class="pun">=</span><span class="atv">"admin/view/template/setting/setting.tpl"</span><span class="tag">&gt;</span><span class="pln"> 
	</span><span class="tag">&lt;operation</span><span class="pln"> </span><span class="atn">error</span><span class="pun">=</span><span class="atv">"skip"</span><span class="tag">&gt;</span><span class="pln">
		</span><span class="tag">&lt;search&gt;</span><span class="pln">&lt;![CDATA[</span><span class="tag">&lt;label</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"col-sm-2 control-label"</span><span class="pln"> </span><span class="atn">for</span><span class="pun">=</span><span class="atv">"input-admin-limit"</span><span class="tag">&gt;</span><span class="pln">&lt;span data-toggle="tooltip" title="</span><span class="pun">&lt;?</span><span class="pln">php echo $help_limit_admin</span><span class="pun">;</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="pln">"&gt;</span><span class="pun">&lt;?</span><span class="pln">php echo $entry_limit_admin</span><span class="pun">;</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="tag">&lt;/span&gt;&lt;/label&gt;</span><span class="pln">]]&gt;</span><span class="tag">&lt;/search&gt;</span><span class="pln">
		</span><span class="tag">&lt;add</span><span class="pln"> </span><span class="atn">position</span><span class="pun">=</span><span class="atv">"before"</span><span class="tag">&gt;</span><span class="pln">&lt;![CDATA[ 
			
		]]&gt;</span><span class="tag">&lt;/add&gt;</span><span class="pln">
	</span><span class="tag">&lt;/operation&gt;</span><span class="pln">
</span><span class="tag">&lt;/file&gt;</span></pre>

<p>
	 
</p>

<p>
	<strong>действие при ошибке - необязательно, но я предпочитаю писать skip - просто пройти дальше мимо</strong>
</p>

<p>
	<strong>можно писать abort (не надо, это оборвет исполнение всей цепочки) или log (писать в лог, но вроде и так все пишется)</strong>
</p>

<p>
	 
</p>

<p>
	Нам нужна радиокнопка которая вкл-выкл действие и сама надпись для этой кнопки
</p>

<p>
	Откроем файл шаблона настроек магазина admin/view/template/setting/setting.tpl и найдем похожий кусочек с радиокнопкой на вкладке "Опции", а заодно и текстовое поле
</p>

<p>
	<img alt="image.png.c7fdecec3e973b1243f9b763af6ffae0.png" class="ipsImage ipsImage_thumbnailed" data-fileid="647490" data-ratio="58.33" style="width:300px;height:auto;" width="967" data-src="https://opencartforum.com/storage/attachment/monthly_2021_05/image.png.c7fdecec3e973b1243f9b763af6ffae0.png" src="https://opencartforum.com/applications/core/interface/js/spacer.png" /></p>

<p>
	 
</p>

<p>
	 
</p>

<p>
	Откроем консоль по ф12 и посмотрим как называется этот элемент и заодно соседний
</p>

<p>
	 
</p>

<p>
	 
</p>

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

	<div class="ipsSpoiler_contents">
		<p>
			<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="647491" href="https://opencartforum.com/storage/attachment/monthly_2021_05/image.png.48fc4966afb51661ce9aced15b8696ee.png" rel=""><img alt="image.thumb.png.9ec1b34db2037c5e718bb9be1690377e.png" class="ipsImage ipsImage_thumbnailed" data-fileid="647491" data-ratio="47.38" style="width:800px;height:auto;" width="1000" data-src="https://opencartforum.com/storage/attachment/monthly_2021_05/image.thumb.png.9ec1b34db2037c5e718bb9be1690377e.png" src="https://opencartforum.com/applications/core/interface/js/spacer.png" /></a>
		</p>
	</div>
</div>

<p>
	 
</p>

<p>
	 
</p>

<p>
	Окей, найдем в tpl-файле этот кусочек кода (для простоты перед ним и будем вставлять наши настройки)
</p>

<p>
	 
</p>

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

	<div class="ipsSpoiler_contents">
		<p>
			<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="647492" href="https://opencartforum.com/storage/attachment/monthly_2021_05/image.png.0e42c78986f10625356c342bd1d32385.png" rel=""><img alt="image.thumb.png.db2a4aa7ddc7979ef865a987c812b6d0.png" class="ipsImage ipsImage_thumbnailed" data-fileid="647492" data-ratio="33.00" style="height:auto;" width="1000" data-src="https://opencartforum.com/storage/attachment/monthly_2021_05/image.thumb.png.db2a4aa7ddc7979ef865a987c812b6d0.png" src="https://opencartforum.com/applications/core/interface/js/spacer.png" /></a>
		</p>
	</div>
</div>

<p>
	 
</p>

<p>
	Теперь подумаем куда нам прицепиться.
</p>

<p>
	<span style="color:#c0392b;"><strong>Самое главное для OCMOD файла - найти УНИКАЛЬНЫЙ ЭЛЕМЕНТ к которому мы будем привязываться, не к &lt;?php echo $text_yes; ?&gt;, не к &lt;div class="form-group required"&gt; а к чему-то что с малой вероятностью будет изменено коллегами-конкурентами-вашими программистами</strong></span>
</p>

<p>
	 
</p>

<p>
	<span style="color:#c0392b;"><strong>Просто запомните, перед тем как идти дальше, проверьте что то что вы указываете в элементе search встречается один раз и ровно там где вам нужно, если нет - ищите дальше куда можно влезть чтобы вас потом не проклинали.</strong></span>
</p>

<p>
	 
</p>

<p>
	На этом примере мы можем прицепиться к 
</p>

<pre class="ipsCode prettyprint lang-php prettyprinted">
<span class="tag">&lt;legend&gt;</span><span class="pun">&lt;?</span><span class="pln">php echo $text_product</span><span class="pun">;</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="tag">&lt;/legend&gt;</span></pre>

<p>
	 
</p>

<p>
	Если нужно будет вставлять куда-то в середину - то можно выбрать другой элемент, хотя давайте так и сделаем, вставим наш модификатор после вкл выкл кол-во товаров
</p>

<p>
	 
</p>

<p>
	Смотрим, нам нужно вклиниться вот сюда
</p>

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

	<div class="ipsSpoiler_contents">
		<p>
			<span> </span><a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="647496" href="https://opencartforum.com/storage/attachment/monthly_2021_05/image.png.8e9df1eaf785e59d4a2d4aaad4e7773d.png" rel=""><img alt="image.thumb.png.7e8f1cab94ae0de0043d72c557fdf092.png" class="ipsImage ipsImage_thumbnailed" data-fileid="647496" data-ratio="68.90" style="height:auto;" width="1000" data-src="https://opencartforum.com/storage/attachment/monthly_2021_05/image.thumb.png.7e8f1cab94ae0de0043d72c557fdf092.png" src="https://opencartforum.com/applications/core/interface/js/spacer.png" /></a> 
		</p>
	</div>
</div>

<p>
	 
</p>

<p>
	Закрывающий див не подходит, form-group тоже, мы не планируем считать какой это обязательный блок во всем файле
</p>

<p>
	я вижу уникальную конструкцию это название блока "кол-во элементов в админке" - туда и пойдем
</p>

<p>
	 
</p>

<p>
	Берем всю строчку и указываем что ее нужно искать (надо вставлять без переносов и пробелов в начале и в конце
</p>

<p>
	 
</p>

<pre class="ipsCode prettyprint lang-xml prettyprinted">
<span class="tag">&lt;search&gt;</span><span class="pln">&lt;![CDATA[</span><span class="tag">&lt;label</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"col-sm-2 control-label"</span><span class="pln"> </span><span class="atn">for</span><span class="pun">=</span><span class="atv">"input-admin-limit"</span><span class="tag">&gt;</span><span class="pln">&lt;span data-toggle="tooltip" title="</span><span class="pun">&lt;?</span><span class="pln">php echo $help_limit_admin</span><span class="pun">;</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="pln">"&gt;</span><span class="pun">&lt;?</span><span class="pln">php echo $entry_limit_admin</span><span class="pun">;</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="tag">&lt;/span&gt;&lt;/label&gt;</span><span class="pln">]]&gt;</span><span class="tag">&lt;/search&gt;</span></pre>

<p>
	 
</p>

<p>
	<strong>search понимает параметр index , то есть если написать &lt;search index="3"&gt;&lt;![CDATA[&lt;/label&gt;]]&gt;&lt;/search&gt; то наш код будет исполняться около 4(!) вхождения &lt;/label&gt; на странице - первый элемент это index="0"</strong>. Старайтесь не использовать это без особой необходимости, кто-то вставит раньше похожий кусочек и все сломается, ваша задача максимально оградить себя от внешних влияний. 
</p>

<p>
	 
</p>

<p>
	<span style="color:#c0392b;"><strong>Без параметра index - операция применится ко всем вхождениям искомой строки в файле</strong></span>
</p>

<p>
	 
</p>

<p>
	<strong>Можно искать по части строки, но старайтесь по целой</strong>
</p>

<p>
	 
</p>

<p>
	<strong>Еще search понимает атрибут trim</strong>, но обычно это не применяется на практике
</p>

<p>
	 
</p>

<p>
	Теперь будем наконец-то вставлять код.
</p>

<p>
	 
</p>

<p>
	Берем просто копипастим радиокнопку вместе с текстовым полем и переименовываем переменные в 1 - то что нам надо, 2 - чтобы тот кто откроет после вас понял что имеется ввиду
</p>

<p>
	 
</p>

<p>
	Получается что-то такое
</p>

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

	<div class="ipsSpoiler_contents">
		<pre class="ipsCode prettyprint lang-html prettyprinted">








<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">"form-group"</span><span class="tag">&gt;</span><span class="pln">
             </span><span class="tag">&lt;label</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"col-sm-2 control-label"</span><span class="tag">&gt;</span><span class="pln">&lt;span data-toggle="tooltip" title="</span><span class="pun">&lt;?</span><span class="pln">php echo $help_replace_cart_button</span><span class="pun">;</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="pln">"&gt;</span><span class="pun">&lt;?</span><span class="pln">php echo $entry_replace_cart_button</span><span class="pun">;</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="tag">&lt;/span&gt;&lt;/label&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">"col-sm-10"</span><span class="tag">&gt;</span><span class="pln">
               </span><span class="tag">&lt;label</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"radio-inline"</span><span class="tag">&gt;</span><span class="pln">
                 </span><span class="pun">&lt;?</span><span class="pln">php </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">$config_replace_cart_button</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="pln">
                 </span><span class="tag">&lt;input</span><span class="pln"> </span><span class="atn">type</span><span class="pun">=</span><span class="atv">"radio"</span><span class="pln"> </span><span class="atn">name</span><span class="pun">=</span><span class="atv">"config_replace_cart_button"</span><span class="pln"> </span><span class="atn">value</span><span class="pun">=</span><span class="atv">"1"</span><span class="pln"> </span><span class="atn">checked</span><span class="pun">=</span><span class="atv">"checked"</span><span class="pln"> </span><span class="tag">/&gt;</span><span class="pln">
                 </span><span class="pun">&lt;?</span><span class="pln">php echo $text_yes</span><span class="pun">;</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="pln">
                 </span><span class="pun">&lt;?</span><span class="pln">php </span><span class="pun">}</span><span class="pln"> </span><span class="kwd">else</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="pln">
                 </span><span class="tag">&lt;input</span><span class="pln"> </span><span class="atn">type</span><span class="pun">=</span><span class="atv">"radio"</span><span class="pln"> </span><span class="atn">name</span><span class="pun">=</span><span class="atv">"config_replace_cart_button"</span><span class="pln"> </span><span class="atn">value</span><span class="pun">=</span><span class="atv">"1"</span><span class="pln"> </span><span class="tag">/&gt;</span><span class="pln">
                 </span><span class="pun">&lt;?</span><span class="pln">php echo $text_yes</span><span class="pun">;</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="pln">
                 </span><span class="pun">&lt;?</span><span class="pln">php </span><span class="pun">}</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="pln">
               </span><span class="tag">&lt;/label&gt;</span><span class="pln">
               </span><span class="tag">&lt;label</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"radio-inline"</span><span class="tag">&gt;</span><span class="pln">
                 </span><span class="pun">&lt;?</span><span class="pln">php </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(!</span><span class="pln">$config_replace_cart_button</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="pln">
                 </span><span class="tag">&lt;input</span><span class="pln"> </span><span class="atn">type</span><span class="pun">=</span><span class="atv">"radio"</span><span class="pln"> </span><span class="atn">name</span><span class="pun">=</span><span class="atv">"config_replace_cart_button"</span><span class="pln"> </span><span class="atn">value</span><span class="pun">=</span><span class="atv">"0"</span><span class="pln"> </span><span class="atn">checked</span><span class="pun">=</span><span class="atv">"checked"</span><span class="pln"> </span><span class="tag">/&gt;</span><span class="pln">
                 </span><span class="pun">&lt;?</span><span class="pln">php echo $text_no</span><span class="pun">;</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="pln">
                 </span><span class="pun">&lt;?</span><span class="pln">php </span><span class="pun">}</span><span class="pln"> </span><span class="kwd">else</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="pln">
                 </span><span class="tag">&lt;input</span><span class="pln"> </span><span class="atn">type</span><span class="pun">=</span><span class="atv">"radio"</span><span class="pln"> </span><span class="atn">name</span><span class="pun">=</span><span class="atv">"config_replace_cart_button"</span><span class="pln"> </span><span class="atn">value</span><span class="pun">=</span><span class="atv">"0"</span><span class="pln"> </span><span class="tag">/&gt;</span><span class="pln">
                 </span><span class="pun">&lt;?</span><span class="pln">php echo $text_no</span><span class="pun">;</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="pln">
                 </span><span class="pun">&lt;?</span><span class="pln">php </span><span class="pun">}</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="pln">
               </span><span class="tag">&lt;/label&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</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"form-group"</span><span class="tag">&gt;</span><span class="pln">
             </span><span class="tag">&lt;label</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"col-sm-2 control-label"</span><span class="pln"> </span><span class="atn">for</span><span class="pun">=</span><span class="atv">"input-replace-cart-button-text"</span><span class="tag">&gt;</span><span class="pln">&lt;span data-toggle="tooltip" title="</span><span class="pun">&lt;?</span><span class="pln">php echo $help_replace_cart_button_text</span><span class="pun">;</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="pln">"&gt;</span><span class="pun">&lt;?</span><span class="pln">php echo $entry_replace_cart_button_text</span><span class="pun">;</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="tag">&lt;/span&gt;&lt;/label&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">"col-sm-10"</span><span class="tag">&gt;</span><span class="pln">
               &lt;input type="text" name="config_replace_cart_button_text" value="</span><span class="pun">&lt;?</span><span class="pln">php echo $config_replace_cart_button_text</span><span class="pun">;</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="pln">" placeholder="</span><span class="pun">&lt;?</span><span class="pln">php echo $entry_replace_cart_button_text</span><span class="pun">;</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="pln">" id="input-replace-cart-button-text" class="form-control" /&gt;
             </span><span class="tag">&lt;/div&gt;</span><span class="pln">
           </span><span class="tag">&lt;/div&gt;</span><span class="pln">			</span></pre>

		<p>
			 
		</p>
	</div>
</div>

<p>
	 
</p>

<p>
	Теперь нам нужно вставить это перед блоком, но там div с классом form-group
</p>

<p>
	 
</p>

<p>
	<strong>используем before offset="1" - это значит что операция начнет применяться на 1 строку выше той которую мы ищем</strong>
</p>

<p>
	<strong>точно так же работает after - это вставка после искомой строки</strong>
</p>

<p>
	<strong>replace - заменяет искомую строку на то что мы напишем</strong>
</p>

<p>
	 
</p>

<p>
	<span style="color:#c0392b;"><strong>несколько строк одновременно в одной операции поиска искать нельзя!</strong></span>
</p>

<p>
	 
</p>

<p>
	У нас получится такая операция и с этим файлом мы закончили
</p>

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

	<div class="ipsSpoiler_contents">
		<pre class="ipsCode prettyprint lang-html prettyprinted">








<span class="pln">	</span><span class="tag">&lt;operation</span><span class="pln"> </span><span class="atn">error</span><span class="pun">=</span><span class="atv">"skip"</span><span class="tag">&gt;</span><span class="pln">
		</span><span class="tag">&lt;search&gt;</span><span class="pln">&lt;![CDATA[</span><span class="tag">&lt;label</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"col-sm-2 control-label"</span><span class="pln"> </span><span class="atn">for</span><span class="pun">=</span><span class="atv">"input-admin-limit"</span><span class="tag">&gt;</span><span class="pln">&lt;span data-toggle="tooltip" title="</span><span class="pun">&lt;?</span><span class="pln">php echo $help_limit_admin</span><span class="pun">;</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="pln">"&gt;</span><span class="pun">&lt;?</span><span class="pln">php echo $entry_limit_admin</span><span class="pun">;</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="tag">&lt;/span&gt;&lt;/label&gt;</span><span class="pln">]]&gt;</span><span class="tag">&lt;/search&gt;</span><span class="pln">
		</span><span class="tag">&lt;add</span><span class="pln"> </span><span class="atn">position</span><span class="pun">=</span><span class="atv">"before"</span><span class="pln"> </span><span class="atn">offset</span><span class="pun">=</span><span class="atv">"1"</span><span class="tag">&gt;</span><span class="pln">&lt;![CDATA[ 
           </span><span class="tag">&lt;div</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"form-group"</span><span class="tag">&gt;</span><span class="pln">
             </span><span class="tag">&lt;label</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"col-sm-2 control-label"</span><span class="tag">&gt;</span><span class="pln">&lt;span data-toggle="tooltip" title="</span><span class="pun">&lt;?</span><span class="pln">php echo $help_replace_cart_button</span><span class="pun">;</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="pln">"&gt;</span><span class="pun">&lt;?</span><span class="pln">php echo $entry_replace_cart_button</span><span class="pun">;</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="tag">&lt;/span&gt;&lt;/label&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">"col-sm-10"</span><span class="tag">&gt;</span><span class="pln">
               </span><span class="tag">&lt;label</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"radio-inline"</span><span class="tag">&gt;</span><span class="pln">
                 </span><span class="pun">&lt;?</span><span class="pln">php </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">$config_replace_cart_button</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="pln">
                 </span><span class="tag">&lt;input</span><span class="pln"> </span><span class="atn">type</span><span class="pun">=</span><span class="atv">"radio"</span><span class="pln"> </span><span class="atn">name</span><span class="pun">=</span><span class="atv">"config_replace_cart_button"</span><span class="pln"> </span><span class="atn">value</span><span class="pun">=</span><span class="atv">"1"</span><span class="pln"> </span><span class="atn">checked</span><span class="pun">=</span><span class="atv">"checked"</span><span class="pln"> </span><span class="tag">/&gt;</span><span class="pln">
                 </span><span class="pun">&lt;?</span><span class="pln">php echo $text_yes</span><span class="pun">;</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="pln">
                 </span><span class="pun">&lt;?</span><span class="pln">php </span><span class="pun">}</span><span class="pln"> </span><span class="kwd">else</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="pln">
                 </span><span class="tag">&lt;input</span><span class="pln"> </span><span class="atn">type</span><span class="pun">=</span><span class="atv">"radio"</span><span class="pln"> </span><span class="atn">name</span><span class="pun">=</span><span class="atv">"config_replace_cart_button"</span><span class="pln"> </span><span class="atn">value</span><span class="pun">=</span><span class="atv">"1"</span><span class="pln"> </span><span class="tag">/&gt;</span><span class="pln">
                 </span><span class="pun">&lt;?</span><span class="pln">php echo $text_yes</span><span class="pun">;</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="pln">
                 </span><span class="pun">&lt;?</span><span class="pln">php </span><span class="pun">}</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="pln">
               </span><span class="tag">&lt;/label&gt;</span><span class="pln">
               </span><span class="tag">&lt;label</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"radio-inline"</span><span class="tag">&gt;</span><span class="pln">
                 </span><span class="pun">&lt;?</span><span class="pln">php </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(!</span><span class="pln">$config_replace_cart_button</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="pln">
                 </span><span class="tag">&lt;input</span><span class="pln"> </span><span class="atn">type</span><span class="pun">=</span><span class="atv">"radio"</span><span class="pln"> </span><span class="atn">name</span><span class="pun">=</span><span class="atv">"config_replace_cart_button"</span><span class="pln"> </span><span class="atn">value</span><span class="pun">=</span><span class="atv">"0"</span><span class="pln"> </span><span class="atn">checked</span><span class="pun">=</span><span class="atv">"checked"</span><span class="pln"> </span><span class="tag">/&gt;</span><span class="pln">
                 </span><span class="pun">&lt;?</span><span class="pln">php echo $text_no</span><span class="pun">;</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="pln">
                 </span><span class="pun">&lt;?</span><span class="pln">php </span><span class="pun">}</span><span class="pln"> </span><span class="kwd">else</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="pln">
                 </span><span class="tag">&lt;input</span><span class="pln"> </span><span class="atn">type</span><span class="pun">=</span><span class="atv">"radio"</span><span class="pln"> </span><span class="atn">name</span><span class="pun">=</span><span class="atv">"config_replace_cart_button"</span><span class="pln"> </span><span class="atn">value</span><span class="pun">=</span><span class="atv">"0"</span><span class="pln"> </span><span class="tag">/&gt;</span><span class="pln">
                 </span><span class="pun">&lt;?</span><span class="pln">php echo $text_no</span><span class="pun">;</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="pln">
                 </span><span class="pun">&lt;?</span><span class="pln">php </span><span class="pun">}</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="pln">
               </span><span class="tag">&lt;/label&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</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"form-group"</span><span class="tag">&gt;</span><span class="pln">
             </span><span class="tag">&lt;label</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"col-sm-2 control-label"</span><span class="pln"> </span><span class="atn">for</span><span class="pun">=</span><span class="atv">"input-replace-cart-button-text"</span><span class="tag">&gt;</span><span class="pln">&lt;span data-toggle="tooltip" title="</span><span class="pun">&lt;?</span><span class="pln">php echo $help_replace_cart_button_text</span><span class="pun">;</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="pln">"&gt;</span><span class="pun">&lt;?</span><span class="pln">php echo $entry_replace_cart_button_text</span><span class="pun">;</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="tag">&lt;/span&gt;&lt;/label&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">"col-sm-10"</span><span class="tag">&gt;</span><span class="pln">
               &lt;input type="text" name="config_replace_cart_button_text" value="</span><span class="pun">&lt;?</span><span class="pln">php echo $config_replace_cart_button_text</span><span class="pun">;</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="pln">" placeholder="</span><span class="pun">&lt;?</span><span class="pln">php echo $entry_replace_cart_button_text</span><span class="pun">;</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="pln">" id="input-replace-cart-button-text" class="form-control" /&gt;
             </span><span class="tag">&lt;/div&gt;</span><span class="pln">
           </span><span class="tag">&lt;/div&gt;</span><span class="pln">			
		]]&gt;</span><span class="tag">&lt;/add&gt;</span><span class="pln">
	</span><span class="tag">&lt;/operation&gt;</span></pre>

		<p>
			 
		</p>
	</div>
</div>

<p>
	 
</p>

<p>
	теперь нужно вдохнуть жизнь в переменные
</p>

<p>
	У нас здесь 2 переменные настроек
</p>

<p>
	это $config_replace_cart_button и $config_replace_cart_button_text а также языковые переменные
</p>

<p>
	 
</p>

<p>
	открываем 
</p>

<p>
	admin/controller/setting/setting.php
</p>

<p>
	 
</p>

<p>
	и ищем там 2 места
</p>

<p>
	где добавляются языковые переменные 
</p>

<p>
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="647505" href="https://opencartforum.com/storage/attachment/monthly_2021_05/image.png.beb7d33d34f413a37d2ba90ecc953649.png" rel=""><img alt="image.thumb.png.499b49786ef5a2c88faea993b9ada583.png" class="ipsImage ipsImage_thumbnailed" data-fileid="647505" data-ratio="8.20" style="height:auto;" width="1000" data-src="https://opencartforum.com/storage/attachment/monthly_2021_05/image.thumb.png.499b49786ef5a2c88faea993b9ada583.png" src="https://opencartforum.com/applications/core/interface/js/spacer.png" /></a>
</p>

<p>
	 
</p>

<p>
	и непосредственно сохраняются настройки, ищем config_product_count
</p>

<p>
	 
</p>

<p>
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="647506" href="https://opencartforum.com/storage/attachment/monthly_2021_05/image.png.78042c5a49076676feff755683de30b0.png" rel=""><img alt="image.thumb.png.8977522258e4eea69b43bf08cf3cc6cd.png" class="ipsImage ipsImage_thumbnailed" data-fileid="647506" data-ratio="13.80" style="height:auto;" width="1000" data-src="https://opencartforum.com/storage/attachment/monthly_2021_05/image.thumb.png.8977522258e4eea69b43bf08cf3cc6cd.png" src="https://opencartforum.com/applications/core/interface/js/spacer.png" /></a>
</p>

<p>
	 
</p>

<p>
	у нас будет 2 операции (можно в одной, но лучше текстовые переменные туда где текстовые, а настройки к настройкам, чтобы выглядело "как родное"
</p>

<p>
	Точно так же копипастим код, переименовываем переменные и получаем что-то такое
</p>

<p>
	 
</p>

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

	<div class="ipsSpoiler_contents">
		<pre class="ipsCode prettyprint lang-php prettyprinted">








<span class="tag">&lt;file</span><span class="pln"> </span><span class="atn">path</span><span class="pun">=</span><span class="atv">"admin/controller/setting/setting.php"</span><span class="tag">&gt;</span><span class="pln"> 
	</span><span class="tag">&lt;operation</span><span class="pln"> </span><span class="atn">error</span><span class="pun">=</span><span class="atv">"skip"</span><span class="tag">&gt;</span><span class="pln">
		</span><span class="tag">&lt;search&gt;</span><span class="pln">&lt;![CDATA[$data['entry_status'] = $this-&gt;language-&gt;get('entry_status');]]&gt;</span><span class="tag">&lt;/search&gt;</span><span class="pln">
		</span><span class="tag">&lt;add</span><span class="pln"> </span><span class="atn">position</span><span class="pun">=</span><span class="atv">"after"</span><span class="tag">&gt;</span><span class="pln">&lt;![CDATA[ 
           $data['entry_replace_cart_button'] = $this-&gt;language-&gt;get('entry_replace_cart_button');
           $data['help_replace_cart_button'] = $this-&gt;language-&gt;get('help_replace_cart_button');
           $data['entry_replace_cart_button_text'] = $this-&gt;language-&gt;get('entry_replace_cart_button_text');
           $data['help_replace_cart_button_text'] = $this-&gt;language-&gt;get('help_replace_cart_button_text');
		]]&gt;</span><span class="tag">&lt;/add&gt;</span><span class="pln">
	</span><span class="tag">&lt;/operation&gt;</span><span class="pln">
	</span><span class="tag">&lt;operation</span><span class="pln"> </span><span class="atn">error</span><span class="pun">=</span><span class="atv">"skip"</span><span class="tag">&gt;</span><span class="pln">
		</span><span class="tag">&lt;search&gt;</span><span class="pln">&lt;![CDATA[if (isset($this-&gt;request-&gt;post['config_product_count'])) {]]&gt;</span><span class="tag">&lt;/search&gt;</span><span class="pln">
		</span><span class="tag">&lt;add</span><span class="pln"> </span><span class="atn">position</span><span class="pun">=</span><span class="atv">"before"</span><span class="tag">&gt;</span><span class="pln">&lt;![CDATA[ 
		
		if (isset($this-&gt;request-&gt;post['config_replace_cart_button'])) {
			$data['config_replace_cart_button'] = $this-&gt;request-&gt;post['config_replace_cart_button'];
		} else {
			$data['config_replace_cart_button'] = $this-&gt;config-&gt;get('config_replace_cart_button');
		}
		if (isset($this-&gt;request-&gt;post['config_replace_cart_button_text'])) {
			$data['config_replace_cart_button_text'] = $this-&gt;request-&gt;post['config_replace_cart_button_text'];
		} else {
			$data['config_replace_cart_button_text'] = $this-&gt;config-&gt;get('config_replace_cart_button_text');
		}

		]]&gt;</span><span class="tag">&lt;/add&gt;</span><span class="pln">
	</span><span class="tag">&lt;/operation&gt;</span><span class="pln">
</span><span class="tag">&lt;/file&gt;</span></pre>

		<p>
			 
		</p>
	</div>
</div>

<p>
	 
</p>

<p>
	Здесь offset нам не нужен, просто вставляем до и после
</p>

<p>
	 
</p>

<p>
	<span style="color:#c0392b;"><span style="font-size:20px;"><strong>Всегда проверяйте что то, к чему привязываемся - уникально!</strong></span></span>
</p>

<p>
	 
</p>

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

<p>
	 
</p>

<p>
	Язык админки у нас может быть разный, но мы сделаем так чтобы везде появились эти языковые переменные и попробуем символ * в пути
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted">
<span class="tag">&lt;file</span><span class="pln"> </span><span class="atn">path</span><span class="pun">=</span><span class="atv">"admin/language/*/setting/setting.php"</span><span class="tag">&gt;</span><span class="pln"> </span></pre>

<p>
	 
</p>

<p>
	Это значит что наш модификатор пробежится по всем папкам в admin/language и поищет в каждой файл setting/setting.php
</p>

<p>
	<strong>Можно написать так &lt;file path="admin/language/*/*/set*.php"&gt; или так &lt;file path="admin/*/*/*/setting.php"&gt;</strong>
</p>

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

<p>
	 
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted">
<span class="tag">&lt;file</span><span class="pln"> </span><span class="atn">path</span><span class="pun">=</span><span class="atv">"admin/language/{ru-ru,en-gb}/setting/setting.php"</span><span class="tag">&gt;</span><span class="pln"> </span></pre>

<p>
	 
</p>

<p>
	это явное указание нескольких папок-файлов в пути
</p>

<p>
	 
</p>

<p>
	в них обоих есть // Text поэтому не будем мудрствовать лукаво
</p>

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

	<div class="ipsSpoiler_contents">
		<p>
			 
		</p>

		<pre class="ipsCode prettyprint lang-html prettyprinted">








<span class="tag">&lt;file</span><span class="pln"> </span><span class="atn">path</span><span class="pun">=</span><span class="atv">"admin/language/{ru-ru,en-gb}/setting/setting.php"</span><span class="tag">&gt;</span><span class="pln"> 
	</span><span class="tag">&lt;operation</span><span class="pln"> </span><span class="atn">error</span><span class="pun">=</span><span class="atv">"skip"</span><span class="tag">&gt;</span><span class="pln">
		</span><span class="tag">&lt;search&gt;</span><span class="pln">&lt;![CDATA[// Text]]&gt;</span><span class="tag">&lt;/search&gt;</span><span class="pln">
		</span><span class="tag">&lt;add</span><span class="pln"> </span><span class="atn">position</span><span class="pun">=</span><span class="atv">"after"</span><span class="tag">&gt;</span><span class="pln">&lt;![CDATA[ 
		$_['entry_replace_cart_button']        = 'Заменять кнопку "купить" при нулевом остатке';
		$_['help_replace_cart_button']         = 'Если включить - будет работать замена';
		$_['entry_replace_cart_button_text']   = 'Текст на кнопке купить при количестве 0';
		$_['help_replace_cart_button_text']    = 'Будет отображаться на кнопке при нулевом количестве';
		]]&gt;</span><span class="tag">&lt;/add&gt;</span><span class="pln">
	</span><span class="tag">&lt;/operation&gt;</span><span class="pln">
</span><span class="tag">&lt;/file&gt;</span></pre>

		<p>
			 
		</p>
	</div>
</div>

<p>
	 
</p>

<p>
	И, о чудо, админку для модуля мы написали и она даже работает!
</p>

<p>
	 
</p>

<p>
	<img alt="image.png.8178aa86666ab37dcf06332d1174e75b.png" class="ipsImage ipsImage_thumbnailed" data-fileid="647510" data-ratio="33.00" style="width:500px;height:auto;" width="943" data-src="https://opencartforum.com/storage/attachment/monthly_2021_05/image.png.8178aa86666ab37dcf06332d1174e75b.png" src="https://opencartforum.com/applications/core/interface/js/spacer.png" /></p>

<p>
	 
</p>

<p>
	 
</p>

<p>
	Теперь будем делать самое главное - чтобы это все работало
</p>

<p>
	 
</p>

<p>
	Начнем с товара, это контроллер product/product и шаблон по такому же пути
</p>

<p>
	 
</p>

<p>
	В контроллере нам нужно получить статус нашей модификации и текст для кнопки (а еще количество товара на склада)
</p>

<p>
	 
</p>

<p>
	Получаем
</p>

<p>
	 
</p>

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

	<div class="ipsSpoiler_contents">
		<pre class="ipsCode prettyprint lang-html prettyprinted">








<span class="tag">&lt;file</span><span class="pln"> </span><span class="atn">path</span><span class="pun">=</span><span class="atv">"catalog/controller/product/product.php"</span><span class="tag">&gt;</span><span class="pln"> 
	</span><span class="tag">&lt;operation</span><span class="pln"> </span><span class="atn">error</span><span class="pun">=</span><span class="atv">"skip"</span><span class="tag">&gt;</span><span class="pln">
		</span><span class="tag">&lt;search&gt;</span><span class="pln">&lt;![CDATA[$data['points'] = $product_info['points'];]]&gt;</span><span class="tag">&lt;/search&gt;</span><span class="pln">
		</span><span class="tag">&lt;add</span><span class="pln"> </span><span class="atn">position</span><span class="pun">=</span><span class="atv">"after"</span><span class="tag">&gt;</span><span class="pln">&lt;![CDATA[ 
		$data['quantity'] = $product_info['quantity'];
		$data['replace_cart_button_status'] = $this-&gt;config-&gt;get('config_replace_cart_button');
		$data['replace_cart_button_text'] = $this-&gt;config-&gt;get('config_replace_cart_button_text');
		]]&gt;</span><span class="tag">&lt;/add&gt;</span><span class="pln">
	</span><span class="tag">&lt;/operation&gt;</span><span class="pln">
</span><span class="tag">&lt;/file&gt;</span></pre>

		<p>
			 
		</p>
	</div>
</div>

<p>
	 
</p>

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

<p>
	 
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted">
<span class="pln">$data['replace_cart_button_status'] = $this-&gt;config-&gt;get('config_replace_cart_button') &amp;&amp; $product_info['quantity'] &lt;= 0 ;</span></pre>

<p>
	 
</p>

<p>
	Все, все данные у нас уже есть, теперь нужно сделать чтобы магия работала в шаблоне
</p>

<p>
	Будем считать что мы нашли уникальный элемент во всех шаблонах и используем путь
</p>

<p>
	 
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted">
<span class="pln">catalog/view/theme/*/template/product/product.tpl</span></pre>

<p>
	 
</p>

<p>
	Поищем кнопку купить
</p>

<p>
	 
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted">
<span class="pln">&lt;button type="button" id="button-cart" data-loading-text="</span><span class="pun">&lt;?</span><span class="pln">php echo $text_loading</span><span class="pun">;</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="pln">" class="btn btn-primary btn-lg btn-block"&gt;</span><span class="pun">&lt;?</span><span class="pln">php echo $button_cart</span><span class="pun">;</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="tag">&lt;/button&gt;</span></pre>

<p>
	 
</p>

<p>
	Пробуем &lt;?php echo $button_cart; ?&gt; , не подходит, оно используется еще в рекомендуемых товарах и если изменится кнопка в товаре - на всех рекомендуемых получим "под заказ"
</p>

<p>
	 
</p>

<p>
	 
</p>

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

<p>
	 
</p>

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

	<div class="ipsSpoiler_contents">
		<pre class="ipsCode prettyprint lang-html prettyprinted">








<span class="tag">&lt;file</span><span class="pln"> </span><span class="atn">path</span><span class="pun">=</span><span class="atv">"catalog/view/theme/*/template/product/product.tpl"</span><span class="tag">&gt;</span><span class="pln"> 
	</span><span class="tag">&lt;operation</span><span class="pln"> </span><span class="atn">error</span><span class="pun">=</span><span class="atv">"skip"</span><span class="tag">&gt;</span><span class="pln">
		</span><span class="tag">&lt;search&gt;</span><span class="pln">&lt;![CDATA[&lt;button type="button" id="button-cart" data-loading-text="</span><span class="pun">&lt;?</span><span class="pln">php echo $text_loading</span><span class="pun">;</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="pln">" class="btn btn-primary btn-lg btn-block"&gt;</span><span class="pun">&lt;?</span><span class="pln">php echo $button_cart</span><span class="pun">;</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="tag">&lt;/button&gt;</span><span class="pln">]]&gt;</span><span class="tag">&lt;/search&gt;</span><span class="pln">
		</span><span class="tag">&lt;add</span><span class="pln"> </span><span class="atn">position</span><span class="pun">=</span><span class="atv">"replace"</span><span class="tag">&gt;</span><span class="pln">&lt;![CDATA[&lt;button type="button" id="button-cart" data-loading-text="</span><span class="pun">&lt;?</span><span class="pln">php echo $text_loading</span><span class="pun">;</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="pln">" class="btn btn-primary btn-lg btn-block"&gt;</span><span class="pun">&lt;?</span><span class="pln">php echo $replace_cart_button_status </span><span class="pun">?</span><span class="pln"> $replace_cart_button_text </span><span class="pun">:</span><span class="pln"> $button_cart</span><span class="pun">;</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="tag">&lt;/button&gt;</span><span class="pln">]]&gt;</span><span class="tag">&lt;/add&gt;</span><span class="pln">
	</span><span class="tag">&lt;/operation&gt;</span><span class="pln">
</span><span class="tag">&lt;/file&gt;</span></pre>

		<p>
			 
		</p>
	</div>
</div>

<p>
	 
</p>

<p>
	<span style="font-size:18px;"><span style="color:#c0392b;"><strong>обратите внимание - replace - тупо заменяет искомое на требуемое, поэтому я рекомендую если вы меняете что-то в одной строке или ее части, так тоже можно - смотрите чтобы оно было без пробелов и переносов, т.к. поломаете верстку и вас никто не будет любить. Также с большой осторожностью используйте offset в replace - он заменяет нижние строки полностью, потренируйтесь на каком-то простом файле</strong></span></span>
</p>

<p>
	 
</p>

<p>
	Вуаля. Опять работает когда количество 0
</p>

<p>
	 
</p>

<p>
	<img alt="image.png.b71ba992b0ceef35f98b6128dc7ded03.png" class="ipsImage ipsImage_thumbnailed" data-fileid="647515" data-ratio="99.00" style="width:400px;height:auto;" width="653" data-src="https://opencartforum.com/storage/attachment/monthly_2021_05/image.png.b71ba992b0ceef35f98b6128dc7ded03.png" src="https://opencartforum.com/applications/core/interface/js/spacer.png" /></p>

<p>
	 
</p>

<p>
	 
</p>

<p>
	Ну, мы уже опытные модулеписатели. Айда провернем то же самое в категориях
</p>

<p>
	А заодно на страничке товаров производителя, поиске и акциях, т.к. контроллеры и шаблоны у них практически идентичны
</p>

<p>
	А еще заодно в рекомендуемых товарах на страничке самого товара
</p>

<p>
	 
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted">
<span class="tag">&lt;file</span><span class="pln"> </span><span class="atn">path</span><span class="pun">=</span><span class="atv">"catalog/controller/product/*.php"</span><span class="tag">&gt;</span><span class="pln">	</span></pre>

<p>
	 
</p>

<p>
	это значит мы будем искать во всех контроллерах в папке product
</p>

<p>
	можно и так
</p>

<p>
	 
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted">
<span class="tag">&lt;file</span><span class="pln"> </span><span class="atn">path</span><span class="pun">=</span><span class="atv">"catalog/controller/product/{category,manufacturer,search,special,product}.php"</span><span class="tag">&gt;</span><span class="pln">	</span></pre>

<p>
	 
</p>

<p>
	Напомню, нам нужно получить статус замены текста на кнопке и, собственно, сам текст
</p>

<p>
	 
</p>

<p>
	Итого 5 контроллеров, ищем строки которые встречаются во всех
</p>

<p>
	 
</p>

<p>
	Возьмем к примеру 
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted">
<span class="pln">'name'        =&gt; $result['name'],</span></pre>

<p>
	это название товара, встречается везде, навредить мы не сможем
</p>

<p>
	 
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted">
<span class="tag">&lt;file</span><span class="pln"> </span><span class="atn">path</span><span class="pun">=</span><span class="atv">"catalog/controller/product/*.php"</span><span class="tag">&gt;</span><span class="pln"> 
	</span><span class="tag">&lt;operation</span><span class="pln"> </span><span class="atn">error</span><span class="pun">=</span><span class="atv">"skip"</span><span class="tag">&gt;</span><span class="pln">
		</span><span class="tag">&lt;search&gt;</span><span class="pln">&lt;![CDATA['name'        =&gt; $result['name'],]]&gt;</span><span class="tag">&lt;/search&gt;</span><span class="pln">
		</span><span class="tag">&lt;add</span><span class="pln"> </span><span class="atn">position</span><span class="pun">=</span><span class="atv">"after"</span><span class="tag">&gt;</span><span class="pln">&lt;![CDATA[ 
		'replace_cart_button_status'        =&gt; $this-&gt;config-&gt;get('config_replace_cart_button') &amp;&amp; $result['quantity'] &lt;= 0,
		'replace_cart_button_text'          =&gt; $this-&gt;config-&gt;get('config_replace_cart_button_text'),
		]]&gt;</span><span class="tag">&lt;/add&gt;</span><span class="pln">
	</span><span class="tag">&lt;/operation&gt;</span><span class="pln">
</span><span class="tag">&lt;/file&gt;</span></pre>

<p>
	 
</p>

<p>
	<strong>Сразу скажу что это не лучший вариант, текст и статус модификации лучше получить где-то до этого цикла товаров и в шаблоне использовать переменные, но наша сейчас цель - понять как работают модификаторы и мы немного уже углубились) </strong>Теперь каждый товар будет знать заменять ли текст на кнопке и если заменять то на какой
</p>

<p>
	 
</p>

<p>
	Точно так же ищем кнопку "купить" и заменяем ее на похожую конструкцию за исключением того что у нас будет не просто $replace_cart_button_status а $product['replace_cart_button_status']. В нормальных шаблонах эти места одинаковые, поэтому будем считать что у нас идеальные условия.
</p>

<p>
	 
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted">
<span class="tag">&lt;file</span><span class="pln"> </span><span class="atn">path</span><span class="pun">=</span><span class="atv">"catalog/view/theme/*/template/product/*.tpl"</span><span class="tag">&gt;</span><span class="pln"> 
	</span><span class="tag">&lt;operation</span><span class="pln"> </span><span class="atn">error</span><span class="pun">=</span><span class="atv">"skip"</span><span class="tag">&gt;</span><span class="pln">
		</span><span class="tag">&lt;search&gt;</span><span class="pln">&lt;![CDATA[&lt;button type="button" onclick="cart.add('</span><span class="pun">&lt;?</span><span class="pln">php echo $product</span><span class="pun">[</span><span class="str">'product_id'</span><span class="pun">];</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="pln">', '</span><span class="pun">&lt;?</span><span class="pln">php echo $product</span><span class="pun">[</span><span class="str">'minimum'</span><span class="pun">];</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="pln">');"&gt;</span><span class="tag">&lt;i</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"fa fa-shopping-cart"</span><span class="tag">&gt;&lt;/i&gt;</span><span class="pln"> </span><span class="tag">&lt;span</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"hidden-xs hidden-sm hidden-md"</span><span class="tag">&gt;</span><span class="pun">&lt;?</span><span class="pln">php echo $button_cart</span><span class="pun">;</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="tag">&lt;/span&gt;&lt;/button&gt;</span><span class="pln">]]&gt;</span><span class="tag">&lt;/search&gt;</span><span class="pln">
		</span><span class="tag">&lt;add</span><span class="pln"> </span><span class="atn">position</span><span class="pun">=</span><span class="atv">"replace"</span><span class="tag">&gt;</span><span class="pln">&lt;![CDATA[&lt;button type="button" onclick="cart.add('</span><span class="pun">&lt;?</span><span class="pln">php echo $product</span><span class="pun">[</span><span class="str">'product_id'</span><span class="pun">];</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="pln">', '</span><span class="pun">&lt;?</span><span class="pln">php echo $product</span><span class="pun">[</span><span class="str">'minimum'</span><span class="pun">];</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="pln">');"&gt;</span><span class="tag">&lt;i</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"fa fa-shopping-cart"</span><span class="tag">&gt;&lt;/i&gt;</span><span class="pln"> </span><span class="tag">&lt;span</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"hidden-xs hidden-sm hidden-md"</span><span class="tag">&gt;</span><span class="pun">&lt;?</span><span class="pln">php echo $product</span><span class="pun">[</span><span class="str">'replace_cart_button_status'</span><span class="pun">]</span><span class="pln"> </span><span class="pun">?</span><span class="pln"> $product</span><span class="pun">[</span><span class="str">'replace_cart_button_text'</span><span class="pun">]</span><span class="pln"> </span><span class="pun">:</span><span class="pln"> $button_cart</span><span class="pun">;</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="tag">&lt;/span&gt;&lt;/button&gt;</span><span class="pln">]]&gt;</span><span class="tag">&lt;/add&gt;</span><span class="pln">
	</span><span class="tag">&lt;/operation&gt;</span><span class="pln">
</span><span class="tag">&lt;/file&gt;</span></pre>

<p>
	 
</p>

<p>
	вуаля
</p>

<p>
	<img alt="image.png.a20bd61734a5b450e7bce00654d282d7.png" class="ipsImage ipsImage_thumbnailed" data-fileid="647517" data-ratio="167.50" style="width:200px;height:auto;" width="432" data-src="https://opencartforum.com/storage/attachment/monthly_2021_05/image.png.a20bd61734a5b450e7bce00654d282d7.png" src="https://opencartforum.com/applications/core/interface/js/spacer.png" /></p>

<p>
	 
</p>

<p>
	 
</p>

<p>
	Упс, в карточке товара рекомендуемые используют чуть другой код (разницы в 1 символе хватит чтобы мод не сработал), ничего, мы добавим аналогичную операцию к product.tpl
</p>

<p>
	 
</p>

<pre class="ipsCode prettyprint lang-xml prettyprinted">
<span class="pln">	</span><span class="tag">&lt;operation</span><span class="pln"> </span><span class="atn">error</span><span class="pun">=</span><span class="atv">"skip"</span><span class="tag">&gt;</span><span class="pln">
		</span><span class="tag">&lt;search&gt;</span><span class="pln">&lt;![CDATA[&lt;button type="button" onclick="cart.add('</span><span class="pun">&lt;?</span><span class="pln">php echo $product</span><span class="pun">[</span><span class="str">'product_id'</span><span class="pun">];</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="pln">', '</span><span class="pun">&lt;?</span><span class="pln">php echo $product</span><span class="pun">[</span><span class="str">'minimum'</span><span class="pun">];</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="pln">');"&gt;</span><span class="tag">&lt;span</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"hidden-xs hidden-sm hidden-md"</span><span class="tag">&gt;</span><span class="pun">&lt;?</span><span class="pln">php echo $button_cart</span><span class="pun">;</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="tag">&lt;/span&gt;</span><span class="pln"> </span><span class="tag">&lt;i</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"fa fa-shopping-cart"</span><span class="tag">&gt;&lt;/i&gt;&lt;/button&gt;</span><span class="pln">]]&gt;</span><span class="tag">&lt;/search&gt;</span><span class="pln">
		</span><span class="tag">&lt;add</span><span class="pln"> </span><span class="atn">position</span><span class="pun">=</span><span class="atv">"replace"</span><span class="tag">&gt;</span><span class="pln">&lt;![CDATA[&lt;button type="button" onclick="cart.add('</span><span class="pun">&lt;?</span><span class="pln">php echo $product</span><span class="pun">[</span><span class="str">'product_id'</span><span class="pun">];</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="pln">', '</span><span class="pun">&lt;?</span><span class="pln">php echo $product</span><span class="pun">[</span><span class="str">'minimum'</span><span class="pun">];</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="pln">');"&gt;</span><span class="tag">&lt;span</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"hidden-xs hidden-sm hidden-md"</span><span class="tag">&gt;</span><span class="pun">&lt;?</span><span class="pln">php echo $product</span><span class="pun">[</span><span class="str">'replace_cart_button_status'</span><span class="pun">]</span><span class="pln"> </span><span class="pun">?</span><span class="pln"> $product</span><span class="pun">[</span><span class="str">'replace_cart_button_text'</span><span class="pun">]</span><span class="pln"> </span><span class="pun">:</span><span class="pln"> $button_cart</span><span class="pun">;</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="tag">&lt;/span&gt;</span><span class="pln"> </span><span class="tag">&lt;i</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"fa fa-shopping-cart"</span><span class="tag">&gt;&lt;/i&gt;&lt;/button&gt;</span><span class="pln">]]&gt;</span><span class="tag">&lt;/add&gt;</span><span class="pln">
	</span><span class="tag">&lt;/operation&gt;</span></pre>

<p>
	 
</p>

<p>
	 
</p>

<p>
	Как-то это сильно просто
</p>

<p>
	Давайте добавим то же самое еще и в модули
</p>

<p>
	В опенкарте 4 стандартных дефолтных модуля (последние, рекомендуемые, хиты продаж и акции), проделываем с ними то же самое
</p>

<p>
	 
</p>

<p>
	О, ухты! В модулях используется для названия товара то же самое
</p>

<p>
	'name'        =&gt; $result['name'],
</p>

<p>
	Сделаем по-умному, изменим путь контроллера там где делали в категориях на
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted">
<span class="tag">&lt;file</span><span class="pln"> </span><span class="atn">path</span><span class="pun">=</span><span class="atv">"catalog/controller/{extension/module,product}/*.php"</span><span class="tag">&gt;</span><span class="pln"> </span></pre>

<p>
	 
</p>

<p>
	и теперь модификатор поищет по обоим путям и добавит переменные везде где нам нужно
</p>

<p>
	 
</p>

<p>
	С шаблоном такое не прокатило, для модулей делаем отдельно
</p>

<p>
	 
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted">
<span class="tag">&lt;file</span><span class="pln"> </span><span class="atn">path</span><span class="pun">=</span><span class="atv">"catalog/view/theme/*/template/extension/module/*.tpl"</span><span class="tag">&gt;</span><span class="pln"> 
	</span><span class="tag">&lt;operation</span><span class="pln"> </span><span class="atn">error</span><span class="pun">=</span><span class="atv">"skip"</span><span class="tag">&gt;</span><span class="pln">
		</span><span class="tag">&lt;search&gt;</span><span class="pln">&lt;![CDATA[&lt;button type="button" onclick="cart.add('</span><span class="pun">&lt;?</span><span class="pln">php echo $product</span><span class="pun">[</span><span class="str">'product_id'</span><span class="pun">];</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="pln">');"&gt;</span><span class="tag">&lt;i</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"fa fa-shopping-cart"</span><span class="tag">&gt;&lt;/i&gt;</span><span class="pln"> </span><span class="tag">&lt;span</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"hidden-xs hidden-sm hidden-md"</span><span class="tag">&gt;</span><span class="pun">&lt;?</span><span class="pln">php echo $button_cart</span><span class="pun">;</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="tag">&lt;/span&gt;&lt;/button&gt;</span><span class="pln">]]&gt;</span><span class="tag">&lt;/search&gt;</span><span class="pln">
		</span><span class="tag">&lt;add</span><span class="pln"> </span><span class="atn">position</span><span class="pun">=</span><span class="atv">"replace"</span><span class="tag">&gt;</span><span class="pln">&lt;![CDATA[&lt;button type="button" onclick="cart.add('</span><span class="pun">&lt;?</span><span class="pln">php echo $product</span><span class="pun">[</span><span class="str">'product_id'</span><span class="pun">];</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="pln">');"&gt;</span><span class="tag">&lt;i</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"fa fa-shopping-cart"</span><span class="tag">&gt;&lt;/i&gt;</span><span class="pln"> </span><span class="tag">&lt;span</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"hidden-xs hidden-sm hidden-md"</span><span class="tag">&gt;</span><span class="pun">&lt;?</span><span class="pln">php echo $product</span><span class="pun">[</span><span class="str">'replace_cart_button_status'</span><span class="pun">]</span><span class="pln"> </span><span class="pun">?</span><span class="pln"> $product</span><span class="pun">[</span><span class="str">'replace_cart_button_text'</span><span class="pun">]</span><span class="pln"> </span><span class="pun">:</span><span class="pln"> $button_cart</span><span class="pun">;</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="tag">&lt;/span&gt;&lt;/button&gt;</span><span class="pln">]]&gt;</span><span class="tag">&lt;/add&gt;</span><span class="pln">
	</span><span class="tag">&lt;/operation&gt;</span><span class="pln">
</span><span class="tag">&lt;/file&gt;</span></pre>

<p>
	 
</p>

<p>
	 
</p>

<p>
	Все сделали и ой
</p>

<p>
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="647519" href="https://opencartforum.com/storage/attachment/monthly_2021_05/image.png.0d6e3f3a8899ae9a069d78b2b1903c48.png" rel=""><img alt="image.thumb.png.bba6abe57f6a6ae2acc86059a373316a.png" class="ipsImage ipsImage_thumbnailed" data-fileid="647519" data-ratio="58.60" style="width:500px;height:auto;" width="1000" data-src="https://opencartforum.com/storage/attachment/monthly_2021_05/image.thumb.png.bba6abe57f6a6ae2acc86059a373316a.png" src="https://opencartforum.com/applications/core/interface/js/spacer.png" /></a>
</p>

<p>
	 
</p>

<p>
	Почему-то это еще с версии 1.5 живет и никто не осмеливается это менять
</p>

<p>
	<span style="color:#c0392b;"><strong>в контроллере рекомендуемых - не $result а $product_info</strong></span>
</p>

<p>
	Делаем исключение и добавляем туда отдельно
</p>

<p>
	 
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted">
<span class="tag">&lt;file</span><span class="pln"> </span><span class="atn">path</span><span class="pun">=</span><span class="atv">"catalog/controller/extension/module/featured.php"</span><span class="tag">&gt;</span><span class="pln"> 
	</span><span class="tag">&lt;operation</span><span class="pln"> </span><span class="atn">error</span><span class="pun">=</span><span class="atv">"skip"</span><span class="tag">&gt;</span><span class="pln">
		</span><span class="tag">&lt;search&gt;</span><span class="pln">&lt;![CDATA['name'        =&gt; $product_info['name'],]]&gt;</span><span class="tag">&lt;/search&gt;</span><span class="pln">
		</span><span class="tag">&lt;add</span><span class="pln"> </span><span class="atn">position</span><span class="pun">=</span><span class="atv">"after"</span><span class="tag">&gt;</span><span class="pln">&lt;![CDATA[ 
		'replace_cart_button_status'        =&gt; $this-&gt;config-&gt;get('config_replace_cart_button') &amp;&amp; $product_info['quantity'] &lt;= 0,
		'replace_cart_button_text'          =&gt; $this-&gt;config-&gt;get('config_replace_cart_button_text'),
		]]&gt;</span><span class="tag">&lt;/add&gt;</span><span class="pln">
	</span><span class="tag">&lt;/operation&gt;</span><span class="pln">
</span><span class="tag">&lt;/file&gt;</span><span class="pln">   </span></pre>

<p>
	 
</p>

<p>
	Все работает, и это было совсем не больно
</p>

<p>
	 
</p>

<p>
	<strong>И вот у нас уже готовый модификатор который немного изменив под свои хотелки можно продать за 300р))</strong>
</p>

<p>
	 
</p>

<p>
	<a class="ipsAttachLink" contenteditable="false" data-fileext="xml" data-fileid="647520" href="https://opencartforum.com/applications/core/interface/file/attachment.php?id=647520" rel="">super_mod.ocmod.xml</a>
</p>

<p>
	 
</p>

<p>
	 
</p>

<p>
	<span style="font-size:20px;">Итого краткое резюме:</span>
</p>

<p>
	<span style="font-size:20px;">- Всегда проверяйте свое условие search чтобы оно было уникальным и никому не мешало, не привязывайтесь к $category_info или $data['heading_title']</span>
</p>

<p>
	<span style="font-size:20px;">- Используйте offset осторожно, а в replace вообще не используйте</span>
</p>

<p>
	<span style="font-size:20px;">- Старайтесь использовать меньшее количество кода, но оставляйте его читаемым</span>
</p>

<p>
	<span style="font-size:20px;">- есть еще search regex но это совсем другая история <img alt=":)" data-emoticon="" height="20" src="https://opencartforum.com/storage/smiles/emoticons/test_smile.png" srcset="https://opencartforum.com/storage/smiles/emoticons/smile@2x.png 2x" title=":)" width="20" /></span>
</p>

<p>
	 
</p>

<p>
	<span style="color:#c0392b;"><strong><span style="font-size:22px;">Если что-то сломалось после применения модификатора из папки system нужно всего лишь переименовать его, скажем, в .ocmod.xml_ , т.е. изменить расширение и обновить кеш модификаторов</span></strong></span>
</p>

<p>
	<span style="color:#c0392b;"><strong><span style="font-size:22px;">Если сломалась страница обновления модификаторов - нужно очистить папку storage/modification (путь к ней можно подглядеть в config.php) тогда, страничка откроется</span></strong></span>
</p>

<p>
	<span style="color:#c0392b;"><strong><span style="font-size:22px;">Это работает если ничего не правилось в кеше модификаторов - но  у кого так - тот и сам знает все боли и их не обновляет <img alt=":)" data-emoticon="" height="20" src="https://opencartforum.com/storage/smiles/emoticons/test_smile.png" srcset="https://opencartforum.com/storage/smiles/emoticons/smile@2x.png 2x" title=":)" width="20" /></span></strong></span>
</p>

<p>
	 
</p>

<p>
	 
</p>

<p>
	<span style="color:#c0392b;"><span style="font-size:18px;"><strong>Это все основано на моем опыте и является моим личным мнением и видением методики написания модификаторов, если у вас есть советы-пожелания - добро пожаловать в комменты</strong></span></span>
</p>

<p>
	 
</p>

<p>
	 
</p>

<p>
	Спасибо за внимание, ваш spectre
</p>

<p>
	 
</p>

<p>
	 
</p>

<p>
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="647495" href="https://opencartforum.com/storage/attachment/monthly_2021_05/image.png.55f6e911250de4c1d70f752fd4a5fa3e.png" rel=""><img alt="image.png" class="ipsImage ipsImage_thumbnailed" data-fileid="647495" data-ratio="NaN" style="height:auto;width:0px;" width="1000" data-src="https://opencartforum.com/storage/attachment/monthly_2021_05/image.thumb.png.6657510c4612a57a507f8de710a9a848.png" src="https://opencartforum.com/applications/core/interface/js/spacer.png" /></a>
</p>

<p>
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="647509" href="https://opencartforum.com/storage/attachment/monthly_2021_05/image.png.cf00ae0f56f193953cde4bc9d6cc3a54.png" rel=""><img alt="image.png" class="ipsImage ipsImage_thumbnailed" data-fileid="647509" data-ratio="NaN" style="height:auto;width:0px;" width="1000" data-src="https://opencartforum.com/storage/attachment/monthly_2021_05/image.thumb.png.418faecbb29fd9e1dfe5278677f69126.png" src="https://opencartforum.com/applications/core/interface/js/spacer.png" /></a>
</p>]]></description><guid isPermaLink="false">401</guid><pubDate>Mon, 17 May 2021 21:17:00 +0000</pubDate></item><item><title>&#x41A;&#x430;&#x43A; &#x444;&#x440;&#x438;&#x43B;&#x430;&#x43D;&#x441;&#x438;&#x442;&#x44C; &#x438; &#x434;&#x430;&#x432;&#x430;&#x442;&#x44C; &#x440;&#x430;&#x431;&#x43E;&#x442;&#x443; &#x444;&#x440;&#x438;&#x43B;&#x430;&#x43D;&#x441;&#x435;&#x440;&#x443; &#x447;&#x442;&#x43E;&#x431; &#x43D;&#x435; &#x43E;&#x431;&#x43B;&#x430;&#x436;&#x430;&#x442;&#x44C;&#x441;&#x44F;</title><link>https://opencartforum.com/blogs/entry/350-kak-frilansit-i-davat-rabotu-frilanseru-chtob-ne-oblazhatsya/</link><description><![CDATA[<p>
	INTRO
</p>

<p>
	Все фрилансеры в 99% случаев попадали на то что им не заплатили денег, а заказчики в 99% случаев попадали на рукожопых специалистов которые брали бабки и пропадали. 
</p>

<p>
	 
</p>

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

<p>
	 
</p>

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

<p>
	 
</p>

<p>
	Начнём с фрилансеров. 
</p>

<p>
	 
</p>

<p>
	1. Самое главное и почему-то самое часто нарушаемое правило. Если взялся за работу - НЕ ПРОПАДАЙ! Если что-то не получается или нужно срочно уйти - напиши заказчику, если он адекватный то поймет. Правда отмазки про переводил бабушку через дорогу и выключили интернет уже мало работают 
</p>

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

<p>
	Уточни все вопросы до того как начнёшь делать, заказчик всегда менее квалифицирован в вопросе с которым пришёл, и пришёл он к человеку который бы решил его проблему. Не выпендривайся, заказчик платит тебе деньги а не наоборот. Но! Всегда четко оговаривай рамки работ, чтобы не было "а поправь-ка мне еще заодно тут раз уж делаешь".
</p>

<p>
	3. Если фрилансишь опенкартом - соблюдай code style и делай бекап папки modification. И ещё не делай костылей если можно обойтись без них. И не пиши тексты прямо в шаблонах, потрать 5 секунд на переменную. Пишешь модификаторы - думай о других. Да и ещё много чего. 
</p>

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

<p>
	5. Не нравится что угодно в заказчике или проекте - не работай с ним
</p>

<p>
	6. Общайся вежливо везде, в почте, мессенджерах и тп
</p>

<p>
	7. Не работай за еду 
</p>

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

<p>
	9. Если тебя что-то спрашивают и у тебя есть возможность ответить - ответь, если возможности нет - ничего страшного 
</p>

<p>
	10. И ещё один страшно трудновыполнимый пункт. Если взял работу и обозначил срок - сдай ее в срок
</p>

<p>
	11. Не суй шеллы в опасении что тебе не заплатят твою тыщу рублей - это мудозвонство
</p>

<p>
	12. Не делай откровенной херни даже если за это платят. Объясни заказчику что это глупо, тупо, не нужно и тп. С аргументами, но можно и без них. Прибыли сейчас ты не получишь но заработаешь пару плюсиков к своей честной репутации и человек обязательно придет еще. Предлагай свои решения задач или дополнительный функционал, если видишь что они уместны, со стороны всегда виднее.
</p>

<p>
	13. <strong style="background-color:#ffffff;color:#353c41;font-size:14px;">Поработал - убери за собой</strong><span style="background-color:#ffffff;color:#353c41;font-size:14px;">, это важно как для клиента так и для других фрилансеров кто будет работать после тебя.</span><br style="background-color:#ffffff;color:#353c41;font-size:14px;" /><span style="background-color:#ffffff;color:#353c41;font-size:14px;">Часто вижу в корне брошенные adminer.php info.php config_.php (с актуальными данным) category_.php category_old.php category_new_old.php и прочий хлам.</span>
</p>

<p>
	by <a contenteditable="false" data-ipshover="" data-ipshover-target="https://opencartforum.com/profile/676281-tank/?do=hovercard" data-mentionid="676281" href="https://opencartforum.com/profile/676281-tank/" rel="">@Tank</a>
</p>

<p>
	Примечание: Если нужно сохранить что-то в сильно измененных файлах - лучше использовать подобные конструкции category.php_050920
</p>

<p>
	14. Принимай любые способы оплаты и плати комиссию за переводы сам, а не "вот с меня снимут полпроцента с вас на 100 р больше"
</p>

<p>
	15. Накосячил - правь быстро и бесплатно
</p>

<p>
	99. Будь крутым 
</p>

<p>
	 
</p>

<p>
	 
</p>

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

<p>
	 
</p>

<p>
	1. Составь ТЗ. Не можешь составить тз - объясни своими словами и картинками что надо сделать. Не мешай все в одну кучу, программист нормальный не будет верстать к примеру, а хороший верстальщик обычно не очень хороший программист и тп. Не пытайся 20 минут рассказать по телефону что нужно. Человек у которого есть столько времени на телефонный разговор вряд ли загружен, а если не загружен - вряд ли хорош. 
</p>

<p>
	Чем больше информации дополнительной - тем лучше, тогда даже с плохим тз нормальный чувак вас поймёт 
</p>

<p>
	Попытайся сам разобраться в вопросе что именно тебе нужно 
</p>

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

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

<p>
	4. Проверяй работу тщательно, обычно все правки делаются после сдачи и все довольны. Не стоит писать через месяц - вот ты нам делал в админке поле для товара а у нас сломалась онлайн - оплата, фрилансер закономерно попросит немного деньжат 
</p>

<p>
	5. Кто последний - не всегда папа
</p>

<p>
	6. Перед тем как начать работу сделай сам все бекапы, создай новые доступы для работы, после работы удали
</p>

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

<p>
	8. Если общаетесь по телефону - звони в какое-то удобное время. В мессенджерах лично я тоже стараюсь никому не писать до 8 и после 19
</p>

<p>
	9. Если работа понравилась - напиши хороший отзыв, вроде это мелочь но довольно сильно мотивирует если это можно так сказать. Помогли на форуме - поставь лайк
</p>

<p>
	10. Перед тем как начать работу с кем-то - погугли отзывы про него. Частенько тут темы повторяются с никами кидал, а если б разок ввёл в гугл ник или логин скайпа этого можно было бы избежать
</p>

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

<p>
	12. Не затягивай с оплатой. Нормальный человек доработает что-то и после того как оплатишь, оплата не означает автоматическое посылание тебя нахер.
</p>

<p>
	13. Во время выполнения проекта - будь на связи, не отвечай раз в 3 дня что-то вроде "ок, мне надо подумать". Чем быстрее коммуникация тем лучше для всех.
</p>

<p>
	14. Если не готов работать прямо сейчас - не надо обсуждать тз, так как обсуждаешь что-то полчаса а потом - "ок, ближе к концу месяца я напишу" 
</p>

<p>
	15. Если обратился к фрилансеру, будь готов предоставить доступ, никаких teamviewer, "сделай у себя локально" и тп. Если так переживаешь за основной сайт - будь добр организовать тестовую площадку
</p>

<p>
	16. Ищи партнера а не раба
</p>

<p>
	99. Ну и самый важный пункт - не будь мудаком, а 2 нормальных человека всегда между собой договорятся 
</p>

<p>
	 
</p>

<p>
	 
</p>

<p>
	Каркас набросал, если есть что дополнить или обсудить - пишите в коментах
</p>

<p>
	 
</p>

<p>
	ваш spectre 
</p>]]></description><guid isPermaLink="false">350</guid><pubDate>Thu, 03 Sep 2020 19:21:00 +0000</pubDate></item><item><title>&#x41A;&#x430;&#x43A; &#x436;&#x435; &#x441;&#x434;&#x435;&#x43B;&#x430;&#x442;&#x44C; &#x440;&#x435;&#x434;&#x438;&#x440;&#x435;&#x43A;&#x442; &#x43D;&#x430; HTTPS &#x438; &#x43D;&#x435; &#x43F;&#x43E;&#x43B;&#x443;&#x447;&#x438;&#x442;&#x44C; &#x446;&#x438;&#x43A;&#x43B;&#x438;&#x447;&#x435;&#x441;&#x43A;&#x443;&#x44E; &#x43F;&#x435;&#x440;&#x435;&#x430;&#x434;&#x440;&#x435;&#x441;&#x430;&#x446;&#x438;&#x44E;</title><link>https://opencartforum.com/blogs/entry/345-kak-zhe-sdelat-redirekt-na-https-i-ne-poluchit-ciklicheskuyu-pereadresaciyu/</link><description><![CDATA[<p>
	На форуме каждый день появляется куча тем что "подключили SSL и все сломалось, циклический редирект и тп"
</p>

<p>
	 
</p>

<p>
	В подавляющем большинстве случаев нужен редирект с www на без и на https с без
</p>

<p>
	 
</p>

<p>
	Первым делом отключаем редиректы в панели хостинга, до добра они никогда не доводят и делаем сами
</p>

<p>
	 
</p>

<p>
	Инструкция для Apache т.к. почти на всех хостингах используется он
</p>

<p>
	 
</p>

<p>
	Все правила редиректов нужно вставлять в файл .htaccess который лежит в корне магазина в этот блок после RewriteBase / !
</p>

<p>
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="573335" href="https://opencartforum.com/storage/attachment/monthly_2020_08/image.png.6a27d58f1fc33a42313dc35bea9df224.png" rel=""><img alt="image.thumb.png.4482f607666ebb6d6c219f4b84990051.png" class="ipsImage ipsImage_thumbnailed" data-fileid="573335" data-ratio="23.10" style="height:auto;" width="1000" data-src="https://opencartforum.com/storage/attachment/monthly_2020_08/image.thumb.png.4482f607666ebb6d6c219f4b84990051.png" src="https://opencartforum.com/applications/core/interface/js/spacer.png" /></a>
</p>

<p>
	 
</p>

<p>
	www редирект простой
</p>

<p>
	 
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted">
<span class="pln">RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]</span></pre>

<p>
	 
</p>

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

<p>
	 
</p>

<p>
	Вторая часть правила у нас будет неизменная
</p>

<p>
	 
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted">
<span class="pln">RewriteRule ^(.*)$ https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]</span></pre>

<p>
	 
</p>

<p>
	А вот первую придется выбрать из
</p>

<p>
	 
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted">
<span class="pln">RewriteCond %{HTTP:SSL} !=1 

RewriteCond %{HTTPS} =off 

RewriteCond %{SERVER_PORT} !^443$

RewriteCond %{ENV:HTTPS} !on

RewriteCond %{HTTP:X-Forwarded-Proto} !https

RewriteCond %{HTTP:X-HTTPS} !1</span></pre>

<p>
	Этого хватит для почти всех хостингов 
</p>

<p>
	 
</p>

<p>
	Расскажу как понять какой тип определения HTTPS вам нужен
</p>

<p>
	 
</p>

<p>
	открываем файл index.php
</p>

<p>
	и пишем туда
</p>

<p>
	 
</p>

<pre class="ipsCode prettyprint lang-php prettyprinted">
<span class="pln">echo </span><span class="str">'&lt;pre&gt;'</span><span class="pun">;</span><span class="pln">
print_r</span><span class="pun">(</span><span class="pln">$_SERVER</span><span class="pun">);</span><span class="pln">
echo </span><span class="str">'&lt;/pre&gt;'</span><span class="pun">;</span></pre>

<p>
	 
</p>

<p>
	открываем сайт по http и видим что-то подобное
</p>

<p>
	 
</p>

<p>
	 
</p>

<p>
	<a class="ipsAttachLink ipsAttachLink_image" href="https://opencartforum.com/storage/attachment/monthly_2020_08/image.png.70a23c961ecf9af57533e0c5caf1b636.png" data-fileid="573375" data-fileext="png" rel=""><img class="ipsImage ipsImage_thumbnailed" data-fileid="573375" data-ratio="85.62" width="876" alt="image.thumb.png.13ebcb8feda9fe607ce87baa18f775ff.png" data-src="https://opencartforum.com/storage/attachment/monthly_2020_08/image.thumb.png.13ebcb8feda9fe607ce87baa18f775ff.png" src="https://opencartforum.com/applications/core/interface/js/spacer.png" /></a>
</p>

<p>
	 
</p>

<p>
	ищем знакомые слова из блока с редиректами
</p>

<p>
	 
</p>

<p>
	и видим
</p>

<p>
	 
</p>

<p>
	[HTTP_X_FORWARDED_PROTO] =&gt; http
</p>

<p>
	 
</p>

<p>
	Значит у нас получится конструкция такого рода
</p>

<p>
	 
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted">
<span class="pln">#Правила для редиректа
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^(.*)$ https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]
#Правила для с www на без
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]</span></pre>

<p>
	 
</p>

<p>
	если хотите чтобы robots.txt был доступен роботам по http
</p>

<p>
	то первым правилом этого блока нужно добавить
</p>

<p>
	 
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted">
<span class="pln">RewriteCond %{REQUEST_FILENAME} !^robots.txt$ [NC]</span></pre>

<p>
	 
</p>

<p>
	 
</p>

<p>
	Если вам лень читать это все и вы просто промотали сюда - подберите просто методом тыка, это занимает 5 минут
</p>

<p>
	 
</p>

<p>
	 
</p>

<p>
	Спасибо за внимание, ваш spectre
</p>

<p>
	 
</p>]]></description><guid isPermaLink="false">345</guid><pubDate>Fri, 14 Aug 2020 12:01:00 +0000</pubDate></item><item><title>&#x41A;&#x430;&#x43A; &#x43D;&#x435; &#x43D;&#x430;&#x434;&#x43E; &#x434;&#x435;&#x43B;&#x430;&#x442;&#x44C; &#x43F;&#x440;&#x438; &#x440;&#x430;&#x437;&#x440;&#x430;&#x431;&#x43E;&#x442;&#x43A;&#x435; &#x43C;&#x430;&#x433;&#x430;&#x437;&#x438;&#x43D;&#x430; &#x43D;&#x430; Opencart</title><link>https://opencartforum.com/blogs/entry/344-kak-ne-nado-delat-pri-razrabotke-magazina-na-opencart/</link><description><![CDATA[<p>
	<span style="font-size:20px;"><strong>Инструкция как делать НЕ НАДО!!!</strong></span>
</p>

<p>
	 
</p>

<p>
	<strong>1. Никаких admin admin и 123456!</strong>
</p>

<p>
	 
</p>

<p>
	Ни в коем случае не ставьте admin admin ни в каких случаях, даже если вам просто нужно поиграться с опенкартом
</p>

<p>
	У вас рядом могут быть живые сайты, которые пострадают
</p>

<p>
	 
</p>

<p>
	<strong>Запомните</strong> - имея админку опенкарта можно получить доступ ко всей файловой системе и другим сайтам сервера/хостинг-аккаунта
</p>

<p>
	 
</p>

<p>
	Никаких example@example.com!
</p>

<p>
	пишите свою или доверенную почту на которую вы сможете получить свой сложный пароль типа &amp;*^%hygkjhGJHG^*&amp;@ghkjhqeeqeqr 
</p>

<p>
	это гораздо безопаснее! Злоумышленник может зарегать example@example.com - и привет!
</p>

<p>
	Отключите демо аккаунт - там доступна на чтение вся информация!
</p>

<p>
	Переименуйте учетку admin - уже плюс к стойкости
</p>

<p>
	Добавьте двухфакторную авторизацию в админку, даже через .htpasswd, это уже осложнит жизнь потенциальному хакеру
</p>

<p>
	Ограничьте сверху доступом по IP
</p>

<p>
	 
</p>

<p>
	<strong>2. Никакого phpmyadmin в мир!</strong>
</p>

<p>
	В 90% случаев phpmyadmin доступен в мир по ip/phpmyadmin
</p>

<p>
	Закрывайте его для чужих, ну, свой ip можно оставить
</p>

<p>
	Попросите хостера это сделать или так же защитить двухфакторной аутентификацией
</p>

<p>
	 
</p>

<p>
	<strong>3. Никаких админеров!</strong>
</p>

<p>
	В каждом пятом сайте админер лежит в корне, удаляйте его после работы или переименуйте в lwjdkhkjwrehtkwrjhvsfvgsfgsf.php если без него нельзя жить!
</p>

<p>
	Это тоже потенциальная уязвимость
</p>

<p>
	 
</p>

<p>
	<strong>4. Никаких логов!</strong>
</p>

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

<p>
	И их можно посмотреть даже под демо-аккаунтом
</p>

<p>
	Логи должны быть доступны только вам, error_log не должен лежать в корне сайта для всех
</p>

<p>
	 
</p>

<p>
	<strong>5. Никаких архивов в корне сайта!</strong>
</p>

<p>
	У многих лежит в корне архив site.tar.gz, db.sql, backup.zip и прочее
</p>

<p>
	Эти файлы можно скачать!!! Там есть все конфиги, логины пароли и прочее интересное, вы сами отдаете свой сайт злоумышленникам.
</p>

<p>
	Никаких доступов в текстовых файлах, ничего!
</p>

<p>
	<img alt="image.png.7b558465cb7dea836256b811ed4e0036.png" class="ipsImage ipsImage_thumbnailed" data-fileid="572750" data-ratio="67.98" style="height:auto;" width="228" data-src="https://opencartforum.com/storage/attachment/monthly_2020_08/image.png.7b558465cb7dea836256b811ed4e0036.png" src="https://opencartforum.com/applications/core/interface/js/spacer.png" /></p>

<p>
	 
</p>

<p>
	вот все должно быть в корне!
</p>

<p>
	 
</p>

<p>
	<strong>6. Регулярно меняйте ВСЕ пароли</strong>
</p>

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

<p>
	Рекомендую раз в месяц
</p>

<p>
	Также сканируйте свой сайт каким-то айболитом или чем-то подобным на предмет всякой херни
</p>

<p>
	 
</p>

<p>
	<strong>7. Не ставьте ломаных модулей (даже бесплатных)!</strong>
</p>

<p>
	Подавляющее число модулей на опенкарт стоят до 1000 р, это не та сумма чтобы ставить себе на сайт бомбы замедленного действия с варезных сайтов!
</p>

<p>
	В один прекрасный момент этот механизм активируется и вы потеряете свой сайт и репутацию с потрохами!
</p>

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

<p>
	 
</p>

<p>
	<strong>8. Никаких ошибок php на фронте!</strong>
</p>

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

<p>
	Не умеете - просите хостера! 
</p>

<p>
	Это касается всей служебной информации
</p>

<p>
	 
</p>

<p>
	<strong>9. SQL-инъекции</strong>
</p>

<p>
	В интернете полно скриптов как базово обезопасить свой сайт хотя бы от самых популярных инъекций!
</p>

<p>
	Найдите в интернете правила для apache и/или nginx и примените их, если не понимаете - попросите специалиста!
</p>

<p>
	 
</p>

<p>
	<strong>10. Давая данные кому-то - не забывайте их менять!</strong>
</p>

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

<p>
	Потратьте 3 минуты после работы на смену доступов!
</p>

<p>
	FTP еще желательно делать по IP чтобы 21 порт был недоступен недоверенным людям, у каждого вменяемого разработчика IP статический (постоянный)
</p>

<p>
	Включите mod_security в PHP, он всякую шушеру нормально отбивает
</p>

<p>
	suhosin тоже неплох, но его настраивать надо
</p>

<p>
	 
</p>

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

<p>
	Часто чтобы покрасить кнопку люди скидывают пароль от хостинга где лежит десяточка сайтов. А ведь не все люди добросовестны
</p>

<p>
	 
</p>

<p>
	<strong>11. Никогда не держите яйца в одной корзине!</strong>
</p>

<p>
	 
</p>

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

<p>
	Часто вижу как дев и прод находятся на одном сервере рядышком, а к деву admin admin потому что разработчику так удобно и он не может запомнить пароль посложнее
</p>

<p>
	Или какой-нибудь дырявый вордпресс бложек старой версии, взломав который весь аккаунт хостинга превращается в кашу из шеллов и показывает гуглу иероглифы а вы этого даже можете не знать!
</p>

<p>
	 
</p>

<p>
	<strong>12. Отрубите tool/upload</strong>
</p>

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

<p>
	А если необходимость есть - сделайте дополнительные проверки!
</p>

<p>
	 
</p>

<p>
	<strong>13. Совет от </strong><a contenteditable="false" data-ipshover="" data-ipshover-target="https://opencartforum.com/profile/26766-mpn2005/?do=hovercard" data-mentionid="26766" href="https://opencartforum.com/profile/26766-mpn2005/" rel="">@mpn2005</a>
</p>

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

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

<p>
	Это касается и конфигов, и robots, и htaccess, да и любых php файлов.
</p>

<p>
	 
</p>

<p>
	<strong>14. Пропишите правильно права на директории!</strong>
</p>

<p>
	Обычно для папок 755, для файлов 644
</p>

<p>
	веб-сервер должен быть запущен от имени владельца файлов и папок
</p>

<p>
	 
</p>

<p>
	<strong>15. Подключите SSL</strong>
</p>

<p>
	Большинство хостингов дает сертификаты от Let's Encrypt бесплатно, а если и не дает - то купить недорого, хватит любого
</p>

<p>
	 
</p>

<p>
	<strong>16. Давайте доступы сотрудникам только туда куда им реально необходимо для работы!</strong>
</p>

<p>
	Менеджеру совершенно не нужно знать smtp-пароль на почту и настройки модулей и иметь возможность смены вашего пароля как администратор
</p>

<p>
	В опенкарт это не сильно понятный процесс но есть модули которые помогают
</p>

<p>
	Постарайтесь сделать так что даже если сотрудник обидится он не смог навредить вам и вашему сайту
</p>

<p>
	 
</p>

<p>
	 
</p>

<p>
	 
</p>

<p>
	Если у вас есть проблемы хотя бы по одному из пунктов - то у вас <strong>большие </strong>проблемы!!!
</p>

<p>
	 
</p>

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

<p>
	 
</p>

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

<p>
	 
</p>

<p>
	Будьте внимательны и бдительны, это ваше бабло и репутация!
</p>

<p>
	 
</p>

<p>
	 
</p>

<p>
	Кто дочитал - всем спасибо за внимание, ваш spectre
</p>

<p>
	 
</p>]]></description><guid isPermaLink="false">344</guid><pubDate>Wed, 12 Aug 2020 09:00:00 +0000</pubDate></item><item><title>&#x41A;&#x430;&#x43A; &#x440;&#x430;&#x431;&#x43E;&#x442;&#x430;&#x442;&#x44C;</title><link>https://opencartforum.com/blogs/entry/341-kak-rabotat/</link><description><![CDATA[<p>
	Я хочу сразу что пост не является целью кого-то обосрать а просто констатирует некоторые факты
</p>

<p>
	 
</p>

<p>
	Каждый божий день ко мне обращается человек 40 с разными насущными проблемами.
</p>

<p>
	 
</p>

<p>
	НО!
</p>

<p>
	 
</p>

<p>
	Проблемы 3-4 (а это примерно 10%) их них решаются отключением-удалением модулей лайтинг или хрен оптимайзер, по-другому я это назвать не могу.
</p>

<p>
	 
</p>

<p>
	Автор <span> </span>оптимайзера в упор не видит там проблем и больше того там не работают кнопки по типу «не трогать фейсбук», а автор морозится и/или шлет всех на--- типа «у других и у меня на демке <span> </span>нормально»
</p>

<p>
	Чего стоит отложенный запуск метрики, счетчики и тп они же бл---<span>  </span>пишут – вставьте код в <span lang="en-us" xml:lang="en-us">head</span><span lang="en-us" xml:lang="en-us"> </span>страницы, когда она загрузится счетчик уже должен работать
</p>

<p>
	 
</p>

<p>
	А ради мифических попугаев, которые в 99% случаев не влияют на ранжирование вашего магазина вы теряете очень много функционала!
</p>

<p>
	 
</p>

<p>
	<a href="https://developers.google.com/speed/pagespeed/insights/?hl=ru&amp;url=rozetka.ua" rel="external nofollow">https://developers.google.com/speed/pagespeed/insights/?hl=ru&amp;url=rozetka.ua</a>
</p>

<p>
	<a href="https://developers.google.com/speed/pagespeed/insights/?hl=ru&amp;url=citrus.ua" rel="external nofollow">https://developers.google.com/speed/pagespeed/insights/?hl=ru&amp;url=citrus.ua</a>
</p>

<p>
	 
</p>

<p>
	вы думаете у розетки или цитруса нет денег оптимизировать пейджспид или купить-написать модуль хай оптимайзер? Или они грузятся по 10 сек как пишет сервис?
</p>

<p>
	 
</p>

<p>
	Да им по---й ваще потому что они думают головой и делают магазин для людей
</p>

<p>
	 
</p>

<p>
	Красивые цифирки это не всегда хорошо и круто, кому нахрен нужен неработающий магазин с 100 попугаями пейджспид?
</p>

<p>
	Хотите пейджспид? Закройте скрипты и стили от робота гугла типа
</p>

<p>
	<span lang="en-us" style="color:#202124;" xml:lang="en-us">&lt;?php if (strpos($_SERVER['HTTP_USER_AGENT'], "Speed Insights" ) == false) { ?&gt;</span>
</p>

<p>
	Или отдайте ему бабку ват как я и будет 100 из 100
</p>

<p>
	<a href="https://developers.google.com/speed/pagespeed/insights/?hl=ru&amp;url=freelancer.od.ua" rel="external nofollow">https://developers.google.com/speed/pagespeed/insights/?hl=ru&amp;url=freelancer.od.ua</a>
</p>

<p>
	 
</p>

<p>
	Показатель пейджспида не показатель реальной скорости и удобности магазина, запомните, вы б-- делаете магазины не для поисковиков а для людей, а то что там какой-то сервис из страны где больше половины людей сидит на адсл показывает что ему там что-то не нравится - вас вообще не должно парить!
</p>

<p>
	 
</p>

<p>
	 
</p>

<p>
	Лайтинг это вообще какая то эпическая хрень, магазин типа начинает работать быстро на главной и со второго раза, но если у вас много товаров – это селф ддос со всеми вытекающими, скрипт с сервера автора – в подарок
</p>

<p>
	Так же как оказалось модуль не знает что в магазине может быть несколько групп покупателей
</p>

<p>
	 
</p>

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

<p>
	 
</p>

<p>
	Если вы пишете модули – не нужно думать что ваш модуль окажется единственным в магазине клиента, не меняйте бл--- системные вызовы <span> </span>типа <span lang="en-us" xml:lang="en-us">getProducts</span><span lang="en-us" xml:lang="en-us"> </span>на свою хрень, не забывайте что это не ваш демо сайт а бл--- магазин с реальными товарами за деньги, владелец которого хочет заплатить вам бабла за то что вы решите его очередную боль.
</p>

<p>
	 
</p>

<p>
	Пейте пиво, думайте башкой, ваш <span lang="en-us" xml:lang="en-us">spectre</span>
</p>

<p>
	 
</p>

<p>
	 
</p>

<p>
	 
</p>

<p>
	<a class="ipsAttachLink ipsAttachLink_image" href="https://opencartforum.com/storage/attachment/monthly_2020_08/image.png.afe612557049fde4d68c99f67a848570.png" data-fileid="573248" data-fileext="png" rel=""><img class="ipsImage ipsImage_thumbnailed" data-fileid="573248" data-ratio="8.50" width="1000" alt="image.thumb.png.40a6f5fabbde448005a63386b87634f4.png" data-src="https://opencartforum.com/storage/attachment/monthly_2020_08/image.thumb.png.40a6f5fabbde448005a63386b87634f4.png" src="https://opencartforum.com/applications/core/interface/js/spacer.png" /></a>
</p>]]></description><guid isPermaLink="false">341</guid><pubDate>Wed, 05 Aug 2020 23:08:00 +0000</pubDate></item></channel></rss>
