/** * get action records and group them for notifications display * @param varchar $sql * @param array $params sql params * @return array */ private function getRecords($p) { $rez = array(); $recs = DM\Notifications::getLast($p['user_id'], $p['limit'], empty($p['fromId']) ? false : $p['fromId']); $actions = array(); //grouping actions by object_id, action type and read property foreach ($recs as $r) { $r['data'] = Util\toJsonArray($r['data']); $group = $r['object_id'] . '_' . $r['action_type'] . '_' . $r['read']; $actions[$group][$r['from_user_id']] = $r; } //iterate actions and group into records up to read property foreach ($actions as $group => $users) { //form id $ids = array(); //would be comma separated action_ids foreach ($users as $r) { $ids[] = $r['id']; } $r = current($users); $record = array('ids' => implode(',', $ids), 'read' => $r['read'], 'user_id' => $r['from_user_id'], 'object_id' => $r['object_id'], 'text' => $this->getUsersString($users) . ' ' . $this->getActionDeclination($r['action_type']) . ' ' . $this->getObjectName($r['data']) . '<div class="cG">' . Util\formatAgoTime($r['action_time']) . '</div>'); $rez[] = $record; } return $rez; }
/** * test notifications module * * @return [type] [description] */ public function testNotifications() { //check if everything is prepeared $this->assertTrue(sizeof($this->userIds) > 3, 'Less than 4 users created'); $this->assertTrue(sizeof($this->objectIds) > 2, 'Less than 3 tasks created'); //add a comment to obj 1 with user 1 referencing user 2 $firstUserId = $this->userIds[0]; $secondUserId = $this->userIds[1]; $thirdUserId = $this->userIds[2]; $forthUserId = $this->userIds[3]; $rootUserId = $this->oldValues['user_id']; $pid = $this->objectIds[0]; $commentData = array('pid' => $pid, 'template_id' => 9, 'data' => array('_title' => 'Hello to user @bow!')); $_SESSION['user']['id'] = $firstUserId; /* make a check - user should be denied to add comments */ try { $commentId = $this->createObject($commentData); } catch (\Exception $e) { $msg = $e->getMessage(); $this->assertTrue($msg == 'Access is denied', $msg); } $_SESSION['user']['id'] = $rootUserId; $this->addAllowSecurityRule(); // try again adding a comment, // now it should work without access exceptions $_SESSION['user']['id'] = $firstUserId; $commentId = $this->createObject($commentData); $this->assertTrue(is_numeric($commentId), 'Wrong comment ID.'); //check notifications for user bow, //he should receive 2 new notifications from root and andrew $this->assertTrue($this->checkLastNotification($secondUserId, array('user_id' => $firstUserId, 'object_id' => $pid, 'read' => 0)), 'Wrong last notification'); //check notifications for root user, he also should receive a new notification from andrew //as owner of the object $this->assertTrue($this->checkLastNotification($rootUserId, array('user_id' => $firstUserId, 'object_id' => $pid, 'read' => 0)), 'No notification for root (owner) user.'); //add comments with all 4 users and check notifications to cover //code for 3 and more users notifications grouping //and check root notifications with each comment for ($i = 0; $i < 4; $i++) { $_SESSION['user']['id'] = $this->userIds[$i]; $commentData['data']['_title'] = 'Comment from user #' . $i . '.'; $this->createObject($commentData); $this->assertTrue($this->checkLastNotification($rootUserId, array('user_id' => $this->userIds[$i], 'object_id' => $pid, 'read' => 0)), 'Wrong last notification for root from user #' . $i . '.'); } $_SESSION['user']['id'] = $rootUserId; /*-------- answer back to previous comment with root and see if notifications are created */ $commentData['data']['_title'] = 'Reply to Hellow comment.'; $commentId = $this->createObject($commentData); //check notifications for all 4 users for ($i = 0; $i < 3; $i++) { $this->assertTrue($this->checkLastNotification($this->userIds[$i], array('object_id' => $pid, 'read' => 0)), 'Wrong last notification from root for user #' . $i . '.'); } $this->checkMarkingNotificationsAsRead(); //end of big testing schema //cover for now some simple code from Notifications $this->assertTrue(\CB\Notifications::getActionDeclination('reopen', 'en') == 'reopened', 'Declination not correct for reopen.'); $this->assertTrue(\CB\Notifications::getActionDeclination('SomeWrongValue!>', 'en') == 'SomeWrongValue!>', 'Declination not correct for a wrong value.'); $this->assertTrue(\CB\Notifications::getActionDeclination('file_upload', 'en') == 'uploaded a file to', 'Declination not correct for file_upload.'); $this->assertTrue(\CB\Notifications::getActionDeclination('file_update', 'en') == 'updated a file in', 'Declination not correct for file_update.'); //update a task and delete them all $obj = \CB\Objects::getCachedObject($pid); $data = $obj->getData(); $data['data']['due_date'] = '2012-12-17T00:00:00Z'; unset($data['data']['importance']); $data['data']['description'] .= ' *update* '; $obj->update($data); foreach ($this->objectIds as $id) { $obj->delete(false); } //get unset notifications and and access functions for preparing email $recs = DM\Notifications::getUnsent(); foreach ($recs as $action) { $userData = \CB\User::getPreferences($action['to_user_id']); $sender = \CB\Notifications::getSender($action['from_user_id']); $body = \CB\Notifications::getMailBodyForAction($action, $userData); } }
/** * add notification records for a given log action * @param array $p * ('object_id', 'object_pid', 'user_id', 'action_type', 'data', 'activity_data_db') * * @return void */ private static function addNotificationRecords($p) { $activityData = Util\toJSONArray($p['activity_data_db']); $users = array(); //backward compatibility if (!empty($activityData['fu'])) { foreach ($activityData['fu'] as $uid) { $users[intval($uid)] = 0; } } if (!empty($activityData['wu'])) { foreach ($activityData['wu'] as $uid) { $users[intval($uid)] = 0; } } //exclude current user from notified users unset($users[User::getId()]); $params = array('object_id' => $p['object_id'], 'action_id' => $p['id'], 'action_type' => $p['action_type'], 'from_user_id' => $p['user_id']); foreach ($users as $uid => $seen) { $params['user_id'] = $uid; $params['seen'] = $seen; DM\Notifications::add($params); } }
function sendUserMails($u) { $uid = $u['id']; if (empty($u['email'])) { return; } $sendType = User::canSendNotifications($uid); if ($sendType == false) { return; } $coreName = Config::get('core_name'); // $coreUrl = Config::get('core_url'); $languages = Config::get('languages'); $lang = $languages[$u['language_id'] - 1]; if (filter_var($u['email'], FILTER_VALIDATE_EMAIL)) { //group mails into digest and separate ones (where user is mentioned) $mails = array('digest' => array(), 'separate' => array()); foreach ($u['mails'] as $notificationId => $notification) { //[$core #$nodeId] $action_type $template_name: $object_title $templateId = Objects::getTemplateId($notification['object_id']); $templateName = Objects::getName($templateId); $subject = '[' . $coreName . ' #' . $notification['object_id'] . '] ' . Notifications::getActionDeclination($notification['action_type'], $lang) . ' ' . $templateName . ' "' . htmlspecialchars_decode($notification['data']['name']) . '"'; $sender = Notifications::getSender($notification['from_user_id']); //divide notification into separate number of actions it consist of $actions = getNotificationActions($notification); for ($i = 0; $i < sizeof($actions); $i++) { $a = $actions[$i]; $message = Notifications::getMailBodyForAction($a, $u); $isMentioned = !empty($a['data']['mentioned']) && in_array($uid, $a['data']['mentioned']); $mails[$isMentioned ? 'separate' : 'digest'][] = array('subject' => $subject, 'body' => $message, 'sender' => $sender, 'nId' => $notificationId); } } //merge digest emails group into one email and put it into separate group if (sizeof($mails['digest']) == 1) { $mails['separate'][] = $mails['digest'][0]; } elseif (!empty($mails['digest'])) { $mail = array(); $ids = array(); $sender = ''; foreach ($mails['digest'] as $m) { $mail[] = $m['body']; $sender = $m['sender']; $ids[] = $m['nId']; } $mails['separate'][] = array('subject' => '[' . $coreName . '] Notifications digest', 'body' => implode('<hr />', $mail), 'sender' => $sender, 'nId' => $ids); } foreach ($mails['separate'] as $mail) { echo $u['email'] . ': ' . $mail['subject'] . "\n"; if (!mail($u['email'], $mail['subject'], $mail['body'], "Content-type: text/html; charset=utf-8\r\nFrom: " . $mail['sender'] . "\r\n")) { System::notifyAdmin('CaseBox cron notification: Cant send notification (' . $mail['nId'] . ') mail to "' . $u['email'] . '"', $mail['body']); } else { DM\Notifications::markAsSeen($mail['nId'], $uid); } } if (!empty($mails['digest'])) { User::setUserConfigParam('lastNotifyTime', Util\dateISOToMysql('now'), $uid); } } }
/** * add notification records for a given log action * @param array $p * ('object_id', 'object_pid', 'user_id', 'action_type', 'data', 'activity_data_db') * * @return void */ private static function addNotificationRecords($p) { $activityData = Util\toJSONArray($p['activity_data_db']); $users = array(); if (!empty($activityData['fu'])) { foreach ($activityData['fu'] as $uid) { $users[intval($uid)] = 0; // email unsent meaning } } if (!empty($activityData['wu'])) { foreach ($activityData['wu'] as $uid) { $users[intval($uid)] = -1; // email doesnt need to be sent } } //exclude current user from notified users unset($users[User::getId()]); $params = array('object_id' => $p['object_id'], 'action_id' => $p['id'], 'action_type' => $p['action_type'], 'from_user_id' => $p['user_id']); foreach ($users as $uid => $uMailSent) { $params['user_id'] = $uid; $params['email_sent'] = $uMailSent; DM\Notifications::add($params); } }
} //dont try to send any notification if the script starts for the first time if (empty($cd['last_start_time'])) { DB\dbQuery('UPDATE notifications SET email_sent = -1 WHERE email_sent = 0') or die(DB\dbQueryError()); exit; } L\initTranslations(); $users = array(); $coreName = Config::get('core_name'); $coreUrl = Config::get('core_url'); $languages = Config::get('languages'); $adminEmail = Config::get('ADMIN_EMAIL'); //send notification mails only if not in dev mode or _dev_sent_mails not set to 0 $sendNotificationMails = Config::get('_dev_mode', 0) == 0 || Config::get('_dev_send_mail', 1) == 1; //collect notifications to be sent $recs = DM\Notifications::getUnsent(); foreach ($recs as $r) { $uid = $r['to_user_id']; if (!isset($users[$uid])) { $users[$uid] = User::getPreferences($uid); } $users[$uid]['mails'][$r['id']] = $r; } //iterate mails for each user and send them foreach ($users as $u) { if (empty($u['email'])) { continue; } $lang = $languages[$u['language_id'] - 1]; if (filter_var($u['email'], FILTER_VALIDATE_EMAIL)) { foreach ($u['mails'] as $notificationId => $action) {