Skip to content

Instantly share code, notes, and snippets.

@dkhorev
Last active April 12, 2024 04:49
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 7 You must be signed in to fork a gist
  • Save dkhorev/33ed27a7259ed9cf0678b767764234e5 to your computer and use it in GitHub Desktop.
Save dkhorev/33ed27a7259ed9cf0678b767764234e5 to your computer and use it in GitHub Desktop.
Фишки битрикс
Уже давно не работаю с битрикс, сохраняю на память
Как сделать фильтр по возрасту для CUser::GetList ?
$stmp_1 = (new \DateTime())->modify('-18 year')->getTimestamp();
$stmp_2 = (new \DateTime())->modify('-16 year')->getTimestamp();
$filter = Array(
"PERSONAL_BIRTHDAY_1" => ConvertTimeStamp($stmp_1, 'SHORT'),
"PERSONAL_BIRTHDAY_2" => ConvertTimeStamp($stmp_2, 'SHORT')
);
$rsUsers = CUser::GetList(($by="personal_birthday"), ($order="asc"), $filter);
while($arUser = $rsUsers->Fetch()){
print_r($arUser);
В процессе выполнения запроса сервер оборвал соединение. Проблема связана с настройкой MySQL и часто возникает когда на сервере установлен небольшой лимит времени на соединение.
Установите в bitrix/php_interface/after_connect.php:
$DB->Query("SET wait_timeout=28800");
исключаем из идекса папки через райт клик, и массово файлы и папки install
PHPStrom - Settings - Directories - exclude files
*min.js;*.log;*.xml;*.txt;*.map.js;*min.css;*.cab;*.jar;*.rar;*.zip;*.eot;*.ttf;*.svg;*.woff;*.woff2;*.png;*.gif;*.jpg;
перебор объекта в JS
Object.keys(obj).forEach(function (key) {
var value = obj[key];
// do something with key or value
});
for (let item in Items) {
...item
}
CIBlockElement::GetProperty быстрее в разы 0.047003 vs 0.002
проверка на выборке из иб с 500к элементов
подружить Б с mpdf - в настройке апача установить на директорию где скрипт который вызывает мпдф
<Directory "%hostdir%/ajax/kp2pdf/">
AllowOverride All
php_admin_value mbstring.func_overload 0
</Directory>
ошибки выгрузок:
большие фото в 1С
лишние ТП или итемы - настраивать отборы или писать обработки на импорт
Нет цен в выгрузке
Итак, что у нас должно быть по соглашениям:
1. Должно быть типовым (не индивидуальным)
2. Должно быть действующим. т.е. статус соглашения должно быть "Действует"
3. Должно быть с пустым сегментом партнеров, т.е. не заполнено поле "Сегмент партнеров"
4. Должно быть доступно внешним пользователям, т.е. установлен флаг "Доступно внешним пользователям".
4.1 Если флаг "Доступно внешним пользователям" не виден, то нужно включить использование внешних пользователей (в администрировании флаг "Разрешить доступ внешним пользователям" - я смотрю на версии УТ11.2)
Затем в соглашении нужно указать вид цены, по которому мы хотим, чтобы выгружались цены.
Убедиться, что по выбранному виду цены имеются цены заполненные на товары и/или характеристики.
Нет цен в выгрузке
Заранее скажу, просто переименование типа цены иногда не помогает.
открыл таблицу b_catalog_group там запись с моим типом цены, и там в поле xml_id ввёл тот самый ИдТипаЦены, сохранил (из prices.xml)
0--. см. интрукцию бх по настройке - в админке надо включить обмен с сайтом:
https://dev.1c-bitrix.ru/learning/course/index.php?COURSE_ID=42&LESSON_ID=6333
0. создать типовое соглашение для выгрузки цен https://yadi.sk/i/yfZHI-WS3M2CFM
1. выгрузить цены в файл и id типа цены прописать в БХ в тип цены розница
2. чтобы выгрузить картинки 1 раз надо сделать "принудительный обмен" вместо простого
3. прикрепление картинок к ТП https://dev.1c-bitrix.ru/community/blogs/product_features/a-pleasant-change-in-modules-for-1c-prikreplena-pictures-to-the-charac.php
Пишет у ТП "предложение без товара" когда мы связали товар с родителем через CML2_LINK
не работает связка по старому:
Bitrix\Catalog\Model\Product::update($nProductID, ['QUANTITY' => $nTotalAmount]);
делаем при добавлении продукта прямое указание TYPE
Bitrix\Catalog\Model\Product::add(['ID' => $id, 'QUANTITY' => $arItem['CATALOG_QUANTITY'], 'TYPE' => ProductTable::TYPE_OFFER]);
или
Bitrix\Catalog\Model\Product::update($nProductID, ['QUANTITY' => $nTotalAmount, 'TYPE' => ProductTable::TYPE_OFFER]);
for ajax:
define("NO_KEEP_STATISTIC", true);
define("STOP_STATISTICS", true);
define("NO_AGENT_CHECK", true);
define("NO_AGENT_STATISTIC", true);
Для отбора по arFilter в GetList - Обязательно должно быть использованы поля IBLOCK_ID и ID, иначе не будет работать корректно.
VM Bitrix - не ставить сайты в дефолтный путь, там нельзя задать домен, прикрепить сертификат и т.п.
в дефолтном папке только редирект файл
altasib.feedback - формы связи
Настройки - Главнй Модуль
Безопасная авторизация
если включено - каждый клиент генерит уникальный ключ и композит перезаписывается
Чтобы рзместить динамик элемент в карточке товара - нельзя его подключить прямо в шаблоне товара
нужно подключить в element.php и в шаблоне своего компонента поставить динамическую область с id контейнера
контейнер положить в шаблон карточки
срабатывает на втором хите++
!!! когда передаешь на фильтрацию IDшники убедись что они не пустые - иначе идет выборк по всему ИБ !!!
<?php
// хак с подгрузкой в крошки всех подразделов
$arSectionFilter["ID"] = intval($arResult['VARIABLES']['SECTION_ID']);
$rsSection = CIBlockSection::GetList([], $arSectionFilter);
if ($arSection = $rsSection->GetNext()) {
$rsPath = GetIBlockSectionPath($arSection["IBLOCK_ID"], $arSection["ID"]);
while ($arPath = $rsPath->GetNext()) {
$APPLICATION->AddChainItem($arPath["NAME"], $arPath["SECTION_PAGE_URL"]);
}
}
?>
метод для получения корзины юзера - вызывать с true где не нужно ее создавать автоматически (счетчики товаров и тп)
чтобы боты не генерили пустые корзины
если на странице компонент с фильтрацией которая не часто меняется ставить "Кешировть с фильтрами" - ускорение
\CIBlockElement::SetPropertyValuesEx(
$this->idItem,
$this->MASTER_IBLOCK_ID, // если не указывается - делается доп запрос в БД на чтение!!
$PROP
);
тонкая настройка смартфильтра
https://dev.1c-bitrix.ru/community/blogs/product_features/smart_filter.php
скачивание версий модулей если их модифицировал кто-то /bitrix/admin/update_system.php?BX_SUPPORT_MODE=Y
– Чтобы протестировать загрузку товаров, нужно кинуть файлы обмена в /upload/1c_exchange/.
Далее под админом открываем урл /bitrix/admin/1c_exchange.php?type=catalog&mode=import&filename=ИМЯ_ФАЙЛА{import.xml, offers.xml и т.д.}.
И дальше обновляем страницу, анализируя шаги обмена за чашкой кофе.
У меня переменную от GET обрабатывается preg_replace, т.к. все в UTF-8, то необходимо было добавить модификатор "u".
Когда включена индексация элементов ИБ, каждый раз при изменении срабатывает сео модуль и пересоздает sitemap.xml и плодит их постоянно
https://klondike-studio.ru/blog/bitrix-avtogeneratsiya-sitemap-xml-danger/
скрипт для крон https://tuning-soft.ru/articles/bitrix/1c-bitrix-auto-generation-of-site-map-sitemap-xml-using-crontab.html
https://dev.1c-bitrix.ru/support/forum/forum6/topic84061/
Если вкратце — в админке карта генерируется файлом /bitrix/modules/seo/admin/seo_sitemap_run.php, из него нужно выкинуть всё что касается пошаговости (например проверки $v < $arValueSteps['...']), указать по какому профилю будет запуск и повесить на крон. Файл, конечно, нужно скопировать из системной папки.
сброс проверки источника запроса
COption::SetOptionString("catalog", "DEFAULT_SKIP_SOURCE_CHECK", "Y");
COption::SetOptionString("sale", "secure_1c_exchange", "N");
news.list - чтобы работала подгрузка страниц по PAGEN_1 аяксом, нужно в компоненте задать DISPLAY_TOP_PAGER или DISPLAY_BOTTOM_PAGER = Y
$.ajax({
url: "/ajax/load_press_center_page.php",
data: {PAGEN_1: ++nPressPageCounter},
type: "GET",
dataType: "html",
timeout: 60000,
async: true,
success: function (response) {
}
});
// номер текущей страницы
$curPage = $arResult["NAV_RESULT"]->NavPageNomer;
// всего страниц - номер последней страницы
$totalPages = $arResult["NAV_RESULT"]->NavPageCount;
// номер постраничной навигации на странице
$navNum = $arResult["NAV_RESULT"]->NavNum;
http://mattweb.ru/item/98-zagruzka-novostej-s-pomoschu-ajax-na-sajte-pod-upravleniem-1s-bitriks
существует инфоблок с разделами, в каждом разделе соответственно элементы,
как с помощью комплексного или простого компонента catalog вывести все элементы данного инфоблока из всех разделов подразделов и т.д.
разобралась, надо было просто поставить галочку в catalog.section Показывать все элементы, если не указан раздел
Добавил в вызове компонента catalog.section
"SHOW_ALL_WO_SECTION" => "Y"
а в комплексном компонента
"SET_STATUS_404" => "N",
"SHOW_404" => "N",
https://idea.1c-bitrix.ru/smart-filter-support-for-work-in-the-root-directory-without-specifying/index.php?pagen=2#comments
версия для печати делается через @media print в css намного быстрее
// этот блок переопределяет постраничную навигацию с учетом изменившегося кол-ва ITEMS
$GLOBALS['NavNum']--; // Эта строка гарантирует корректную работу кеша
$rsItems = new CDBResult();
$rsItems->InitFromArray($arResult['ITEMS']);
$rsItems->NavStart($arParams['CUSTOM_NEWS_COUNT']);
$arResult['CUSTOM_NAV_STRING'] = $rsItems->GetPageNavString("", $arParams['PAGER_TEMPLATE']);
$arResult['NAV_RESULT'] = $rsItems;
$arResult['ITEMS'] = array();
while (is_object($rsItems) && $arItem = $rsItems->GetNext()) {
$arResult['ITEMS'][] = $arItem;
}
// dump($arResult['NAV_RESULT']->NavPageCount);
// dump($arResult['NAV_RESULT']->NavPageNomer);
хороший компонент для быстрых отзывов/комментов http://marketplace.1c-bitrix.ru/solutions/api.reviews/?sphrase_id=74299951#tab-about-link
а также алтасиб фидбек хорош (аякс)
продление демо лицензий https://www.1c-bitrix.ru/bsm_register.php
классная сжималка фоток на сайте dev2fun.imagecompress
https://tuning-soft.ru/articles/phpstorm/how-to-speed-up-phpstorm.html
видео - https://youtu.be/X5jfgYSAzd0
Нам понадобятся плагины: imagemagick, jpegoptim и optipng
Устанавливаем плагины (centos)yum -y install jpegoptim optipng ImageMagick
Далее переходим в папку с картинками (например upload) и выполняем команды:
Уменьшаем слишком большие файлы (больше 2000px) Осторожно! Перезаписывает существующие файлы.
find -name *.jpg -exec mogrify -resize '2000x>' '{}' \;
Сжатие без потерь:
find -name *.jpg -exec jpegoptim --all-progressive --strip-all -t '{}' \;
find -name *.png -exec optipng -o3 '{}' \;
для определенной папки:
find /home/bitrix/ext_www/alefmex.ru/upload/iblock/ -iname "*.jpg" -exec jpegoptim --strip-all --all-progressive -pm85 {} \;
find /home/bitrix/ext_www/alefmex.ru/upload/iblock/ -iname *.png -exec optipng -o3 '{}' \;
Автоматизируем оптимизацию, повесив скрипт на cron. Создаем файлик img-optim.sh в /home/bitrix и кладем в него наши команды с небольшим изменением. Команда find будет искать только те файлы которые были созданы/изменены в течение дня. Т.ч. заранее необходимо запустить вручную команду для оптимизации всех картинок, а дальше уже добавлять обработчик на крон.
#!/bin/bash
find /home/bitrix -name *.jpg -ctime -1 -exec jpegoptim --all-progressive --strip-all -t '{}' \;
find /home/bitrix -name *.png -ctime -1 -exec optipng -o3 '{}' \;
Добавляем в крон crontab -e
0 0 * * * /home/bitrix/img-optim.sh >/dev/null 2>&1
// правильное добавление доп скриптов в шаблоне компонента
$this->addExternalCss(SITE_TEMPLATE_PATH . "/css/bootstrap-wysiwyg.css");
$this->addExternalJS(SITE_TEMPLATE_PATH . "/js/bootstrap-wysiwyg.min.js");
$this->addExternalJS($templateFolder . "/js/bootstrap-wysiwyg.min.js");
// mediaplayer plugin
$this->addExternalJS($templateFolder . "/mediaelement/mediaelement-and-player.min.js");
$this->addExternalJS($templateFolder . "/mediaelement/plugin/markers.min.js");
$this->addExternalCss($templateFolder . "/mediaelement/mediaelementplayer.min.css");
404 для каталога https://dev.1c-bitrix.ru/support/forum/forum6/topic39571/ (последний коммент дельный)
настройка сео для смарт фильтра http://it-svalka.ru/razrabotka/tonkaya-nastroyka-seo-umnogo-filtra.html
Когда необходимо импортировать большую базу в mysql через командную строку в локальном веб-вервере OpenServer, то нужно проделать несколько нехитрых рукодвижений.
1. Узнаем версию Mysql в OpenServer, для этого переходим в Настройки -> Вкладка Модули -> MySQL/MariaDB
2. Кидаем файл базы, например baza.sql в папку с сайтом в OpenServer, по пути: d:\OpenServer\domains\site
3. Возвращаемся в OpenServer, тыкаем по флажку правой кнопкой, выбираем Дополнительно -> Консоль, запускаем консоль.
4. В консоле переходим в папку Mysql, например: d:\OpenServer\modules\database\MySQL-5.6-x64\bin
5. Делаем импорт ./mysql -uuser [-p123] baza_mysql < D:\OpenServer\domains\site\baza.sql, где -u— пользователь базы, -p — пароль пользователя базы, baza_mysql — имя базы в которую нужно сделать импорт и путь базы для импорта.
./mysql.exe -uroot profitcon < /c/_Biz/OpenServer527/domains/profitcon-crm-bitrix.loc/vdnfvtjdb.sql
*
* шпарглаки по ХЛ блокам:
* http://thisis-blog.ru/elementi-highload-bloka/
* http://julliet.ru/articles/highload-api.html
* http://max22.ru/d7/highload-about/
// MYSQL RAW TEST
// global $DB;
// // $DB->Query("TRUNCATE TABLE cache_entity_vars;");
// $arTest = $DB->Query("DELETE FROM cache_entity_vars1 WHERE UF_CODE='$sProp' AND UF_IB='".COMPANY_IB_ID_REL."'");
//
// $xCount = 0;
// $arTmp = [];
// $xLimit = 1000;
// foreach ($arResult as $sVal) {
// $arTmp[] = "('".$sProp."','".COMPANY_IB_ID_REL."','".base64_encode($sVal)."')";
// $xCount++;
//
// // write
// if ($xCount >= $xLimit) {
// $DB->Query("INSERT INTO `cache_entity_vars1` (UF_CODE, UF_IB, UF_VALUE) VALUES " . implode(',', $arTmp));
// // $this->dump('Записали пакет из ' . $xCount);
// $arTmp = [];
// $xCount = 0;
// }
// }
// if (count($arTmp)) {
// $DB->Query("INSERT INTO `cache_entity_vars1` (UF_CODE, UF_IB, UF_VALUE) VALUES " . implode(',', $arTmp));
// // $this->dump('Записали пакет из ' . $xCount);
// }
// MYSQL RAW TEST
// чтение из mysql
// $arTest = $DB->Query("SELECT * FROM cache_entity_vars1 WHERE UF_CODE='$sProp' AND UF_IB='".COMPANY_IB_ID_REL."'");
// $arTest = $arTest->SelectedRowsCount();
Поиск и замена по регулярному выражению помогает решить проблему.
Жмем CTRL+R, вставляем <!--.[a-zA-Z _-]{1,} -->, заменяем на пустую строку
// выборка с arGroupBy _значительно_ быстрее чем без (когда надо подсчитать кол-во уник значений)
$db_list = \CIBlockElement::GetList(
['ID' => 'ASC'],
$arFilter,
['PROPERTY_SOME'], // arGroupBy
false,
['PROPERTY_SOME']
);
Страница без хедера и футера
<?php
define("NO_KEEP_STATISTIC", true);
define("STOP_STATISTICS", true);
define("NO_AGENT_CHECK", true);
define("NO_AGENT_STATISTIC", true);
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php");
//Code here
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/epilog_after.php");
Это общие курсы, которые надо пройти если хочешь собирать проекты на битрикс... основы так сказать.
По ним же подготовка к экзаменам №1 и №2
https://academy.1c-bitrix.ru/training/course/
Конкретно под задачу вот эти видео (весь 1 урок):
https://www.youtube.com/playlist?list=PLzPivwyXljVVXMH5VNSfSocd1P33kJZVj
как работаем с кастомизацией битрикс - типичный воркфлоу:
несмотря на то что сказано в задаче ("сделать компонент" - не понимать буквально, а подумать сначала...)
1. пробуем вывести базовым компонентов, многие из них поддерживают даже получение связанных свойств от других ИБ (к сожалению news.list к таким не относится)
2. смотри компонент который вроде подходит (делает хотя бы часть задачи) - news.list подходит, он выведет нам список и ID привязанных эелементов
3. нужно вывести другие связанные данные? да, нам нужно получить имена юзеров - не кидаемся сразу копировать ньюз лист, а думаем дальше
4. расширять логику стандартных шаблонов можно через result_modifier.php
5. думаем - можем ли мы его тут использовать? (почти всегда ответ ДА, в нашем случае тоже "да")
итого мы не изобретаем велосипед, а берем готовый компонент и получаем наши данные в result_modifier
задача решена и быстро (10-15 минут реально :))
если и когда понадобится оптимизация прям очень хардкорная - тогда уже скопируем компонент в свой неймспейс и будем пилить
/**
* get https or http text
*
* @return string
*/
private static function GetServerHttp()
{
$bHttps = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') || $_SERVER['SERVER_PORT'] == 443;
if (true === $bHttps) {
return 'https://';
} else {
return 'http://';
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment