select * fr om b_option wh ere MODULE_ID='security' AND NAME='ipcheck_disable_file'; |
http {
...
log_format time_combined '$request_time $upstream_response_time $pipe [$time_local] "$request" $status'
' $body_bytes_sent "$http_user_agent" $remote_addr - $remote_user';
...
} |
add_header X-Time '$request_time'; |
mixed CSubscription::Update( int ID, array arFields, string SITE_ID = SITE_ID ); int CSubscription::Add( array arFields, string SITE_ID = SITE_ID ); |
$subscr->Add($arFields,'s1') |
Удобство использования бизнес-процессов битрикс бесспорно, но часто мы сталкиваемся с проблемами внедрения или дальнейших доработок уже существующего бизнес-процесса.
Одна из таких проблем отправка почтовых сообщений. В режиме тестирования бизнес-процесса приходится постоянно менять получателей почтового сообщения для отладки, потом еще раз менять для релиза, а если БП состоит из множества этапов, это приводит к ошибкам и потери времени.
Конечно, некоторые пытаются упростить процесс тестирования, заводя отдельные переменные, режимы и другие варианты кастомизации бизнес-процесса, но не сильно сокращаются затраты.
Теперь вам не надо мучиться с тестированием т.к. мы сделали бесплатный активити "".
Activity позволяет упростить вашу работу, сократить ошибки, уменьшить трудозатраты и быть удобным. Оно не нарушает привычные принципы работы, вы так же заполяете все стандартные поля: Отправитель сообщения, Получатель сообщения, Тема сообщения, Текст сообщения и т.д.
Но в любой момент можно, открыть активити, нажать чек бокс "Режим отладки Бизнес-процесса", добавить ваш email для отладки и все сообщения будут уходить вам (всего 2 клика).
Выключается режим обратным нажатием на чек бокс и все работает в обычном режиме
А как же посмотреть режим, не заходя в активити? Да-да и это тоже мы продумали! Режим отладки подкрашивает название активити в бордовый цвет, при просмотре шаблона бизнес-процесса.
Невероятно удобно просто.
Еще небольшой тизер нашего незаменимого активити, скоро увидим 
Смотреть сюда
| Да, будут уходить на старый адрес, пока пользователь не отпишется от рассылки. |
В ORM на текущий момент нет массового добавления элементов. Скорее всего такой функционал не появится, поскольку должна работать система событий.
Если
1. Не используются UF_ поля
2. Данные добавляются только в одну таблицу
3. Не нужны события
4. У всех записей одинаковый набор полей
То можно сформировать запрос в полуавтоматическом режиме (аналогичный функционал присутствует старом ядре).
Пусть у нас есть описание сущности: PromoCabinet\Positions\DetailTable
Получаем имя таблицы в базе, соединение, а также объект $sqlHelper
use Bitrix\Main\Type; use Bitrix\Main\Application; use PromoCabinet\Positions\DetailTable; $tableName = DetailTable::getTableName(); $connection = Application::getConnection(DetailTable::getConnectionName()); $sqlHelper = $connection->getSqlHelper(); |
Далее формируем массив полей для добавления для каждого элемента
$item = [ "CLIENT_ID" => $clientId, "DATE" => new Type\Date, "PHRASE" => $phrase, "POSITION_YANDEX" => $positionYandex, "POSITION_GOOGLE" => $positionGoogle, "IS_NEW" => ($wordDateTs > $dateTs), ]; |
Вызываем метод prepareInsert объекта $sqlHelper. Методу передается имя таблицы и массив полей нового элемента (такой же, как и для метода DetailTable::add)
$insert = $sqlHelper->prepareInsert($tableName, $item); |
В итоге получаем список полей и их значений для вставки в базу.
$sql = "INS ERT IN TO ".$sqlHelper->quote($tableName)."(".$insert[0].") "."VALUES (".$insert[1].")";
Используя $insert[0] и несколько $insert[1] можно сформировать единый sql-запрос.и далее выполнить его: $connection->queryExecute($addSql);
По умолчанию для всех файлов инфоблоков используется общая папка /upload/iblock/. Файлы сохраняются в подпапки, сгенерированные случайным образом, например, /upload/iblock/ff7/.
Как следствие, все файлы доступны по прямой ссылке. В целом, в этом нет ничего страшного, так как итоговый путь (при условии, что файл отдается через php) сложно подобрать. Но в некоторых случаях требуются дополнительные меры безопасности.
Основная идея – как-то вынести файлы инфоблока в отдельную подпапку и закрыть её с помощью стандартных механизмов nginx / apache.
Небольшим дополнительным плюсом будет то, что можно достаточно просто посмотреть, сколько места занимают файлы отдельного инфоблока.
Суть в следующем: в методе CFile::SaveFile второй параметр ($strSavePath) отвечает за директорию внутри папки upload. Инфоблоки его передают как «iblock», нам надо его заменить.
Подробнее:
DEBUG
INFO
NOTICE
WARNING
ERROR
CRITICAL
ALERT
EMERGENCY
- в этом списке они расположены по возрастанию важности.$loggerMonolog = new Logger('logger');$loggerToSlack = new Logger('loggerToSlack');$loggerFormatted = new Logger('loggerFormatted'); |
StreamHandler - логирование в файл
$loggerMonolog = new Logger('logger');$loggerMonolog->pushHandler(new StreamHandler($_SERVER["DOCUMENT_ROOT"] . '/loggerToFile.log', Logger::INFO));$loggerMonolog->addWarning('test logs');$loggerMonolog->warning('warning text example');$loggerMonolog->error('error text example');$loggerMonolog->error('error text', array('session' => $_SESSION));$loggerMonolog->info('info text example');$loggerMonolog->addInfo('new message', array('session' => $_SESSION)); |
$handlerInfoStream = new RotatingFileHandler($_SERVER["DOCUMENT_ROOT"] . '/logs/info.log', 0, Logger::INFO);
$handlerWarningStream = new RotatingFileHandler($_SERVER["DOCUMENT_ROOT"] . '/logs/warning.log', 0, Logger::WARNING);
$handlerErrorStream = new RotatingFileHandler($_SERVER["DOCUMENT_ROOT"] . '/logs/error.log', 0, Logger::ERROR);
$handlerInfoStream->setFilenameFormat('{date}-{filename}', 'Y/m/d');
$handlerWarningStream->setFilenameFormat('{date}-{filename}', 'Y/m/d');
$handlerErrorStream->setFilenameFormat('{date}-{filename}', 'Y/m/d');
$loggerMonolog->pushHandler($handlerInfoStream);
$loggerMonolog->pushHandler($handlerWarningStream);
$loggerMonolog->pushHandler($handlerErrorStream);
|
NativeMailerHandler
$handlerMail = new NativeMailerHandler('root@localhost.com', "monolog", COption::GetOptionString('main', 'email_from'), Logger::INFO);
$handlerMail->setFormatter(new HtmlFormatter());
$handlerMail->setContentType('text/html');
$loggerMonolog->pushHandler($handlerMail);
|
SlackWebhookHandler
$handlerSlack = new SlackWebhookHandler("https://hooks.slack.com/services/T04NB7T81/BAC35BJT1/95pr8ZlfbvhXH1o******, null, null, true, "sunglasses", false, false, Logger::INFO);
$loggerToSlack->warning('warning text example to slack <!everyone>');$loggerToSlack->info(json_encode(array('session' => $_SESSION)));
|
Первый параметр - это webhookUrl
для работы с Rollbаr ставим пакет "rollbar/rollbar": "^1"
RollbarHandler используем именно из этого пакета, т.к RollbarHandler из пакета monolog на данный момент устаревший. подробнее: глава “Using Monolog”
//use Monolog\Handler\RollbarHandler; use Rollbar\Rollbar; use Rollbar\Payload\Level; use Rollbar\Monolog\Handler\RollbarHandler; Rollbar::init( |
array( 'access_token' => '5a7e9c4897f341e3abc1********', 'environment' => 'development' ));$loggerMonolog->pushHandler(new RollbarHandler(Rollbar::logger(), Logger::INFO)); |
BrowserConsoleHandler
$loggerMonolog->pushHandler(new BrowserConsoleHandler()); |
LineFormatter - запись лога представляет из себя строку
HtmlFormatter - записи форматируются в удобную для чтения html таблицу, обычно используется при отправке лога на e-mail
JsonFormatter - запись преобразуется в json-строку
Процессоры:IntrospectionProcessor - добавляет информацию о текущей строке/файле/классе/методе, в которых производится запись в лог
WebProcessor - добавляет в лог текущие url, метод запроса и ip клиента
MemoryUsageProcessor - добавляет в лог сведения о текущем использовании памяти
Один из возможных вариантов применения monolog:
$user = new CUser;
$userID = $user->Add($arFields);
if (!$userID){
$loggerMonolog = new Logger('loggerErrorUserRegistration');
$loggerMonolog->pushHandler(new StreamHandler($_SERVER["DOCUMENT_ROOT"] . '/loggerErrorUserRegistration.log', Logger::ALERT));
$handlerMail = new NativeMailerHandler('root@localhost.com', "monolog", COption::GetOptionString('main', 'email_from'), Logger::ALERT);
$handlerMail->setFormatter(new HtmlFormatter());
$handlerMail->setContentType('text/html');
$loggerMonolog->pushHandler($handlerMail);
$handlerSlack = new SlackWebhookHandler("https://hooks.slack.com/services/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”, null, null, true, false, false, false,
Logger::ALERT);
$loggerToSlack = new Logger('loggerToSlack');
$loggerToSlack->pushHandler($handlerSlack);
loggerToSlack->setProcessor(new IntrospectionProcessor(Logger::ALERT));
$loggerMonolog->alert('error registration user');
$loggerToSlack->alert('error registration user <!everyone>');
}
|
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use Monolog\Handler\BrowserConsoleHandler;
use Monolog\Formatter\LineFormatter;
use Monolog\Formatter\HtmlFormatter;
use Monolog\Formatter\ScalarFormatter;
use Monolog\Formatter\JsonFormatter;
use Monolog\Handler\RotatingFileHandler;
use Monolog\Handler\NativeMailerHandler;
use Monolog\Handler\SlackWebhookHandler;
use Monolog\Handler\LogglyHandler;
//use Monolog\Handler\RollbarHandler;
use Rollbar\Rollbar;
use Rollbar\Payload\Level;
use Rollbar\Monolog\Handler\RollbarHandler;
$loggerBitrix = \Monolog\Registry::getInstance('debug');
$loggerBitrix->info('Debug session', array( 'item_id' => 0, 'Data' => $_SESSION));
$loggerApp = \Monolog\Registry::getInstance('app');
$loggerApp->info('info text example');
$loggerMonolog = new Logger('logger');
$loggerMonolog->pushHandler(new StreamHandler($_SERVER["DOCUMENT_ROOT"] . '/loggerToFile.log', Logger::INFO));
$loggerMonolog->pushHandler(new BrowserConsoleHandler());
$handlerInfoStream = new RotatingFileHandler($_SERVER["DOCUMENT_ROOT"] . '/logs/info.log', 0, Logger::INFO);
$handlerWarningStream = new RotatingFileHandler($_SERVER["DOCUMENT_ROOT"] . '/logs/warning.log', 0, Logger::WARNING);
$handlerErrorStream = new RotatingFileHandler($_SERVER["DOCUMENT_ROOT"] . '/logs/error.log', 0, Logger::ERROR);
$handlerInfoStream->setFilenameFormat('{date}-{filename}', 'Y/m/d');
$handlerWarningStream->setFilenameFormat('{date}-{filename}', 'Y/m/d');
$handlerErrorStream->setFilenameFormat('{date}-{filename}', 'Y/m/d');
$loggerMonolog->pushHandler($handlerInfoStream);
$loggerMonolog->pushHandler($handlerWarningStream);
$loggerMonolog->pushHandler($handlerErrorStream);
$handlerMail = new NativeMailerHandler('root@localhost.com', "monolog", COption::GetOptionString('main', 'email_from'), Logger::INFO);
$handlerMail->setFormatter(new HtmlFormatter());
$handlerMail->setContentType('text/html');
$loggerMonolog->pushHandler($handlerMail);
$handlerSlack = new SlackWebhookHandler("https://hooks.slack.com/services/T04NB7T81/BAC35BJT1/95pr8ZlfbvhX********", null, null, true, "sunglasses", false,
false, Logger::INFO);
$loggerToSlack = new Logger('loggerToSlack');
$loggerMonolog->pushHandler($handlerSlack);
$loggerToSlack->pushHandler($handlerSlack);
$loggerMonolog->pushHandler(new LogglyHandler('70997a00-a48f-4e33-9059-812d67a5f383/tag/monolog', Logger::INFO));
Rollbar::init( array( 'access_token' => '5a7e9c4897f341e3abc1*******', 'environment' => 'development' ));
$loggerMonolog->pushHandler(new RollbarHandler(Rollbar::logger(), Logger::INFO));
$loggerMonolog->addWarning('test logs');
$loggerMonolog->warning('warning text example');
$loggerMonolog->error('error text example');
$loggerMonolog->error('error text', array('session' => $_SESSION));
$loggerMonolog->info('info text example');
$loggerMonolog->info('info text', array('session' => $_SESSION));
$loggerMonolog->debug('debug text', array('session' => $_SESSION));
$loggerMonolog->info(json_encode(array('session' => $_SESSION)));
$loggerMonolog->addInfo('new message', array('session' => $_SESSION));
$loggerToSlack->warning('warning text example to slack <!everyone>'); |
$loggerToSlack->info(json_encode(array('session' => $_SESSION)));
$dateFormat = "Y n j, g:i a";
$output = "%datetime% > %level_name% > %message% %context% %extra%\n";
$formatter = new LineFormatter($output, $dateFormat);
$streamFormatted = new StreamHandler($_SERVER["DOCUMENT_ROOT"] . '/formattedLog.log', Logger::DEBUG);
$streamFormatted->setFormatter($formatter);
$loggerFormatted = new Logger('loggerFormatted');
$loggerFormatted->pushHandler($streamFormatted);
$loggerFormatted->warning('warning text example');
$loggerFormatted->error('error text example');
$loggerFormatted->error('error text', array('session' => $_SESSION));
$loggerFormatted->info('info text example');
$loggerFormatted->info('info text', array('session' => $_SESSION)); |
require_once($_SERVER['DOCUMENT_ROOT'] . '/vendor/autoload.php'); \Bex\Monolog\MonologAdapter::loadConfiguration(); |
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use Monolog\Handler\BrowserConsoleHandler;
use Monolog\Formatter\LineFormatter;
use Monolog\Formatter\HtmlFormatter;
use Monolog\Formatter\ScalarFormatter;
use Monolog\Formatter\JsonFormatter;
use Monolog\Handler\RotatingFileHandler;
use Monolog\Handler\NativeMailerHandler;
use Monolog\Handler\SlackWebhookHandler;
use Monolog\Handler\LogglyHandler;
//use Monolog\Handler\RollbarHandler;
use Rollbar\Rollbar;
use Rollbar\Payload\Level;
use Rollbar\Monolog\Handler\RollbarHandler;
$loggerBitrix = \Monolog\Registry::getInstance('debug');
$loggerBitrix->info('Debug session', array(
'item_id' => 0,
'Data' => $_SESSION
));
$loggerToFile = \Monolog\Registry::getInstance('loggerToFile');
$loggerToBrowserConsole = \Monolog\Registry::getInstance('loggerToBrowserConsole');
$loggerToRotatingFile = \Monolog\Registry::getInstance('loggerToRotatingFile');
$loggerToNativeMailer = \Monolog\Registry::getInstance('loggerToNativeMailer');
$loggerToSlackWebhook = \Monolog\Registry::getInstance('loggerToSlackWebhook');
$loggerToRollbar = new Logger('loggerToRollbar');
$configRollbar = \Bitrix\Main\Config\Configuration::getInstance()->get('rollbar');
Rollbar::init(
array(
'access_token' => $configRollbar["access_token"],
'environment' => $configRollbar['development']
)
);
$loggerToRollbar->pushHandler(new RollbarHandler(Rollbar::logger(), Logger::INFO));
$loggerToFileFormatted = \Monolog\Registry::getInstance('loggerToFileFormatted');
$loggerToAll = \Monolog\Registry::getInstance('loggerToAll');
$loggerToAll->addWarning('test logs settings all');
$loggerToAll->warning('warning text example settings all');
$loggerToAll->error('error text example settings all');
$loggerToAll->error('error text settings all', array('session' => $_SESSION));
$loggerToAll->info('info text example settings all');
$loggerToAll->info('info text settings all', array('session' => $_SESSION));
$loggerToAll->debug('debug text settings all', array('session' => $_SESSION));
$loggerToAll->info(json_encode(array('session settings all' => $_SESSION)));
$loggerToAll->addInfo('new message settings all', array('session' => $_SESSION));
/*
monolog-adapter для работы с конфигами использует cascade, а у cascade, как я понял, отсутствует поддержка подобных методов: |
$handlerMail->setContentType('text/html');
$handlerInfoStream->setFilenameFormat('{date}-{filename}', 'Y/m/d');
*/ |
'monolog' => array(
'value' => array(
'formatters' => array(
'NativeMailerFormatter' => array(
'class' => '\Monolog\Formatter\HtmlFormatter',
),
'StreamHandlerFormatter' => array(
'class' => '\Monolog\Formatter\LineFormatter',
"format" => "%datetime% > %level_name% > %message% %context% %extra%\n",
"dateFormat" => "Y n j, g:i a"
)
),
'handlers' => array(
'default' => array(
'class' => '\Monolog\Handler\StreamHandler',
'level' => 'INFO',
'stream' => '/app.log'
),
'debug_log' => array(
'class' => '\Bex\Monolog\Handler\BitrixHandler',
'level' => 'DEBUG',
'event' => 'DEBUG',
'module' => ''
),
'BitrixIblockHandler' => array(
'class' => '\Bex\Monolog\Handler\BitrixIblockHandler',
'level' => 'DEBUG',
'iblock_id' => 10,
'rotating_count_elements' => 5,
'rotating_count_days' => 2,
'notify_to_admin' => true
),
'StreamHandler' => array(
'class' => '\Monolog\Handler\StreamHandler',
'level' => 'INFO',
'stream' => './loggerToFile.log'
),
'StreamHandlerFormatted' => array(
'class' => '\Monolog\Handler\StreamHandler',
'level' => 'DEBUG',
'stream' => './loggerToFileFormatted.log',
'formatter' => "StreamHandlerFormatter"
),
'BrowserConsoleHandler' => array(
'class' => '\Monolog\Handler\BrowserConsoleHandler',
),
'RotatingFileHandler' => array(
'class' => '\Monolog\Handler\RotatingFileHandler',
'level' => 'INFO',
'maxFiles' => 5,
'filename' => './logs/info.log',
),
'NativeMailerHandler' => array(
'class' => '\Monolog\Handler\NativeMailerHandler',
'to' => 'root@localhost.com',
'subject' => 'monolog info',
'level' => 'INFO',
'from' => "null@" . $_SERVER['SERVER_NAME'],
'formatter' => "NativeMailerFormatter"
),
'SlackWebhookHandler' => array(
'class' => '\Monolog\Handler\SlackWebhookHandler',
'level' => 'INFO',
'webhookUrl' => "https://hooks.slack.com/services/T04NB7T81/BAC35BJT1/95pr8ZlfbvhXH1*******"
)
),
'loggers' => array(
'app' => array(
'handlers' => array('default'),
),
'debug' => array(
'handlers' => array('debug_log'),
),
'loggerToFile' => array(
'handlers' => array('StreamHandler'),
),
'loggerToFileFormatted' => array(
'handlers' => array('StreamHandlerFormatted'),
),
'loggerToBrowserConsole' => array(
'handlers' => array('BrowserConsoleHandler'),
),
'loggerToRotatingFile' => array(
'handlers' => array('RotatingFileHandler'),
),
'loggerToNativeMailer' => array(
'handlers' => array('NativeMailerHandler'),
),
'loggerToSlackWebhook' => array(
'handlers' => array('SlackWebhookHandler'),
),
'loggerToAll' => array(
'handlers' => array('debug_log', 'StreamHandler', 'StreamHandlerFormatted', 'BrowserConsoleHandler',
'RotatingFileHandler', 'NativeMailerHandler', 'SlackWebhookHandler', 'BitrixIblockHandler'),
),
)
),
'readonly' => false
),
'rollbar' => array(
'value' => array(
'access_token' => '5a7e9c4897f341e3abc1be*******',
'environment' => 'development'
)
), |



