Для выполнения каких-либо действий в назначенный момент в Битриксе используются агенты: учебный курс и cправка API.
Агенты названы крайне неудачно "периодические" и "непериодические". Разберём, какие реально бывают агенты.
Агент - это запись в специальной таблице:
какой код надо выполнить,
когда выполнить,
с каким периодом выполнять,
каким способом назначать время следующего запуска агента (периодический или непериодический агент).
Обычно, когда пользователь зашел на страничку сайта, ядро Битрикса смотрит, есть ли агенты, время которых наступило и выполняет их.
Важно. В начале хита еще не объявлена переменная $USER. Её в агентах использовать нельзя.
Можно в агенте создать объект $USER, что-то с ним сделать и уничтожить.
Реальное время запуска агента обычно чуть-чуть позже, чем время, на которое назначен агент. Момент запуска — это когда кто-то зашел на страницу сайта.
Настройки -> Настройки продукта -> Агенты:
Агенты, прежде всего, бывают повторяющиеся или неповторяющиеся. Это зависит от программиста, который написал код агента.
Если функция агента возвращает вызов себя, то агент повторяется.
Если функция агента ничего не возвращает, то агент будет удален из таблицы и больше не запустится. Агент не повторяется.
Программист может сделать агента, который повторится бесконечное число раз. Или только 2-3 раза в зависимости от условий. В списке агентов это увидеть нельзя. Только смотреть в код.
Пример функций агентов повторяющихся бесконечное число раз:
// пример функций агентов
function TestAgentPeriod()
{
AddMessage2Log( "Периодический BX_CRONTAB:".BX_CRONTAB." BX_CRONTAB_SUPPORT:".BX_CRONTAB_SUPPORT );
return "TestAgentPeriod();";
}
function TestAgentNotPeriod()
{
AddMessage2Log( "Непериодический BX_CRONTAB:".BX_CRONTAB." BX_CRONTAB_SUPPORT:".BX_CRONTAB_SUPPORT );
return "TestAgentNotPeriod();";
}
Вычисление следующего времени запуска.
Для повторяющихся агентов есть смыл говорить об интервале запуска и способе вычисления времени следующего запуска.
В данном примере интервал агентов 15 секунд. Один агент периодический, а другой непериодический.
Назначенное время следующего запуска периодического агента вычисляется так:
Старое назначенное время агента + интервал.
Этот способ позволяет запустить агент точное число раз. Например, раз в день запускается агент очистки старых почтовых событий или агент с ежедневным отчетом о посещаемости сайта.
Назначенное время следующего запуска непериодического агента вычисляется так:
Время завершения последнего запуска агента (выполнение return агента) + интервал
Абсолютное большинство агентов непериодические.
Например, агент пересчета рейтингов запускается раз в час. Но если за сутки не было ни одного посетителя, то логичнее выполнить агент один раз и сдвинуть назначенное время следующего запуска на час вперед после запуска. В случае периодического агента, этот код выполнился бы 24 раза за все сутки.
Агенты могут запускаться не только на хитах пользователя, но и на кроне. Но, как это правильно настроить, — тема отдельной большой статьи.
Доброго времени суток! На форуме поднимался как-то уже вопрос о том, как, подтягивая компоненты битрикса по аяксу вытягивать также и скритп, который подключается к компоненту и файл стилей компонента. Тогда решения данного вопроса нормально не было найдено.
И вот теперь есть решение: Более подробно изучил работу с BX.ajax
Сильно расписывать нет времени, посему, сразу готовые наработки.
Итак, есть какой-то компонент. У данного компонента есть файл result_modifier.php
Т.о. в файл /ajax.php размещаем подключение компонента. Указанным запросом получаем данный компонент и помещаем его в контейнер с id="result_container". Все!
В результате файлы script.js и style.css, подключаемые вместе с компонентом, будут также подключаться и при запросе компонента по технологии ajax.
Пример подключения скриптов для ajaxа - хорошая штука. Но столкнулся ещё с проблемой инициализации битриксовых скриптов после ajax-загрузки: в компоненте catalog.section не срабатывают стандартные действия (добавить в корзину, добавить в сравнение). При этом сами скрипты подгрузились.
Мы рассмотрели, какие бывают агенты. Теперь научимся их запускать на кроне. Мы сможем переложить часть задач с пользователей сайта на крон и ускорить время выполнения страниц.
Признаюсь. К этому снаряду я подходил несколько раз. И только с последнего толчка смог осилить этот вес. Сложность в том, что существует большое количество недокументированных констант и опций. Их совместное поведение совершенно не очевидно.
Константы, которые могут влиять на запуск агентов и отправку писем:
BX_CRONTAB
BX_CRONTAB_SUPPORT
NO_AGENT_CHECK
DisableEventsCheck
Опции модуля main, которые влияют на запуск агентов:
agents_use_crontab - по умолчанию не задана
check_agents - по умолчанию не задана
При этом не всё можно прочитать в исходном коде. Файл ядра Битрикса /bitrix/modules/main/include.php обфусцирован.
Нам надо повесить все агенты на крон.
Была подобная статья и учебный курс, но там есть фатальный недостаток: все почтовые события тоже вешаются на крон. Крон работает с минимальной частотой раз в минуту. Получается, что пользователь нажимает «восстановить пароль» и минуту ждет письмо. Еще один недостаток — статья устарела и в ней нет, как настроить резервное копирование по расписанию.
Нам надо, чтобы отправка писем была на хитах, а все агенты и резервное копирование работали на кроне.
Посмотрим, как сейчас обстоят дела в Битриксе:
По умолчанию на кроне вызывается файл /bitrix/modules/main/tools/cron_events.php:
В файле в самом начале стоит define("BX_CRONTAB", true);. Из-за этого в прологе устанавливается другая константа define("BX_CRONTAB_SUPPORT", true);. В результате данный крон-скрипт обрабатывает ТОЛЬКО непериодические агенты.
Исходный код функции обработки агентов.
function CheckAgents()
{
...
//For a while agents will execute only on primary cluster group
if((defined("NO_AGENT_CHECK") && NO_AGENT_CHECK===true) || (defined("BX_CLUSTER_GROUP") && BX_CLUSTER_GROUP !== 1))
return null;
$agents_use_crontab = COption::GetOptionString("main", "agents_use_crontab", "N");
$str_crontab = "";
if($agents_use_crontab=="Y" || (defined("BX_CRONTAB_SUPPORT") && BX_CRONTAB_SUPPORT===true))
{
if(defined("BX_CRONTAB") && BX_CRONTAB===true)
$str_crontab = " AND IS_PERIOD='N' ";
else
$str_crontab = " AND IS_PERIOD='Y' ";
}
...
return CAgent::ExecuteAgents($str_crontab);
}
Настройка агентов на кроне:
Проверьте, чтобы в файле dbconn.php не было установленных констант:
BX_CRONTAB
BX_CRONTAB_SUPPORT
NO_AGENT_CHECK
DisableEventsCheck
Установите опцию, которая запрещает выполнение агента в прологе:
COption::SetOptionString("main", "check_agents", "N");
echo COption::GetOptionString("main", "check_agents", "Y"); // должно вывестись N
Опция, которая влияет на выбор агентов в функции CheckAgents, должна быть не определена или "N".
COption::SetOptionString("main", "agents_use_crontab", "N");
echo COption::GetOptionString("main", "agents_use_crontab", "N"); // должно вывестись N
<?php
$_SERVER["DOCUMENT_ROOT"] = realpath(dirname(__FILE__)."/. ./..");
$DOCUMENT_ROOT = $_SERVER["DOCUMENT_ROOT"];
define("NO_KEEP_STATISTIC", true);
define("NOT_CHECK_PERMISSIONS",true);
define('BX_NO_ACCELERATOR_RESET', true); // чтобы не глючило на VMBitrix 3.1 из-за Zend при отправке бэкапа в облако.
// здесь никакой агент не выполнится. Потому что мы сделали COption::SetOptionString("main", "check_agents", "N");
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php");
@set_time_limit(0);
@ignore_user_abort(true);
CAgent::CheckAgents(); // а вот тут все агенты выполнятся. И периодические, и непериодические
CEvent::CheckEvents(); // почтовые события мы оставили выполняться на хитах. Но и тут они могут выполняться. Почему нет?
define("BX_CRONTAB", true);
// модуль email-маркетинг
if(CModule::IncludeModule('sender'))
{
\Bitrix\Sender\MailingManager::checkPeriod(false);
\Bitrix\Sender\MailingManager::checkSend();
}
// а еще есть файлик резервного копирования, который запустится, когда его время придет.
require($_SERVER['DOCUMENT_ROOT']."/bitrix/modules/main/tools/backup.php");
?>
Пропишите правило в крон, например * * * * * /usr/bin/php -f /home/bitrix/www/bitrix/php_interface/cron_events.php
Результат
Теперь должно работать. Все агенты периодические и непериодические запускаются на cron. Все почтовые события отправляются на хитах пользователей сразу. Если к отправке письма привязана отправка SMS, то SMS тоже отправится сразу и не будет ждать крона.
Недостатки
Решение вполне рабочее, но есть проблемы:
1. Свой файл /bitrix/php_interface/cron_events.php, как и в старой статье, не будет обновляться.
Битрикс уже добавлял в крон резервное копирование по расписанию. Если они еще что-то добавят, то у вас не появится новый функционал.
2. В Виртуальной машине Битрикса уже настроен крон для файла /bitrix/modules/main/tools/cron_events.php. Вам придется настроить крон на свой файл /bitrix/php_interface/cron_events.php
Решение
Мы написали свой модуль «Агенты на кроне», который очень прост, удобен и лишен этих недостатков.
terseto, установите модуль на тестовый сайт https://labs.1c-bitrix.ru/ а потом скопируйте /bitrix/modules/askaron.agents к себе. Модуль бесплатный. DisableEventsCheck не трогайте, она отключает отправку писем.
Потом установите define("BX_CRONTAB_SUPPORT", true); в dbconn.php
Битрикс рекомендует для ускорения работы сайта переносить выполнение агентов с хитов пользователей на крон.
Агенты — это служебные задачи, которые запускаются в определенное время. Например, пересчет рейтинга пользователей сайта запускается раз в час.
Агенты запускаются, когда какой-нибудь пользователь заходит на сайт. Если при посещении страницы вдруг запустился пересчет рейтингов, то страница может дольше открываться.
Разумно запускать выполнение агентов с помощью служебной программы cron, а не на хитах пользователей.
В Битриксе нет понятного инструмента для переноса агентов на крон.
Есть несколько советов и моя статья, как создать отдельный файл, как настроить крон и установить несколько непонятных констант.
Такие решения рабочие, но требуют настройки, изучения, и свой отдельный крон-файл не будет обновляться.
Мы используем стандартный файл Битрикса /bitrix/modules/main/tools/cron_events.php. Крон уже настроен в Виртуальной машине Битрикса для этого файла, и делать ничего не надо.
На других хостингах вам придется настроить правило, например: * * * * * /usr/bin/php -f /home/bitrix/www/bitrix/modules/main/tools/cron_events.php
Об этом написано в подсказке на странице настроек:
С модулем «Агенты на кроне» будут все возможности, которые появятся в Битриксе при будущих обновлениях.
Мы очень старались сделать модуль простым и понятным. Поэтому он немножко платный. Срок демо-периода 30 дней. Демо-версия полностью функциональная.
Модуль бесплатный.
UPD 25.11.2014 Частые вопросы:
— Нужно ли прописывать константу BX_CRONTAB_SUPPORT в dbconn.php?
— Нет, необязательно. С нашим модулем агенты не зависят от константы BX_CRONTAB_SUPPORT.
Но от этой константы в Битриксе зависит отправка почты.
Если вы напишите define("BX_CRONTAB_SUPPORT", true) ; в dbconn.php, то почтовые события будут срабатывать на кроне раз в минуту.
Если уберете константу, то почта будет отправляться без задержки на хитах пользователей.
— Нужно ли прописывать константу BX_CRONTAB в dbconn.php?
— Нет, ни в коем случае, забудьте про неё. Константа BX_CRONTAB уже прописана в служебном файле, который вызывается кроном. В dbconn.php для всех страниц её включать нельзя.
Дмитрий, важнейшее преимущество модуля, кроме простоты настроек в том, что вместе с агентами на крон не переносятся почтовые сообщения. Очень бесит, когда письма о заказе приходится ждать минуту.
Модуль не будет трогать вашу почту. С модулем вы сами решаете переносить почту на агенты или нет с помощью константы BX_CRONTAB_SUPPORT
Зайцев Артемий, я только за упрощение, просто в данном случае просто не понятно что именно упрощается. Наскоком на одном из проектов я установил модуль, но возникла проблема с пингами в задачах (наверное вы в курсе, пишут об этом в отзывах) и получается прежде чем упрощать все равно приходится разбираться в том какие действия выполняет модуль, и что упрощается). Иными словами - чтобы это упрощение вкусить - нужно понять что мне нужно делать и что не нужно.
Пока что правильно я вас понял - суть упрощения в том что "не нужно настраивать в ядре Б24 опции связанные с запуском агентов - их делает сам модуль", но при этом крон настраивать нужно?
Т.е конкретно из стандартного мануала вычеркиваем пункты
Дмитрий, что касается неправильной работы каких-то отдельных агентов - надо обращаться в разработчику агентов, то есть к Битриксу, если это модуль задач. Битрикс обычно просит удалить наш модуль и настроить стандартным способом. Регламент технической поддержки не позволяет, что-либо проверять, если есть сторонние модули.
Допустим, таблица сделок, или лидов, или любой другой список, основанный на гридах (в CRM таких данных чуть менее, чем полностью). И допустим, что эта таблица должна выглядеть так, как установил админ, или другой супер-юзер. Решение под катом.
Дрёмин Станислав написал: В result_modifier брал настройки супер-юзера через CUserOptions::GetOption и записывал их через CUserOptions::SetOption для конкретного юзера.
Вот тут небольшой минус - перетираются собственные настройки пользователя. В случае, например, модуля из Маркета это делать нельзя - модуль удалили > настройки должны остаться.
Дрёмин Станислав, так прост вытащи через GetOption массив, потом через array_merge() добавь то что нужно и запиши, тогда не слетит ничего. А если ты просто передаешь массив с параметрами то он естественно затрет уже установленные пользователем параметры
require_once ($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/classes/general/csv_data.php";);
$csvFile = new CCSVData('R', true);
$csvFile->LoadFile($_FILES['csv']['tmp_name']);
$csvFile->SetDelimiter(',');
while ($arRes = $csvFile->Fetch()) {
ec($arRes);
}
Собственно: - подключаем файл класса работы с CSV - создаем объект класса, указываем, что будет использоваться разделитель (R, есть еще фикс.поля F), и первая строка содержит заголовки (true); можно не указывать эти параметры и задать отдельными методами
- загружаем файл - ставим делиметер, где допустимые параметры: \t (табуляция), запятая, пробел, точка с запятой. - бежим как при обычной выборке из базы (напомню, Fetch возвращает НЕ обработанные данные, а GetNext безопасные).
Эту фичу наверное нужно использовать для того что бы избежать всяческих проблем с кодировкой и прочими настройками которые Битрикс учитывает. Антон там в строке подключения библиортеки лишнее
Практически каждый модуль имеет настройки. И иногда встает задача, что какую-то настройку для частного конкретного случая надо переопределить (для конкретной группы пользователей, или раздела сайта, или ID сайта). Но меняя в модуле, настройка меняется для всех случаев. Вот как это можно переопределить в частном случае.
Долганин Антон, сработал такой код, но он меняет значение настройки глобально для всех пользователей (он был вставлен прямо в init.php и скорее всего срабатывал на начальной стадии загрузки страницы, нужно понять при каком событии и как вызвать этот код):
use \Bitrix\Main\Config\Option;
class A extends Option
{
public static function changeOptions($module, $config, $value)
{
parent::$options[$module]['-'][$config] = $value;
}
}
A::changeOptions('main', 'new_user_registration_email_confirmation', 'N');
Долганин Антон написал: Вот для нового ядра (наследуемся и переопределяем protected)
Возможно для кого-то тема будет все еще актуальна. Код из последнего сообщения Антона в настоящее время не заработает. Вероятно, в одном из обновлений главного модуля было решено сменить порядок хранения настроек и теперь модуль является корневым ключом массива, а настройки с привязкой к сайтам (или без таковой), '-', 's1' и т.д. - являются вложенными в каждый модуль.
Поэтому предлагаю такую реализацию класса для решения данной задачи:
<?php
class ExtendedOption extends \Bitrix\Main\Config\Option
{
/**
* Локально изменить настройку определенного модуля для текущего хита.
* См. подробнее здесь: https://dev.1c-bitrix.ru/community/webdev/user/11948/blog/7799/
*
* @param $module
* @param $parameter
* @param $value
*/
public static function changeOptionForCurrentHit($module, $parameter, $value)
{
if (!isset(parent::$options[$module]['-'][$parameter])) {
static::get($module, $parameter);
}
parent::$options[$module]['-'][$parameter] = $value;
}
}
ExtendedOption::changeOptionForCurrentHit('main', 'captcha_registration', 'N');
Что если в вызов компонента system.auth.form добавить "AJAX_MODE" => "Y", а в шаблоне у <form убрать атрибут target ? Вроде работает ajax без дописок всяких.
В одном из моих личных проектов потребовалось сделать приложение 2 типа для bitrix24 и работать с его API. Я человек ленивый, поэтому решил написать «простенькую» обёртку поверх REST- вызовов.
// инициализируем бибилиотеку для работы с B24
$obB24App = new \Bitrix24\Bitrix24();
$obB24App->setApplicationScope($arParams['B24_APPLICATION_SCOPE']);
$obB24App->setApplicationId($arParams['B24_APPLICATION_ID']);
$obB24App->setApplicationSecret($arParams['B24_APPLICATION_SECRET']);
// выставляем настройки, зависящие от пользователя
$obB24App->setDomain($arParams['DOMAIN']);
$obB24App->setMemberId($arParams['MEMBER_ID']);
$obB24App->setAccessToken($arParams['AUTH_ID']);
$obB24App->setRefreshToken($arParams['REFRESH_ID']);
// получили информацию по текущему пользователю из Bitrix24
$obB24User = new \Bitrix24\User\User($obB24App);
$arCurrentB24User = $obB24User->current();
Пример получения списка задач
/**
* объект для работы с задачами
**/
$obTasks = new \Bitrix24\Task\TaskItems($obB24App);
/**
* список задач из B24
* @var $arB24Tasks array */
$arB24Tasks = $obTasks->getList(
array("ID" => 'desc'),
array('RESPONSIBLE_ID' => $arUser['B24_USER_ID']),
array('ID','TITLE','CREATED_DATE','DEADLINE','STATUS','REAL_STATUS','STATUS_CHANGED_DATE','GROUP_ID','CHANGED_DATE'),
null);
Я её периодически обновляю, но уже сейчас она вполне пригодна для работы. Критика и пулл-реквесты приветствуются.
Булгаков Никита
Проблема в том, что битрикс сменил UI авторизации и моя библиотека перестала работать. До момента, пока не переписал её под новый UI... У Вас если происходят ошибки - смотрите адрес скрипта где эта ошибка произошла и задавайте вопрос в ISSUES на гитхабе разработчику библиотекы
Группы на сайте создаются не только сотрудниками «1С-Битрикс», но и партнерами компании. Поэтому мнения участников групп могут не совпадать с позицией компании «1С-Битрикс».