Битриксоид из Колхоза
744 subscribers
298 photos
9 videos
5 files
98 links
Изучаем #Битрикс, находим ошибки, обслуживаем проекты, пишем модули, разрабатываем компоненты.

Ютуб: shorturl.at/himBM
Модуль-ускоритель: shorturl.at/lsyTW
Модуль комментариев: shorturl.at/ACDT2
Сайт разработчика: https://burlaka.studio
Download Telegram
Народ, если вы чего интересного замечаете, пишите мне, вы будете указаны как автор подсказки.
@AlexeyGfiProgrammer
=====
«Новый» фильтр и его where

$filter = \Bitrix\Main\Entity\Query::filter();

$filter->where();
$filter->whereNot();
$filter->whereColumn();
$filter->whereNull();
$filter->whereNotNull();
$filter->whereIn();
$filter->whereNotIn();
$filter->whereBetween();
$filter->whereNotBetween();
$filter->whereLike();
$filter->whereNotLike();
$filter->whereExists();
$filter->whereNotExists();
$filter->whereMatch();
$filter->whereNotMatch();
$filter->where();
$filter->whereNot();
$filter->whereColumn();
$filter->whereNull();
$filter->whereNotNull();
$filter->whereIn();
$filter->whereNotIn();
$filter->whereBetween();
$filter->whereNotBetween();
$filter->whereLike();
$filter->whereNotLike();
$filter->whereExists();
$filter->whereNotExists();


#битрикс #orm #D7 #запрос
=====
Пример использования нового фильтра, код из ядра

$filter = Main\Entity\Query::filter();
$filter->whereIn('PRODUCT_ID', $pageOfferIds);

$filter->where(
Main\Entity\Query::filter()
->logic('or')
->where('QUANTITY_FROM', '<=', 1)
->whereNull('QUANTITY_FROM')
);

$filter->where(
Main\Entity\Query::filter()
->logic('or')
->where('QUANTITY_TO', '>=', 1)
->whereNull('QUANTITY_TO'));

$iterator = Catalog\PriceTable::getList(array(
'select' => array(
'PRODUCT_ID', 'CATALOG_GROUP_ID', 'PRICE', 'CURRENCY',
'PRICE_SCALE', 'TMP_ID'
),
'filter' => $filter,
'order' => array('PRODUCT_ID' => 'ASC', 'CATALOG_GROUP_ID' => 'ASC')
));
while ($row = $iterator->fetch())
{
...
}

#битрикс #orm #D7 #запрос
=====
Операторы в $filter->where

$filter = Main\Entity\Query::filter();

$filter->whereColumn('PARENT.LEFT_MARGIN', '<', 'SECTION.LEFT_MARGIN')
$filter->where('SHIPPING_CENTER', '=', 'Y');
$filter->where('PRICE', 'between', array(100, 7770));

#битрикс #orm #D7 #запрос
=====
Phpstorm временные файлы нужного типа

Есть в шторме хорошая штука: scratch-файлы.
Когда можно временное хранилище-болванку создать, нужного типа (php, js, css, ...) но это не будет файл проекта. Код набросать или выгрузить туда на время.

Например, есть у нас скрипт отладки и записи во временный файл. Мы ходим по файлам ядра и ищем проблему. Приходится код вставлять, потом забирать, потом снова вставлять... Временное хранилище нужного типа создали, там код набросали и при необходимости оттуда берём.

Ctrl+Alt+Shift+Insert

#bitrix #phpstorm
=====
js/json туда и обратно

Парсер правильной json-строки, например:
$json = '{"a":1,"b":2,"c":3,"d":4,"e":5}';
...производим через специальный класс (подсказал @altavir) — он учитывает кодировку, работает как под utf-8 так и под windows-1251:
\Bitrix\Main\Web\Json::decode($json);

Если же мы имеем строку, похожую на javascript-объект и нам её нужно корректно распарсить в php-объект, например:
$jsObject = "{\nid: 123,\nclickmap: true,\ntrackLinks: true,\naccurateTrackBounce: true,\nwebvisor: true,\necommerce: "dataLayer"\n}";
...пользуем
\CUtil::JsObjectToPhp($jsObject, true);
(!) со вторым параметром true, чтобы механизм пошёл не по json_decode (который при парсинге такой строки навернётся), а через «грязный парсинг».

Ну и соответственно в обратную сторону:
• упаковка php-объекта в json:
\Bitrix\Main\Web\Json::encode($json);
• упаковка php-объекта в javascript:
\CUtil::PhpToJSObject($phpObject, ...тут_парочка_интересных_ключей);

