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;
}
// PHPMailer konfigurieren
ConfigurePhpMailer();
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($previousDate === false || $previousDate !== $currentDate){
sendNotificationMail($user['id'], $user['private_count'], $user['public_count']);
setUserCacheValue($user['id'], $currentDate);
}
}
/*****************************************
ENDE: Ab hier nur Funktionen
******************************************/
/**
* PHPMailer konfigurieren
*
* @return void
*/
function ConfigurePhpMailer()
{
global $app;
// Mail-Konfiguration laden
$mailConfig = [
'benutzername' => $app->erp->Firmendaten("benutzername"),
'passwort' => $app->erp->Firmendaten("passwort"),
'host' => $app->erp->Firmendaten("host"),
'port' => $app->erp->Firmendaten("port"),
'mailssl' => (int)$app->erp->Firmendaten("mailssl"),
'noauth' => (int)$app->erp->Firmendaten("noauth"),
'mailanstellesmtp' => (int)$app->erp->Firmendaten("mailanstellesmtp"),
];
// PHPMailer initialisieren
$app->mail = new PHPMailer($app);
$app->mail->CharSet = 'UTF-8';
$app->mail->PluginDir = 'plugins/phpmailer/';
if($mailConfig['mailanstellesmtp'] === 1){
$app->mail->IsMail();
}else{
$app->mail->IsSMTP();
if($mailConfig['noauth'] === 1){
$app->mail->SMTPAuth = false;
}else{
$app->mail->SMTPAuth = true;
}
if($mailConfig['mailssl'] === 1){
$app->mail->SMTPSecure = 'tls';
}else if($mailConfig['mailssl'] === 2){
$app->mail->SMTPSecure = 'ssl';
}
$app->mail->Host = $mailConfig['host'];
$app->mail->Port = $mailConfig['port'];
$app->mail->Username = $mailConfig['benutzername'];
$app->mail->Password = $mailConfig['passwort'];
}
}
/**
* 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($private = [], $public = [])
{
if (empty($private)) {
$private = [];
}
if (empty($public)) {
$public = [];
}
$result = [];
foreach ($private 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 ($public 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;
}
$app->mail->ClearData();
$app->mail->AddAddress($toMail, $toName);
$fromMail = $app->erp->GetFirmaMail();
$fromName = $app->erp->GetFirmaName();
$subject = '[Xentral] Ungelesene Chat-Nachrichten';
$totalMessageCount = (int)$privateMessages + (int)$publicMessages;
$messages = GetNewestMessagesForUser($userId);
if (empty($messages)) {
return false;
}
// Xentral-Logo einbinden
$logoFilePath = dirname(__DIR__) . '/www/themes/new/images/xentral_logo.png';
$app->mail->AddEmbeddedImage($logoFilePath, 'logo', 'logo.png');
// 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']);
}
$app->mail->From = $fromMail;
$app->mail->FromName = $fromName;
$app->mail->Subject = $subject;
$app->mail->Body = GetHtmlMessage($toName, $totalMessageCount, $messages);
$app->mail->IsHTML(true);
if(!$app->mail->Send()){
echo $app->mail->ErrorInfo;
$app->erp->LogFile("Mailer Error: " . $app->mail->ErrorInfo);
return false;
}
return true;
}
/**
* 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 = <<
[Xentral] 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;
}