<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Блог Jelu.ru - блог по разработке, администрированию Linux систем, программированию.</title>
<link href="https://www.jelu.ru"></link>
<id>urn:uuid:32f8ffe6-136f-0d24-90f0-57dfddd0711c</id>
<description type="html"><![CDATA[Jelu.ru - блог по разработке, администрированию Linux систем, программированию и просто интересных моментов в жизни.
]]></description>
<updated>2026-03-14T06:37:21+03:00</updated>
<entry>
<title>ClickHouse команды для бекапа и восстановления</title>
<author>Jelu</author>
<published>2021-04-16T00:00:00+03:00</published>
<updated>2021-04-16T00:00:00+03:00</updated>
<summary type="html"><![CDATA["
<p>Создание бекапа</p>

<p>clickhouse-client --password *** --database=dashboard --query=&quot;SELECT * FROM dashboard.records FORMAT CSV&quot; &gt; ~/records.csv</p>

<p>&nbsp;</p>

<p>Развернуть из бекапа</p>

<p>clickhouse-client --password *** --database=dashboard --query=&quot;insert into dashboard.records FORMAT CSV&quot; &lt; records.csv</p>
]]></summary>
<link href="https://www.jelu.ru/post/clickhouse-komandy-dlya-bekapa-i-vosstanovleniya.html"></link>
<id>urn:uuid:29ef5339-a267-4e49-e746-8fa118379d9e</id>
</entry>
<entry>
<title>Отображение ветки git в консоли Linux</title>
<author>Jelu</author>
<published>2019-10-01T00:00:00+03:00</published>
<updated>2019-10-01T00:00:00+03:00</updated>
<summary type="html"><![CDATA["
<p>Очень удобно, когда в консоле сразу выводится ветка git, в которой работаешь:</p>

<p><img alt="" src="https://www.jelu.ru/upload/image/268f0dc4f6dd90bcb4407a75925adee4.png" style="width: 721px; height: 208px;" /></p>

<p>Чтобы в Linux добавить отображение, откройте фаил .bashrc, который лежит в корне домашней папки</p>

<p>&nbsp;</p>

<pre class="brush: php;  toolbar: false; hljs php">
nano ~/.bashrc</pre>

<p>&nbsp;</p>

<p>и в самый конец добавьте строки:</p>

<p>&nbsp;</p>

<pre class="brush: php;  toolbar: false; hljs php">
PS1=&#39;\[\033[0;32m\]\[\033[0m\033[0;32m\]\u\[\033[0;36m\] @ \[\033[0;36m\]\h \w\[\033[0;32m\]$(__git_ps1)\n\[\033[0;32m\]└─\[\033[0m\033[0;32m\] \$\[\033[0m\033[0;32m\] ▶\[\033[0m\] &#39;
</pre>

<p>&nbsp;</p>

<p>сохраните и перезапустите консоль, теперь у вас отображается ветка + консоль стилизована</p>

<p>&nbsp;</p>

<p>Другой вариант, если вам не нравится перенос строки + есть подсветка веток</p>

<p><img alt="" src="https://www.jelu.ru/upload/image/48bbf62d064b706f45d2bca0a89802c5.png" style="width: 732px; height: 438px;" /></p>

<p>&nbsp;</p>

<pre class="brush: php;  toolbar: false; hljs php">
function parse_git_branch {
    git branch --no-color 2&gt; /dev/null | sed -e &#39;/^[^*]/d&#39; -e &#39;s/* \(.*\)/(\1)/&#39;
}

function proml {
    local        BLUE=&quot;\[\033[0;34m\]&quot;
    local         RED=&quot;\[\033[0;31m\]&quot;
    local      YELLOW=&quot;\[\033[0;33m\]&quot;
    local   LIGHT_RED=&quot;\[\033[1;31m\]&quot;
    local       GREEN=&quot;\[\033[0;32m\]&quot;
    local LIGHT_GREEN=&quot;\[\033[1;32m\]&quot;
    local  LIGHT_GRAY=&quot;\[\033[0;37m\]&quot;
    case $TERM in
        xterm*)
        TITLEBAR=&#39;\[\033]0;\u@\h:\w\007\]&#39;
        ;;
        *)
        TITLEBAR=&quot;&quot;
        ;;
    esac

PS1=&quot;$PS1$YELLOW\$(parse_git_branch)$LIGHT_GRAY&quot;
PS2=&#39;&gt; &#39;
PS4=&#39;+ &#39;
}

proml
</pre>
]]></summary>
<link href="https://www.jelu.ru/post/otobrazhenie-vetki-git-v-konsoli-linux.html"></link>
<id>urn:uuid:dda8b8a4-f65c-835a-b0fb-1c9b63bde828</id>
</entry>
<entry>
<title>Используйте безопасные COOKIE.</title>
<author>Jelu</author>
<published>2019-02-25T00:00:00+03:00</published>
<updated>2019-02-25T00:00:00+03:00</updated>
<summary type="html"><![CDATA["
<p>Во время разработки, мы часто используем COOKIE для хранения важной информации, такой как токены авторизации, разные ключи и т.&nbsp;д. Но даже в самых защищенных системах, из-за человеческого фактора, можно допустить возможность выполнения XSS-атак, что может привести к утечке важных данных.</p>

<p>Классическая атака, когда через XSS похищается токен авторизации и потом злоумышленник может войти в систему. Для этих целей, в современных браузерах существует защита: атрибут httponly &mdash; который указывает, что cookie с таким атрибутом нельзя передавать скриптовому языку, например Javascript.</p>

<p>Подробно о XSS и похищении данных можно почитать:</p>

<p><a href="https://developer.mozilla.org/ru/docs/Web/HTTP/%D0%9A%D1%83%D0%BA%D0%B8#%D0%91%D0%B5%D0%B7%D0%BE%D0%BF%D0%B0%D1%81%D0%BD%D0%BE%D1%81%D1%82%D1%8C">https://developer.mozilla.org/ru/docs/Web/HTTP/Куки#Безопасность</a></p>

<p>Как использовать:</p>

<p>во время установки COOKIE указывать атрибут httpOnly.</p>

<p>PHP</p>

<pre class="brush: php;  toolbar: false; hljs php hljs">
setcookie($name, $value, $expire, $path, $domain, $secure, $httponly);
setrawcookie($name, $value, $expire, $path, $domain, $secure, $httponly);
</pre>

<p>устанавливать 7 атрибут в true</p>

<pre class="brush: php;  toolbar: false; hljs php hljs">
setcookie(&#39;Foo&#39;,&#39;Bar&#39;,0,&#39;/&#39;, &#39;www.sample.com&#39; , false, true);
</pre>

<p>или в заголовке</p>

<pre class="brush: php;  toolbar: false; hljs php hljs">
header(&quot;Set-Cookie: name=value; httpOnly&quot;);</pre>

<p>Так же, можно принудительно ставить все COOKIE с httpOnly через глобальные настройки, но тогда вы не сможете сами работать с COOKIE через Javascript.</p>

<p></p>

<pre class="brush: php;  toolbar: false; hljs php hljs">
&lt;?php
ini_set(&#39;session.cookie_httponly&#39;, 1);
</pre>

<p>&nbsp;</p>

<p>В заключение хочется напомнить, что данная мера не является 100% гарантией защиты от кражи данных, по-этому лучше проверять все данные вводимые пользователями и относиться к любым внешним данным с подозрением, валидируя и проверяя их.</p>

<p>PS: COOKIE тоже являются внешними данными и их тоже необходимо проверять и валидировать!</p>

<p>&nbsp;</p>
]]></summary>
<link href="https://www.jelu.ru/post/ispolzuyte-bezopasnye-cookie.html"></link>
<id>urn:uuid:dbff64fe-fb91-007f-6556-e9365f234dc2</id>
</entry>
<entry>
<title>1С-Битрикс убираем ошибку валидации html5 «The type attribute is unnecessary for JavaScript resources.»</title>
<author>Jelu</author>
<published>2018-02-09T00:00:00+03:00</published>
<updated>2018-02-09T00:00:00+03:00</updated>
<summary type="html"><![CDATA["
<p>В html5 убрали атрибут type у тэга script. Теперь чтобы&nbsp;ваш код был валидным, нужно убрать его&nbsp;из кода. В Битриксе библиотека скриптов генерируется автоматически&nbsp;и нет настроек которые бы позволили убрать этот атрибут в административной панеле.</p>
<p>&nbsp;</p>
<p><img alt="" src="/upload/image/7af489679bb18203d4a95fcf76d64167.jpg" style="width: 800px; height: 375px;" /></p>

<p>&nbsp;</p>

<p>Для решения этой проблемы, можно воспользоваться предобработчиком, встроенным в ядро системы. Для этого надо добавить следующий код в <strong>bitrix/php_interface/init.php</strong> (Если у вас в системе нет такого файла, создайте его, он автоматически будет подгружен системой. init.php служит для того, что бы подключать к системе пользовательские функции, скрипты и обработчики):</p>

<p>&nbsp;</p>

<pre class="brush: php;  toolbar: false; hljs php hljs">
AddEventHandler(&quot;main&quot;, &quot;OnEndBufferContent&quot;, &quot;delete_type&quot;);
function delete_type(&amp;$content) {
	$content = str_replace(&quot; type=\&quot;text/javascript\&quot;&quot;, false, $content);
}
</pre>
]]></summary>
<link href="https://www.jelu.ru/post/bitrix-html5-remove-type-attribute.html"></link>
<id>urn:uuid:b6010039-54f7-9b52-ea28-12357bf1a864</id>
</entry>
<entry>
<title>Запрет переноса javascript в Bitrix.</title>
<author>Jelu</author>
<published>2017-03-11T00:00:00+03:00</published>
<updated>2017-03-11T00:00:00+03:00</updated>
<summary type="html"><![CDATA["
В Битрикс есть полезная опция, перенос всех javascript в конец страницы, которая позволяет ускорить отображение важного контента. Это является одной из рекомендаций PageSpeed Insights
<p><img alt="" src="/upload/image/4b3248e0753323aeb22d03a0fed1332b.jpg" style="width: 589px; height: 208px;" /></p>

<p>Но бывают ситуации, когда перенос скриптов бывает лишним, например вставленная карта сайта или html5shiv, который подгружается для старых браузеров Internet Explorer.</p>

<p>Так вот, если вам нужно запретить перенос скрипта, добавьте ему аттрибут <strong>data-skip-moving=&quot;true&quot;</strong></p>

<pre class="brush: php;  toolbar: false; hljs php">
&lt;!--[if lt IE 9]&gt;
&lt;script data-skip-moving=&quot;true&quot; src=&quot;https://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.min.js&quot;&gt;&lt;/script&gt;
&lt;![endif]--&gt;
</pre>
]]></summary>
<link href="https://www.jelu.ru/post/zapret-perenosa-javascript-skripta-v-bitrix.html"></link>
<id>urn:uuid:bd493cb7-207d-3d36-fda7-59b5171733d0</id>
</entry>
<entry>
<title>Исправление ошибки $.browser is undefined</title>
<author>Jelu</author>
<published>2017-03-11T00:00:00+03:00</published>
<updated>2017-03-11T00:00:00+03:00</updated>
<summary type="html"><![CDATA["
<p>Начиная с jquery 1.9 была удалена поддержка $.browser, из-за чего некоторые скрипты перестали функционировать. Для исправления этой ошибки добавьте в свои скрипты следующий код:</p>
<p>&nbsp;</p>
<pre class="brush: php;  toolbar: false; hljs php">
jQuery.browser = {};
jQuery.browser.mozilla=/mozilla/.test(navigator.userAgent.toLowerCase())&amp;&amp;!/webkit/.test(navigator.userAgent.toLowerCase());
jQuery.browser.webkit=/webkit/.test(navigator.userAgent.toLowerCase());
jQuery.browser.opera=/opera/.test(navigator.userAgent.toLowerCase());
jQuery.browser.msie=/msie/.test(navigator.userAgent.toLowerCase());
</pre>
<p>&nbsp;</p>
<p>Его можно вынести в отдельный фаил и подключить сразу после jquery.</p>
]]></summary>
<link href="https://www.jelu.ru/post/ispravlenie-oshibki-browser-is-undefined.html"></link>
<id>urn:uuid:21c4c377-1378-7f7e-0919-795701eb0a88</id>
</entry>
<entry>
<title>Ubuntu 16.04, Mysql 5.7 исправление проблемы с open_files_limit.</title>
<author>Jelu</author>
<published>2016-10-23T00:00:00+03:00</published>
<updated>2016-10-23T00:00:00+03:00</updated>
<summary type="html"><![CDATA["
<p>Если у вас возникает проблема &laquo;Error in accept: Too many open files&raquo; в вашей базе данных, Mysql или MariaDB, то вы наверно пытались увеличить в конфиге параметр open_files_limit, но вот не задача, после перезагрузки сервера, параметр остается фиксированным &mdash; 1024.</p>

<p><img alt="" src="/upload/image/d76a44f400d39617726c27855aca5060.jpg" style="width: 610px; height: 133px;" /></p>

<p>Для исправления в Ubuntu 16.04 ( так же актуально для более ранних версий ), сделайте следующие действия, от рута:</p>

<p>Посмотрите что записано в /etc/security/limits.conf</p>

<p>&nbsp;</p>

<pre class="brush: php;  toolbar: false; hljs php">
nano /etc/security/limits.conf</pre>

<p>&nbsp;</p>

<p>Увеличьте текущие лимиты и добавьте лимиты для Mysql, я сделал мягкий лимит 24000, жесткий 35000</p>

<p>&nbsp;</p>

<pre class="brush: php;  toolbar: false; hljs php">
#@student - maxlogins 4
* hard nofile 35000
* soft nofile 24000

root hard nofile 35000
root soft nofile 24000

mysql hard nofile 35000
mysql soft nofile 24000

# End of file
</pre>

<p><img alt="" src="/upload/image/9dda61a3f49163de29ce253dfe1a8618.jpg" style="width: 451px; height: 147px;" /></p>

<p>&nbsp;</p>

<p>Дальше откроем /lib/systemd/system/mysql.service</p>

<pre class="brush: php;  toolbar: false; hljs php">
nano /lib/systemd/system/mysql.service</pre>

<p>Добавьте в [Service]</p>

<pre class="brush: php;  toolbar: false; hljs php">
LimitNOFILE=35000
</pre>

<p><img alt="" src="/upload/image/618358292abdd8779584c961172c03c2.jpg" style="width: 600px; height: 305px;" /></p>

<p>&nbsp;</p>

<p>Перезапустим сервисы:</p>

<pre class="brush: php;  toolbar: false; hljs php">
systemctl daemon-reload
service mysql restart
</pre>

<p>Проверим поменялись ли лимиты:</p>

<pre class="brush: php;  toolbar: false; hljs php">
mysql -u root -p
show variables like &#39;open_files_limit&#39;;
</pre>

<p><img alt="" src="/upload/image/336492bbcbc082abb7734954a63d92a6.jpg" style="width: 600px; height: 284px;" /></p>
]]></summary>
<link href="https://www.jelu.ru/post/ispravlenie-problemy-s-open-files-limit.html"></link>
<id>urn:uuid:2c61e6f3-3627-3cb7-e1b9-9f331a583ea0</id>
</entry>
<entry>
<title>Удаление лишних пробелов в PHP.</title>
<author>Jelu</author>
<published>2016-09-25T00:00:00+03:00</published>
<updated>2016-09-25T00:00:00+03:00</updated>
<summary type="html"><![CDATA["
<p>Обрабатывая информацию, собирая ее из разных источников, например с сайта поставщика, мы часто сталкиваемся с тем, что нам надо ее привести в достойный вид, удалив лишние пробелы.</p>

<h2>Удаление пробелов в начале или конце строки.</h2>

<p>Стандартные функция trim( string $str [, string $character_mask = &quot; \t\n\r\0\x0B&quot; ]) удаляет все возможные пробелы в начале или в конце строки, так же эта функция может удалять те символы, которые вам не нужны, например точку или запятую:</p>

<pre class="brush: php;  toolbar: false;">
$str = trim($str, &quot;,&quot;);
</pre>

<p>или</p>

<pre class="brush: php;  toolbar: false;">
$str = trim($str, &quot;.&quot;);
</pre>

<p>Так же есть 2 функции, ltrim и rtrim, которые работают так же как и trim, за исключением того , что ltrim удаляет символы в начале строки, а rtrim в конце.</p>

<h3>Удаление лишних пробелов в самом тексте.</h3>

<p>Иногда нужно удалить лишние пробелы, а иногда и табы, в самом тексте, например: &laquo;Купив&nbsp; телефон&nbsp;&nbsp; сегодня вы&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; получите самый&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; лучший подарок&raquo;. В этом тексте после каждого слова стоит более 1 пробела, Попробуем заменить лишние через регулярное выражение:</p>

<pre class="brush: php;  toolbar: false;">
$str = preg_replace(&#39;/\s+/&#39;, &#39; &#39;, $str);</pre>

<p>В данном случае \s говорит что надо заменить все пробелы, а + включая табы на 1 пробел. Если вы считаете, что регулярные выражения зло, то можно использовать:</p>

<pre class="brush: php;  toolbar: false;">
$str = str_replace(&quot;	&quot;, &quot; &quot;, $str);
while( strpos($str,&quot;  &quot;)!==false){
	$str = str_replace(&quot;  &quot;, &quot; &quot;, $str);
}
</pre>

<h3>Удаление &laquo;не удаляемых&raquo; пробелов.</h3>

<p>Возможно вы столкнулись с такой проблемой, что ни одно из средств перечисленных выше не удаляет пробелы. Для начала рассмотрите внимательно текст, желательно в исходном коде, потому что текст &laquo; Купив телефон сегодня вы получите самый лучший подарок&raquo; может оказаться таким: &laquo;&amp;amp;nbsp;Купив &amp;nbsp;телефон&amp;nbsp;сегодня вы&amp;nbsp;получите самый лучший подарок&raquo;. Для начала надо заменить &amp;amp;nbsp; и &amp;nbsp; просто на пробелы:</p>

<pre class="brush: php;  toolbar: false;">
$str = str_replace(&#39;&amp;amp;&#39;, &#39;&amp;&#39;, $str);
$str = str_replace(&#39;&amp;nbsp;&#39;, &#39; &#39;, $str);
</pre>

<p>А потом, применить один из способов, о котором я писал выше.</p>

<p>Хорошо, это мы сделали, но у нас остались лишние пробелы, которые не удаляются стандартными методами. Вероятнее всего это NO-BREAK SPACE, в таблице utf-8 символов он идет как c2 a0.</p>

<p><img alt="" src="https://www.jelu.ru/upload/image/5d09a3a9d48d869ef49faa3885c1aad8.jpg" style="width: 605px; height: 107px;" /></p>

<p>Для начала попробуйте перевести ваш текст в HEX:</p>

<pre class="brush: php;  toolbar: false;">
echo bin2hex($str);
echo substr_count($str, &quot;\xc2\xa0&quot;);
</pre>

<p>и поищите там: c2a0, как видно на скриншоте, у меня аж 2 таких пробела</p>

<p><img alt="" src="https://www.jelu.ru/upload/image/98c1e9c0935fbb6256ddebc05b8fac2e.jpg" style="width: 532px; height: 71px;" /></p>

<p>Удаление через регулярное выражение:</p>

<pre class="brush: php;  toolbar: false;">
echo preg_replace(&#39;!\s++!u&#39;, &#39; &#39;, $str);
</pre>

<p>Удаление без регулярного выражения:</p>

<pre class="brush: php;  toolbar: false;">
$text = hex2bin(str_replace(&#39;c2a0&#39;, &#39;20&#39;, bin2hex($str)));
while( strpos($text,&#39;  &#39;)!==false){
	$text = str_replace(&quot;  &quot;, &quot; &quot;, $text);
}
$text = trim($text);
</pre>

<p>переводим наш текс в HEX, заменяем NO-BREAK SPACE на обычный пробел, переводим обратно в обычный текст, после этого можно сделать замену пробелов и чистку.</p>

<p>Возможно у вас есть свой способ, может более практичный, как исправлять &quot;не удаляемые&quot; пробелы, то поделитесь в комментариях.</p>
]]></summary>
<link href="https://www.jelu.ru/post/udalenie-lishnih-probelov-v-php.html"></link>
<id>urn:uuid:9f10bf17-cda2-8ef3-ca07-8aa740be2006</id>
</entry>
<entry>
<title>1С-Битрикс. Сортировка по цене в системах с разной валютой.</title>
<author>Jelu</author>
<published>2016-09-19T00:00:00+03:00</published>
<updated>2016-09-19T00:00:00+03:00</updated>
<summary type="html"><![CDATA["
<p>Долгие годы разработчики просили возможность сортировать по цене, там где используется несколько валют. Ведь система позволяет одни цены на товары хранить в рублях, другие в евро и т.&nbsp;д. Это удобно, учитывая, что многие поставщики дают цены в валюте, то проще сохранить ее сразу в валюте и потом на выходе отдавать в рублях, на текущий курс.</p>

<p>И вот случилось чудо, спустя 4-5 лет долгих костылей и просьб на сайте разработчика, в API была добавлена возможность сортировать с учетом валюты.</p>

<p><img alt="" src="/upload/image/8345586070aa7c2186e2a7a974907ceb.jpg" style="width: 600px; height: 111px;" /></p>

<h2>Использование сортировки цен с валютой в 1C-Bitrix версии 16.0.3 и старше</h2>

<p>Для того что бы использовать эту возможность, надо посмотреть в вашей системе, какой тип цены является базовы, для этого идем в Магазин &rarr; Настройки &rarr; Типы цен</p>

<p><img alt="" src="/upload/image/620d723fedbc77b3e7f6f582f303edf6.jpg" style="width: 600px; height: 499px;" /></p>

<p>В моем случае это ID = 1</p>

<p>Дальше мы добавляем в вызов компонента возможность сортировать по убыванию цены, например:</p>

<pre class="brush: php;  toolbar: false;">
		&quot;ELEMENT_SORT_FIELD&quot; =&gt; &quot;CATALOG_PRICE_SCALE_1&quot;,
		&quot;ELEMENT_SORT_ORDER&quot; =&gt; &quot;desc&quot;, 
</pre>

<p>Или возрастанию:</p>

<pre class="brush: php;  toolbar: false;">
		&quot;ELEMENT_SORT_FIELD&quot; =&gt; &quot;CATALOG_PRICE_SCALE_1&quot;,
		&quot;ELEMENT_SORT_ORDER&quot; =&gt; &quot;asc&quot;, 
</pre>

<p>Так же, вы можете добавить 2 параметр сортировки с ключем ELEMENT_SORT_FIELD2 и ELEMENT_SORT_ORDER2.</p>

<h3>Но что делать тем, у кого версия битрикса младше 16.0.3?</h3>

<p>Для этого есть разные способы, я решил использовать дополнительное свойство, в которое я пишу цену в рублях (конвертирую) и уже сортирую по ней. Сейчас я его подробно опишу.</p>

<p>Для начала, нам нужно создать свойство: PRICE_SORT, в название я написал &laquo;Цена в рублях для сортировки&raquo;, тип: число.</p>

<p><img alt="" src="https://www.jelu.ru/upload/image/7dfdcdd21f9b6ab13d22f851c6f73f24.jpg" style="width: 600px; height: 88px;" /></p>

<p>Дальше, нам необходимо заполнить его у всех товаров, я это сделал при помощи вот такого скрипта:</p>

<pre class="brush: php;  toolbar: false;">
function update_catalog_price_sort(){
	
	$count = 0;	

	try{
		$arFilter = Array( &quot;IBLOCK_ID&quot; =&gt; 2 );
		$res = CIBlockElement::GetList(Array(), $arFilter, false, false, Array(&quot;ID&quot;, &quot;PROPERTY_PRICE_SORT&quot;, &#39;CATALOG_GROUP_1&#39;) );
		while($row = $res-&gt;GetNext())
		{
			$price = $row[&#39;CATALOG_PRICE_1&#39;];

			echo &quot;Start update {$row[&#39;ID&#39;]}: {$price} {$row[&#39;CATALOG_CURRENCY_1&#39;]} to &quot;;

			if ($row[&#39;CATALOG_CURRENCY_1&#39;] != &#39;RUB&#39;){
				$price = CCurrencyRates::ConvertCurrency($price, $row[&#39;CATALOG_CURRENCY_1&#39;], &#39;RUB&#39;);
			}

			if ($price != $row[&#39;PROPERTY_PRICE_SORT_VALUE&#39;]){

				CIBlockElement::SetPropertyValuesEx($row[&#39;ID&#39;], 2, array(
					&#39;PRICE_SORT&#39;  =&gt; $price
				));

				echo &quot;{$price} {RUB} - DONE \n&quot;;

				$count++;

				sleep(0.2);

			} else {
				echo &quot;{$price} {RUB} - NOT NEED UPDATE \n&quot;;
			}
		}

	} catch(Exception $ex) {
		smail(&#39;Запуск обновления цен-сортировок&#39;, &#39;Провал - обновления:&#39; . $ex-&gt;getMessage() );
	}
	
	return $count;
}
</pre>

<p>Вначале мы запрашиваем все товары в системе, у меня около 120 тыс. Из запроса мы получаем:</p>

<ul>
	<li>ID - индификатор товара</li>
	<li>CATALOG_PRICE_1 &mdash; цена товара. Учтите, что если у вас, базовый тип цены другой (смотри выше где можно проверить), то и цифра в конце ключа, будет другой. В любом случае, вы всегда можете сделать print_r($row) и узнать правильность ID базовой цены</li>
	<li>CATALOG_CURRENCY_1 &mdash; в какой валюте сохранена цена. Так же как и с ценой, важно учитывать ID в конце ключа</li>
</ul>

<p>Дальше все просто, если валюта отличается от RUB, делаем конвертацию:</p>

<pre class="brush: php;  toolbar: false;">
$price = CCurrencyRates::ConvertCurrency($price, $row[&#39;CATALOG_CURRENCY_1&#39;], &#39;RUB&#39;);
</pre>

<p>и потом полученную цену сравниваем с тем, что у нас сохранено в PRICE_SORT (ключ в массиве: PROPERTY_PRICE_SORT_VALUE), если цены различаются, обновляем.</p>

<p>Для отладки я использую вывод информации и отлов исключения, с уведомление на почту. Дальше нам остается функцию update_catalog_price_sort() поместить в агент, который будет обновлять цены. Я его добавил в агент обновляющий валюту. Он у меня запускается раз в сутки, когда на сервере минимальная нагрузка.</p>

<p>Учтите важный момент! Это ресурсоёмкая задача, по-этому агенты должны исполняться на cron.</p>

<p>Ну и самое важное, прописываем наше поле PRICE_SORT в вызове компонента:</p>

<pre class="brush: php;  toolbar: false;">
	&quot;ELEMENT_SORT_FIELD&quot; =&gt; &#39;PROPERTY_PRICE_SORT&#39;,
</pre>

<p>Надеюсь эта статья будет вам полезна, если вы нашли ошибки или опечатки, пишите в комментариях.</p>
]]></summary>
<link href="https://www.jelu.ru/post/1s-bitriks-sortirovka-po-cene-v-sistemah-s-raznoy-valyutoy.html"></link>
<id>urn:uuid:5e3520cb-b3d3-7e4f-9fda-f9754c9aaf37</id>
</entry>
<entry>
<title>Bitrix. Исправляем ошибку «Работа с сокетами - Ошибка! Не работает»</title>
<author>Jelu</author>
<published>2016-05-21T00:00:00+03:00</published>
<updated>2016-05-21T00:00:00+03:00</updated>
<summary type="html"><![CDATA["
<p>Во время тестирования сайта, выскакивает следующая ошибка:</p>

<pre class="brush: php;  toolbar: false;">
Работа с сокетами (check_socket): Fail</pre>

<p><img alt="" src="/upload/27-02-2016/001.png" title="" /><br />
А в журнале мы видим следующий лог:</p>

<pre class="brush: php;  toolbar: false;">
2016-Feb-27 13:41:10 Работа с сокетами (check_socket): Fail
Connection to site.ru:80  Success
== Request ==
GET /bitrix/admin/site_checker.php?test_type=socket_test&amp;unique_id=83f81a8666278b68e58012ce161a1dd0 HTTP/1.1
Host:  site.ru


== Response ==
HTTP/1.1 404 Not Found
Server: nginx/1.4.6 (Ubuntu)
Date: Sat, 27 Feb 2016 12:41:10 GMT
Content-Type: text/html
Content-Length: 177
Connection: keep-alive

== Body ==
&lt;html&gt;
&lt;head&gt;&lt;title&gt;404 Not Found&lt;/title&gt;&lt;/head&gt;
&lt;body bgcolor=&quot;white&quot;&gt;
&lt;center&gt;&lt;h1&gt;404 Not Found&lt;/h1&gt;&lt;/center&gt;
&lt;hr&gt;&lt;center&gt;nginx/1.4.6 (Ubuntu)&lt;/center&gt;
&lt;/body&gt;
&lt;/html&gt;

==========
</pre>

<p>Для начала мы видим в этом логе, что при запросе система получает 404 ошибку. Нам нужно понять почему она происходит. Для этого нам нужно проверить логи веб-сервера. Так как у меня работает на nginx + apache2, я открыл логи nginx (Linux /var/log/nginx/error.log).</p>

<p>В данном логе я ищу мой запрос</p>

<pre class="brush: php;  toolbar: false;">
2016/02/27 13:41:10 [error] 2309#0: *658 openat() &quot;/usr/share/nginx/html/bitrix/admin/site_checker.php&quot; failed (2: No such file or directory), client: 127.0.0.1, server: localhost, request: &quot;GET /bitrix/admin/site_checker.php?test_type=socket_test&amp;unique_id=83f81a8666278b68e58012ce161a1dd0 HTTP/1.1&quot;, host: &quot;site.ru&quot;
</pre>

<p>И что мы тут видим? Когда скрипт обращается сам к себе, то происходит обращение вообще не понятно по какому адресу &laquo;/usr/share/nginx/html/bitrix/admin/site_checker.php&raquo;, тогда как сайт лежит: /var/www/site.ru/www/bitrix/admin/site_checker.php</p>

<p>Так же обратите внимание по какому адресу обращается скрипт:</p>

<pre class="brush: php;  toolbar: false;">
client: 127.0.0.1, server: localhost, 
</pre>

<p>Из этого мы делаем вывод что site.ru привязан к localhost и при обращении сайта к самому себе пытается найти файлы не в папке сайта, а в папке nginx по умолчанию. Открыв фаил /etc/hosts я увидел следующую запись:</p>

<pre class="brush: php;  toolbar: false;">
127.0.0.1 localhost.localdomain localhost site.ru
</pre>

<p>Изменив эту строчку на</p>

<pre class="brush: php;  toolbar: false;">
127.0.0.1 localhost.localdomain localhost
</pre>

<p>я успешно прошел тест, и ошибка больше не возникала!</p>
]]></summary>
<link href="https://www.jelu.ru/post/bitrix-ispravlyaem-oshibku-rabota-s-soketami-oshibka-ne-rabotaet.html"></link>
<id>urn:uuid:608b414e-3339-cf7d-2bcd-5951e64459a9</id>
</entry>
</feed>