Conf)) { $conf = new Config(); $app->Conf = $conf; } if(empty($app->DB) || empty($app->DB->connection)) { $app->DB = new DB($app->Conf->WFdbhost, $app->Conf->WFdbname, $app->Conf->WFdbuser, $app->Conf->WFdbpass, $app, $app->Conf->WFdbport); } if(empty($app->erp)) { if(class_exists('erpAPICustom')) { $erp = new erpAPICustom($app); } else { $erp = new erpAPI($app); } $app->erp = $erp; } // Alle Benutzer ermitteln die seit 30 Minuten ungelesene private Nachrichten haben // u.kalender_ausblenden = "Im Kalender/Chat ausblenden"; außerdem keine Chat-Benachrichtigung empfangen $usersWithUnreadPrivateMessages = $app->DB->SelectArr( 'SELECT c.user_to AS id, MAX(c.zeitstempel) AS message_date, COUNT(c.id) AS message_count FROM `user` AS u INNER JOIN `chat` AS c ON c.user_to = u.id AND c.user_to <> 0 LEFT JOIN `chat_gelesen` AS g ON c.id = g.message WHERE g.id IS NULL AND u.activ = 1 AND u.kalender_ausblenden != 1 AND DATE_ADD(c.zeitstempel, INTERVAL 30 MINUTE) < NOW() GROUP BY c.user_to' ); // Alle Benutzer ermitteln die seit 30 Minuten ungelesene öffentliche Nachrichten haben // u.kalender_ausblenden = "Im Kalender/Chat ausblenden"; außerdem keine Chat-Benachrichtigung empfangen $usersWithUnreadPublicMessages = $app->DB->SelectArr( 'SELECT u.id, MAX(c.zeitstempel) AS message_date, COUNT(c.id) AS message_count FROM `user` AS u INNER JOIN `chat` AS c ON c.zeitstempel > u.logdatei AND c.user_to = 0 LEFT JOIN `chat_gelesen` AS g ON c.id = g.message AND g.user = u.id WHERE g.id IS NULL AND u.activ = 1 AND u.kalender_ausblenden != 1 AND DATE_ADD(c.zeitstempel, INTERVAL 30 MINUTE) < NOW() GROUP BY u.id' ); // Benutzer zusammenführen $usersWithUnreadMessages = combineUserResult( $usersWithUnreadPrivateMessages, $usersWithUnreadPublicMessages ); if(empty($usersWithUnreadMessages)){ return; } foreach ($usersWithUnreadMessages as $user) { $previousDate = (int)getUserCacheValue($user['id']); $currentDate = max((int)$user['private_date'], (int)$user['public_date']); // Datum gleich > User hat bereits Benachrichtigung bekommen + keine neuen Nachrichten vorhanden > Benachrichtigung NICHT senden // Datum ungleich > User hat bereits Benachrichtigung bekommen + Neue Nachrichten vorhanden > Benachrichtigung senden // Kein Datum hinterlegt > User hat noch nie Benachrichtigung bekommen > Benachrichtigung senden // if(empty($previousDate) || $previousDate !== $currentDate){ sendNotificationMail($user['id'], $user['private_count'], $user['public_count']); setUserCacheValue($user['id'], $currentDate); // } } /***************************************** ENDE: Ab hier nur Funktionen ******************************************/ /** * Timestamp der letzten ungelesenen Chat-Nachricht abrufen, zu der eine Mail-Benachrichtigung versendet wurde * * Soll verhindern dass Mail-Benachrichtigungen mehrfach versendet werden. * * @param int $userId * * @return string|false */ function getUserCacheValue($userId) { global $app; $result = $app->DB->Select( "SELECT k.value FROM userkonfiguration AS k WHERE k.name = 'chat_unread_message_date' AND k.user = '{$userId}' LIMIT 1" ); if(empty($result)){ return false; } return $result; } /** * Timestamp wegspeichern, der letzten ungelesenen Chat-Nachricht zu der eine Mail-Benachrichtigung versendet wurde * * Soll verhindern dass Mail-Benachrichtigungen mehrfach versendet werden. * * @param int $userId * @param string $cacheValue * * @return void */ function setUserCacheValue($userId, $cacheValue) { global $app; $userConfigId = (int)$app->DB->Select( "SELECT k.id FROM userkonfiguration AS k WHERE k.name = 'chat_unread_message_date' AND k.user = '{$userId}' LIMIT 1" ); if($userConfigId > 0){ $app->DB->Update( "UPDATE userkonfiguration SET `value` = '{$cacheValue}' WHERE `user` = '{$userId}' AND `name` = 'chat_unread_message_date' LIMIT 1" ); }else{ $app->DB->Insert( "INSERT INTO userkonfiguration (`user`, `name`, `value`) VALUES ('{$userId}', 'chat_unread_message_date', '{$cacheValue}')" ); } } /** * @param array $private * @param array $public * * @return array */ function combineUserResult($privates = [], $publics = []) { if (empty($privates)) { $privates = []; } if (empty($publics)) { $publics = []; } $result = []; foreach ($privates as $user) { $userId = $user['id']; $result[$userId]['id'] = $userId; $result[$userId]['private_date'] = strtotime($user['message_date']); $result[$userId]['private_count'] = $user['message_count']; } foreach ($publics as $user) { $userId = $user['id']; $result[$userId]['id'] = $userId; $result[$userId]['public_date'] = strtotime($user['message_date']); $result[$userId]['public_count'] = $user['message_count']; } return $result; } /** * Mail-Benachrichtung senden * * @param int $userId * @param array $privateMessages * @param array $publicMessages * * @return bool */ function sendNotificationMail($userId, $privateMessages, $publicMessages) { global $app; if((int)$userId === 0){ return false; } if((int)$publicMessages === 0 && (int)$privateMessages === 0){ return false; } $toMail = $app->DB->Select( "SELECT a.email FROM `user` AS u INNER JOIN adresse a ON a.id = u.adresse WHERE u.id = '{$userId}' AND u.activ = 1 LIMIT 1" ); $toName = $app->DB->Select( "SELECT a.name FROM `user` AS u INNER JOIN adresse a ON a.id = u.adresse WHERE u.id = '{$userId}' AND u.activ = 1 LIMIT 1" ); if(empty($toMail)){ return false; } $fromMail = $app->erp->GetFirmaMail(); $fromName = $app->erp->GetFirmaName(); $subject = 'Ungelesene Chat-Nachrichten'; $totalMessageCount = (int)$privateMessages + (int)$publicMessages; $messages = GetNewestMessagesForUser($userId); if (empty($messages)) { return; } /* // Profilbilder einbinden $userFromIds = array_unique(array_column($messages, 'user_from')); foreach ($userFromIds as $userFromId) { $profileImage = GetProfilImage($userFromId); $app->mail->AddEmbeddedImage($profileImage['path'], $profileImage['cid'], $profileImage['name']); }*/ // $text = GetHtmlMessage($toName, $totalMessageCount, $messages); ?!? -> IF we want to use formatted mails, we will have to make use of templates // Very lean implementation: $text = "Neue Chat-Nachrichten vorhanden.

