private static function flushNotificationBuffer($doGrouping = true) { if (!empty(self::$buffer)) { $sites = self::getSitePair(); $byUser = array(); foreach (self::$buffer as $i => $message) { if (is_array($message['TO_USER_IDS'])) { foreach ($message['TO_USER_IDS'] as $userId) { // determine notify event here, if it was not given if ((string) $message['NOTIFY_EVENT'] == '') { $notifyEvent = 'manage'; if ($message['ADDITIONAL_DATA']['TASK_ASSIGNED_TO'] !== null) { if ($userId == $message['ADDITIONAL_DATA']['TASK_ASSIGNED_TO']) { $notifyEvent = 'task_assigned'; } } } else { $notifyEvent = $message['NOTIFY_EVENT']; } $byUser[$userId][$message['TASK_ID']] = array_merge($message, array('NOTIFY_EVENT' => $notifyEvent)); } } } $users = self::getUsers(array_keys($byUser)); foreach ($byUser as $userId => $messages) { if (!isset($users[$userId])) { continue; } $unGroupped = array(); if (count($messages) > 1 && $doGrouping) { // send for each action type, notification type and author separately $deepGrouping = array(); foreach ($messages as $taskId => $message) { // we do not group entities that differ from 'TASK' and NOTIFY_EVENTS that differ from 'manage' if ($message['ENTITY_CODE'] != 'TASK' || $message['NOTIFY_EVENT'] != 'manage') { $unGroupped[$taskId] = $message; continue; } // if type is unknown, let it be "update" $type = (string) $message['EVENT_DATA']['ACTION'] !== '' ? $message['EVENT_DATA']['ACTION'] : 'TASK_UPDATE'; if ($type != 'TASK_ADD' && $type != 'TASK_UPDATE' && $type != 'TASK_DELETE' && $type != 'TASK_STATUS_CHANGED_MESSAGE') { // unknown action type. nothing to report about continue; } $fromUserId = $message['FROM_USER_ID']; if ((string) $fromUserId == '') { continue; } $deepGrouping[$type][$fromUserId][$message['NOTIFY_EVENT']][] = $taskId; } if (!empty($deepGrouping)) { foreach ($deepGrouping as $type => $byAuthor) { foreach ($byAuthor as $authorId => $byEvent) { foreach ($byEvent as $event => $taskIds) { $path = CTaskNotifications::getNotificationPathMultiple($users[$userId], $taskIds, true); $instantTemplate = self::getGenderMessage($authorId, 'TASKS_TASKS_' . $type . '_MESSAGE'); $emailTemplate = self::getGenderMessage($authorId, 'TASKS_TASKS_' . $type . '_MESSAGE_EMAIL'); $pushTemplate = self::getGenderMessage($authorId, 'TASKS_TASKS_' . $type . '_MESSAGE_PUSH'); $instant = self::placeLinkAnchor($instantTemplate, $path, 'BBCODE'); $email = self::placeLinkAnchor($emailTemplate, $path, 'EMAIL'); $push = self::placeLinkAnchor('#USER_NAME# ' . $pushTemplate, $path, 'NONE'); $tag = static::formatImNotificationTag($userId, $taskIds, 'TASKS'); $arMessageFields = array("TO_USER_ID" => $userId, "FROM_USER_ID" => $authorId, "NOTIFY_TYPE" => IM_NOTIFY_FROM, "NOTIFY_MODULE" => 'tasks', "NOTIFY_EVENT" => $event, "NOTIFY_MESSAGE" => $instant, "NOTIFY_MESSAGE_OUT" => $email, "NOTIFY_TAG" => $tag, "PUSH_MESSAGE" => substr($push, 0, self::PUSH_MESSAGE_MAX_LENGTH)); CIMNotify::Add($arMessageFields); } } } } } else { $unGroupped = $messages; } // send each message separately foreach ($unGroupped as $taskId => $message) { $pathToTask = self::GetNotificationPath($users[$userId], $taskId, true, $sites); $pathToTask = self::addParameters($pathToTask, $message['ADDITIONAL_DATA']['TASK_URL']); $message['ENTITY_CODE'] = ToUpper($message['ENTITY_CODE']); $message['MESSAGE']['INSTANT'] = self::placeLinkAnchor($message['MESSAGE']['INSTANT'], $pathToTask, 'BBCODE'); $message['MESSAGE']['EMAIL'] = self::placeLinkAnchor($message['MESSAGE']['EMAIL'], $pathToTask, 'EMAIL'); if ((string) $message['MESSAGE']['PUSH'] != '') { $message['MESSAGE']['PUSH'] = self::placeLinkAnchor($message['MESSAGE']['PUSH'], $pathToTask, 'NONE'); } $message['TO_USER_IDS'] = array($userId); // message callbacks here if (is_callable($message['CALLBACK']['BEFORE_SEND'])) { $message = call_user_func_array($message['CALLBACK']['BEFORE_SEND'], array($message)); } // event process here if (!static::fireMessageEvent($message)) { continue; } $userId = $message['TO_USER_IDS'][0]; // it may have changed on event // make IM parameters // todo make tag format more sutable $entityIds = array(); if ('COMMENT' == $message['ENTITY_CODE']) { $entityIds = array(intval($message['EVENT_DATA']['MESSAGE_ID'])); } $tag = static::formatImNotificationTag($userId, array($taskId), $message['ENTITY_CODE'], $entityIds); $arMessageFields = array("TO_USER_ID" => $userId, "FROM_USER_ID" => $message['FROM_USER_ID'], "NOTIFY_TYPE" => IM_NOTIFY_FROM, "NOTIFY_MODULE" => "tasks", "NOTIFY_EVENT" => $message['NOTIFY_EVENT'], "NOTIFY_TAG" => $tag, "NOTIFY_MESSAGE" => $message['MESSAGE']['INSTANT'], "NOTIFY_MESSAGE_OUT" => $message['MESSAGE']['EMAIL']); if ((string) $message['ADDITIONAL_DATA']['NOTIFY_ANSWER']) { // enabling notify answer for desktop $arMessageFields['NOTIFY_ANSWER'] = 'Y'; } if ((string) $message['MESSAGE']['PUSH'] != '') { // add push message $arMessageFields['PUSH_MESSAGE'] = self::placeLinkAnchor($message['MESSAGE']['PUSH'], $pathToTask, 'NONE'); // user should be able to open the task window to see the changes ... // see /mobile/install/components/bitrix/mobile.rtc/templates/.default/script.js for handling details $arMessageFields['PUSH_PARAMS'] = array('ACTION' => 'tasks', 'TAG' => $tag); if ((string) $message['ADDITIONAL_DATA']['NOTIFY_ANSWER']) { // ... and open an answer dialog in mobile $arMessageFields['PUSH_PARAMS'] = array_merge($arMessageFields['PUSH_PARAMS'], array('CATEGORY' => 'ANSWER', 'URL' => SITE_DIR . 'mobile/ajax.php?mobile_action=task_answer', 'PARAMS' => array('TASK_ID' => $taskId))); } } CIMNotify::Add($arMessageFields); } } } self::$buffer = array(); }