#битрикс #json
=====
Я.Метрика

Коды подключения, полученные от техподдержки.

🇷🇺 https://mc.yandex.ru/metrika/tag.js
🇺🇦 https://cdn.jsdelivr.net/npm/yandex-metrica-watch/tag.js

#метрика #яндекс
Битриксоид из Колхоза
===== Я.Метрика Коды подключения, полученные от техподдержки. 🇷🇺 https://mc.yandex.ru/metrika/tag.js 🇺🇦 https://cdn.jsdelivr.net/npm/yandex-metrica-watch/tag.js #метрика #яндекс
Ещё техподдержка сказала, что встречающийся в коде <img src="https://mc.yandex.ru/watch/49682911"... можно удалить без вреда для счётчика и показателей (критично для Украины).
=====
Собрать данных для анализа


Пример кода для сбора статистики из проблемной функции.
Например, компонент что-то не то выдаёт наружу. Идём в CIBlockElement::GetList
...bitrix/modules/iblock/classes/mysql/iblockelement.php
...и обеспечиваем себе статистику на хите.

global $USER;
if ($USER->GetID() == 1) {
\Bitrix\Main\Diag\Debug::writeToFile(
array(
'LOG_DATE' => date("Y-m-d H:i:s"),
'$arOrder' => $arOrder,
'$arFilter' => $arFilter,
'BACKTRACE' => \Bitrix\Main\Diag\Helper::getBackTrace(3, DEBUG_BACKTRACE_IGNORE_ARGS)
)
);
}