'monolog' => array(
'value' => array(
'formatters' => array(
'StreamHandlerFormatter' => array(
'class' => '\Monolog\Formatter\LineFormatter',
"format" => "%datetime% > %level_name% > %message% %context% %extra%\n",
"dateFormat" => "Y n j, g:i a"
)
),
'handlers' => array(
...........
'BitrixIblockHandler' => array(
'class' => '\Bex\Monolog\Handler\BitrixIblockHandler',
'level' => 'DEBUG',
'iblock_id' => 10, //id инфоблока, в который будут складываться записи
'rotating_count_elements' => 5, //удалить все записи из инфоблока, кроме первых 'rotating_count_elements'
'rotating_count_days' => 2, // удалить элементы из инфоблока, которые старше 'rotating_count_days' дней
'notify_to_admin' => true //показ уведомлений администратору
),
),
'loggers' => array(
'app' => array(
'handlers' => array('default'),
),
'debug' => array(
'handlers' => array('debug_log'),
),
'loggerToFile' => array(
'handlers' => array('StreamHandler'),
),
'loggerToFileFormatted' => array(
'handlers' => array('StreamHandlerFormatted'),
),
'loggerToBrowserConsole' => array(
'handlers' => array('BrowserConsoleHandler'),
),
'loggerToRotatingFile' => array(
'handlers' => array('RotatingFileHandler'),
),
'loggerToNativeMailer' => array(
'handlers' => array('NativeMailerHandler'),
),
'loggerToSlackWebhook' => array(
'handlers' => array('SlackWebhookHandler'),
),
'loggerToAll' => array(
'handlers' => array('debug_log', 'StreamHandler', 'StreamHandlerFormatted', 'BrowserConsoleHandler',
'RotatingFileHandler', 'NativeMailerHandler', 'SlackWebhookHandler', 'BitrixIblockHandler'),
), )
),
'readonly' => false
),` |
use Monolog\Logger;
$loggerToAll = \Monolog\Registry::getInstance('loggerToAll');$loggerToAll->addWarning('test logs settings all');
$loggerToAll->warning('warning text example settings all');
$loggerToAll->error('error text example settings all');
$loggerToAll->error('error text settings all', array('session' => $_SESSION));
$loggerToAll->info('info text example settings all');
$loggerToAll->info('info text settings all', array('session' => $_SESSION));
$loggerToAll->debug('debug text settings all', array('session' => $_SESSION));
$loggerToAll->info(json_encode(array('session settings all' => $_SESSION)));
$loggerToAll->addInfo('new message settings all', array('session' => $_SESSION));
|


$rsItems = \Bitrix\Iblock\ElementTable::getList(Array(
'filter' => Array(
'IBLOCK_ID' => $IBLOCK_ID,
'FESTIVAL.IBLOCK_PROPERTY_ID' => $IBLOCK_PROPERTY_ID
),
"count_total" => true,
'select' => Array(
'*',
'FESTIVAL_ORDER'
),
'order' => Array(
'FESTIVAL_ORDER' => 'DESC',
'ID' => 'ASC'
),
'limit' => $nav->getLimit(),
'offset' => $nav->getOffset(),
'runtime' => Array(
new Entity\ReferenceField(
'FESTIVAL',
'IblockElementPropertyTable',
Array(
'=this.ID' => 'ref.IBLOCK_ELEMENT_ID',
)
),
new Entity\ExpressionField('FESTIVAL_ORDER', '%s = '.$PROPERTY_VALUE, array('FESTIVAL.VALUE'))
)
)); |
new Entity\ExpressionField('FESTIVAL_ORDER', '%s = '.$PROPERTY_VALUE, array('FESTIVAL.VALUE')) |

new Entity\ReferenceField( 'FESTIVAL', 'IblockElementPropertyTable', Array( '=this.ID' => 'ref.IBLOCK_ELEMENT_ID', ) ), |
<?php
if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED !== true) {
die();
}
$this->__file = '/bitrix/components/bitrix/crm.company.list/templates/.default/template.php';
$this->__folder = '/bitrix/components/bitrix/crm.company.list/templates/.default';
// Добавить новый столбец 'Последний комментарий'
$arResult['HEADERS'][] = [
'id' => 'CUSTOM_VIRTUAL_COMMENT',
'name' => 'Последний комментарий',
'sort' => false,
'editable' => false,
];
// Заполнить значениями новый столбец 'Последний комментарий'
foreach ($arResult['COMPANY'] as $id => &$company) {
$result = \Bitrix\Crm\Timeline\Entity\TimelineTable::query()
->addSelect('COMMENT')
->registerRuntimeField('binding', [
'data_type' => '\Bitrix\Crm\Timeline\Entity\TimelineBindingTable',
'reference' => [
'=this.ID' => 'ref.OWNER_ID',
],
'join_type' => 'inner',
])
->where('binding.ENTITY_ID', $id)
->where('binding.ENTITY_TYPE_ID', \CCrmOwnerType::Company)
->whereNotNull('COMMENT')
->setOrder(['CREATED' => 'DESC'])
->setLimit(1)
->exec()
->fetch()
;
$company['CUSTOM_VIRTUAL_COMMENT'] = $result['COMMENT'];
}
|
<?php
if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED !== true) {
die();
}
|