"; foreach ($messages as $message) { $zeitstempel = strtotime($message['zeitstempel']); $message['zeitstempel'] = 'am ' . date('d.m.Y', $zeitstempel) . ' um ' . date('H:i', $zeitstempel) .' Uhr'; $text .= "\"".$message['message']."\"
"; if (empty($message['user_to'])) { $text .= "(öffentlich)
"; } $text .= "".$message['user_from_name']." ".$message['zeitstempel']."

"; $text = htmlspecialchars($text); } // function MailSend($from,$from_name,$to,$to_name,$betreff,$text,$files="",$projekt="",$signature=true,$cc="",$bcc="", $system = false) $app->erp->MailSend($fromMail,$fromName,$toMail,$toName,$subject,$text,"","",false,"","", true); $app->erp->LogFile("Mailed ".$subject." to ".$toMail); } /** * Chat-Nachrichten für Mail ermitteln * * Benötigt wird nur die neueste Nachricht pro Absender. * Und die neueste Nachricht aus dem öffentlichen Raum. * * @param int $userId * * @return array */ function GetNewestMessagesForUser($userId) { global $app; $lastUnreadMessageTimestamp = getUserCacheValue($userId); if (empty($lastUnreadMessageTimestamp)) { $lastUnreadMessageTimestamp = time(); } $privateMessages = $app->DB->SelectArr( 'SELECT c.user_to, c.user_from, a.name AS user_from_name, c.message, c.zeitstempel FROM chat AS c INNER JOIN `user` AS u ON c.user_from = u.id INNER JOIN `adresse` AS a ON u.adresse = a.id INNER JOIN ( SELECT MAX(c.id) AS message_id FROM chat AS c LEFT JOIN `chat_gelesen` AS g ON c.id = g.message WHERE g.id IS NULL AND c.user_to <> 0 GROUP BY c.user_from, c.user_to ) AS newest_messages ON c.id = newest_messages.message_id WHERE c.user_to = ' . (int)$userId . ' AND u.activ = 1 AND UNIX_TIMESTAMP(c.zeitstempel) > ' . $lastUnreadMessageTimestamp . ' GROUP BY c.user_from' ); $publicMessages = $app->DB->SelectArr( 'SELECT c.user_to, c.user_from, a.name AS user_from_name, c.message, c.zeitstempel FROM chat AS c INNER JOIN `user` AS u ON c.user_from = u.id INNER JOIN `adresse` AS a ON u.adresse = a.id INNER JOIN ( SELECT MAX(c.id) AS message_id FROM chat AS c WHERE c.user_to = 0 GROUP BY c.user_to ) AS newest_messages ON c.id = newest_messages.message_id LEFT JOIN `chat_gelesen` AS g ON c.id = g.message AND g.user = u.id AND u.id = ' . (int)$userId . ' WHERE u.activ = 1 AND g.id IS NULL AND UNIX_TIMESTAMP(c.zeitstempel) > ' . $lastUnreadMessageTimestamp ); if (empty($privateMessages)) { $privateMessages = []; } if (empty($publicMessages)) { $publicMessages = []; } return array_merge($privateMessages, $publicMessages); } /** * Profilbild pro User ermitteln * * @param int $userId * * @return array */ function GetProfilImage($userId) { global $app; if((int)$userId > 0){ $adresse = (int)$app->DB->Select( "SELECT a.id FROM user u LEFT JOIN adresse a ON a.id = u.adresse LEFT JOIN adresse_rolle ar ON ar.adresse = a.id WHERE u.activ = 1 AND u.kalender_ausblenden != 1 AND ar.subjekt = 'Mitarbeiter' AND (ar.bis = '0000-00-00' OR ar.bis <= NOW()) AND u.id = '{$userId}' AND ((u.hwtoken <> 4 ) OR u.hwtoken IS NULL) LIMIT 1" ); if($adresse > 0){ $dateiversion = (int)$app->DB->Select( "SELECT dv.id FROM datei_stichwoerter ds INNER JOIN datei d ON ds.datei = d.id INNER JOIN datei_version dv ON dv.datei = d.id WHERE d.geloescht = 0 AND objekt LIKE 'Adressen' AND parameter = '{$adresse}' AND subjekt LIKE 'Profilbild' ORDER by dv.id DESC LIMIT 1" ); if($dateiversion > 0){ $userdata = isset($app->Conf->WFuserdata) ? $app->Conf->WFuserdata : str_replace('index.php', '', $_SERVER['SCRIPT_FILENAME']) . '../userdata'; $path = $userdata . '/dms/' . $app->Conf->WFdbname; $cachefolder = $path . '/cache'; $cachefolder = $app->erp->GetDMSPath($dateiversion . '_100_100', $cachefolder, true); if(file_exists($cachefolder . '/' . $dateiversion . '_100_100')){ $type = mime_content_type($cachefolder . '/' . $dateiversion . '_100_100'); switch ($type) { case 'image/jpg': case 'image/jpeg': return [ 'cid' => 'user_' . $userId, 'name' => 'user_' . $userId . '.jpg', 'path' => $cachefolder . '/' . $dateiversion . '_100_100', ]; case 'image/png': return [ 'cid' => 'user_' . $userId, 'name' => 'user_' . $userId . '.png', 'path' => $cachefolder . '/' . $dateiversion . '_100_100', ]; case 'image/gif': return [ 'cid' => 'user_' . $userId, 'name' => 'user_' . $userId . '.gif', 'path' => $cachefolder . '/' . $dateiversion . '_100_100', ]; case 'application/pdf': return [ 'cid' => 'user_' . $userId, 'name' => 'user_' . $userId . '.png', 'path' => dirname(__DIR__) . '/themes/new/images/pdf.svg', ]; } } } } } return [ 'cid' => 'user_' . $userId, 'name' => 'user_' . $userId . '.png', 'path' => dirname(__DIR__) . '/www/themes/new/images/profil.png', ]; } /** * HTML-Nachrichteninhalt zusammenstellen * * @param string $receipientName * @param int $messageTotalCount * @param array $messages * * @return string HTML-Template */ function GetHtmlMessage($receipientName, $messageTotalCount, $messages = []) { $template = << [OpenXE] Ungelesene Chat-Nachrichten

Hallo {$receipientName}!

Es gibt {$messageTotalCount} neue Chat-Nachrichten im Xentral ERP.

HTML; $privateHeaderViewed = false; foreach ($messages as $message) { $zeitstempel = strtotime($message['zeitstempel']); $message['zeitstempel'] = 'vom ' . date('d.m.Y', $zeitstempel) . ' um ' . date('H:i', $zeitstempel) .' Uhr'; $template .= '
'; if ((int)$message['user_to'] === 0) { $template .= '

Neueste öffentliche Nachricht

'; } if ((int)$message['user_to'] > 0 && $privateHeaderViewed === false) { $template .= '

Ungelesene private Nachrichten

'; $privateHeaderViewed = true; } $template .= '
' . '' . '
'. '
'. ''. $message['user_from_name'] . ' '. '' . $message['zeitstempel'] . ''. '
'. '
'.htmlspecialchars($message['message']).'
'. '
'. '
'; } $template .= '
' . '
' . ''; return $template; }