getBackTrace(3... — на сколько уровней (в примере — 3) вверх загребать backtrack-информацию
$USER->GetID() == 1 — код пользователя (в примере — 1), под которым работаем админом.

Отладка выведется в файл /__bx_log.log
Не забываем чистить после отладки!

#битрикс #отладка
=====
В строке строку строкой

\Bitrix\Main\Text\BinaryString — библиотека для базовых операций над и со строками.
Учитывает кодировку и наличие необходимых функций в наборе.

То есть можно через
mb_strpos(
$str,
'bitrixoid',
0,
SITE_CHARSET
);

...а можно через библиотеку:
\Bitrix\Main\Text\BinaryString::getPosition(
$str,
'bitrixoid'
);

#битрикс #строки
=====
Попасть в кодировку

\Bitrix\Main\Text\Encoding
::convertEncodingToCurrent($string)
- метод, который конвертирует $string в кодировку проекта.

И в том же классе интерес представляет метод определения, является ли кодировка строки UTF-8 или нет:
\Bitrix\Main\Text\Encoding
::detectUtf8($string)

#битрикс #utf
=====
Проброс PAGEN_X в аякс и там его корректный подхват
Способ 1

a. При аякс-вызове в пост-параметры пробросить pagen, например:
PAGEN_2=3

b. В компоненте, построенном «на классах», в унаследованной функции onPrepareComponentParams вызываем родительский метод.

Внутри него есть функция makeMagicWithPageNavigation, которая выцепляет pagen из пост-параметров (а не из урла) и при корректном обнаружении инитит глобальную $NavNum...
Битриксоид из Колхоза
===== Проброс PAGEN_X в аякс и там его корректный подхват Способ 1 a. При аякс-вызове в пост-параметры пробросить pagen, например: PAGEN_2=3 b. В компоненте, построенном «на классах», в унаследованной функции onPrepareComponentParams вызываем родительский…
c. В том же компоненте, в унаследованной функции initialLoadAction вызываем родительский метод: parent::initialLoadAction();, который внутри себя доходит до GetNavParams. Эта функция как раз и подватывает подготовленный на шаге "b" $NavNum.

Таким образом происходит дополнительно страховка от следующей ситуации:
...на странице несколько шаблонов с постраничкой. Каждый из них соответственно линкуется на свой pagen, начиная с единицы:
• первый компонент смотрит на PAGEN_1;
• второй компонент смотрит на PAGEN_2;
• третий компонент смотрит на PAGEN_3
... а в файле, который обслуживает аякс-запрос, запрашиваемый компонент единственный. И согласно указанной выше логике он должен смотреть на PAGEN_1, хотя в запросе с основной страницы он приходит как PAGEN_2.

#битрикс #постраничка #аякс
=====
Фильтрация и обезопасивание $_REQUEST

Объекту request можно применить фильтр. В админке уже есть реализованный класс PostDecodeFilter, который приводит post -данные в кодировку проекта. Реализует интерфейс IRequestFilter. Можно по аналогии запилить свой класс, который например обезопасивает данные (типа прогоняет через htmlspecialchars)... и накатить на request несколько фильтров.

#битрикс #фильтры #безопасность
=====
Обработка строк через «аяксовский» механизм

Имеем кусок html, который содержит javascript-код (как правило, такое получаем через аякс). Нам из него нужно выцепить скрипты, выполнить на странице и ещё колбэк подписать на событие обработки всех скриптов.

Пинаем процессор, который разделит мух по видам
BX.processHTML(result);

...и скармливаем JS другому процессору
BX.ajax.processScripts

🤟 Приятный нюанс: наш колбэк выполнится тогда, когда реально все скрипты отработают. То есть буквально: если мы запрашиваем подключение каких-то javascript-файлов, колбэк будет вызван тогда, когда все файлы в списке будут прогружены на страницу.

#битрикс #аякс
=====
Свет на поток событий

Скрипт, которым можно пропустить через себя вызовы JS битриксовских событий.
Выполняем в консоли и начинаем видеть поток событий. Благодаря замыканиям, все объекты в логе доступны для инспекции.

let originalBxOnCustomEvent = BX.onCustomEvent;

BX.onCustomEvent = function (eventObject, eventName, eventParams, secureParams)
{
// onMenuItemHover например выбрасывает в другом порядке
let realEventName = BX.type.isString(eventName) ?
eventName : BX.type.isString(eventObject) ? eventObject : null;

if (realEventName) {
console.log(
'%c' + realEventName,
'background: #222; color: #bada55; font-weight: bold; padding: 3px 4px;'
);
}

console.dir({
eventObject: eventObject,
eventParams: eventParams,
secureParams: secureParams
});

originalBxOnCustomEvent.apply(
null, arguments
);
};


Собрано на коде, присланного @zekko_Andrey

#битрикс #отладка #BX #события
=====
is ajax

Внутри \Bitrix\Main\Page\Asset
работает private переменная-флаг ajax.

Его «целевой» потребитель — метод
\Bitrix\Main\Page\Asset::getInstance()->getCss(),
...который в случае установленного аякс-флага пакует стили не в <link...> а оборачивает в javascript-вызов и тогда подключение стилей выглядит например так:
<script type="text/javascript">
BX.loadCSS(['.../.default/style.css?1556374578666']);
</script>

Флаг работает только в паре с инициализацией аякс-шапки
$APPLICATION->ShowAjaxHead(...);
...который его зажигает.

То есть если мы собираем свой аякс-обработчик, чтобы стили были обёрнуты для корректной обработки ответа BX-функциями, мы должны проинициализировать аякс-шапку.

#битрикс #аякс #ajax #BX
Битриксоид из Колхоза
===== is ajax Внутри \Bitrix\Main\Page\Asset работает private переменная-флаг ajax. Его «целевой» потребитель — метод \Bitrix\Main\Page\Asset::getInstance()->getCss(), ...который в случае установленного аякс-флага пакует стили не в <link...> а оборачивает…
Публичным «братом» указанного флага является
$APPLICATION->bInAjax;
...который мы можем проверять например внутри своих компонентов.

Важно помнить, что оба устанавливаются только при иниализации аякс-шапки:
$APPLICATION->ShowAjaxHead(...);

#битрикс #аякс #ajax #BX
Битриксоид из Колхоза
Публичным «братом» указанного флага является $APPLICATION->bInAjax; ...который мы можем проверять например внутри своих компонентов. Важно помнить, что оба устанавливаются только при иниализации аякс-шапки: $APPLICATION->ShowAjaxHead(...); #битрикс #аякс…
Трио-счастья для джсон-аякса замыкает метод
\Bitrix\Iblock\Component\Base::sendJsonAnswer($result);
...который пакует переданный ему массив в джсон, делает нужные финализации и рубит скрипт.

Массив может содержать всё нужное для паредачи наружу. JS метод допакует сам.

#битрикс #json #аякс #ajax
=====
Доступ к индексируемым записям

При подписывании на событие переиндексации
search|onReindex своим обработчиком, важно выбросить ключ PERMISSIONS.

В нём — список групп пользователей, которые будут иметь доступ к просмотру индексируемого контента. Либо числами либо в формате Gчисло.
Доступ для всех == группа с номером 2.

Если ключ PERMISSIONS в ответе не присутствует, запись не маркируется доступом, хотя и сохраняется в поисковый индекс.

В частности, механизм построения сайтмапа буквально указывает при выборке записей группу G2.

#битрикс #индексирование #сайтмап #sitemap