2021-05-21 08:49:41 +02:00
< ? php
/*
**** COPYRIGHT & LICENSE NOTICE *** DO NOT REMOVE ****
*
* Xentral ( c ) Xentral ERP Sorftware GmbH , Fuggerstrasse 11 , D - 86150 Augsburg , * Germany 2019
*
* This file is licensed under the Embedded Projects General Public License * Version 3.1 .
*
* You should have received a copy of this license from your vendor and / or * along with this file ; If not , please visit www . wawision . de / Lizenzhinweis
* to obtain the text of the corresponding license version .
*
**** END OF COPYRIGHT & LICENSE NOTICE *** DO NOT REMOVE ****
*/
?>
< ? php
class Chat {
/** @var Application $app */
var $app ;
/** @var \Xentral\Components\Template\TemplateInterface $tmpl */
protected $tmpl ;
const MODULE_NAME = 'Chat' ;
public function __construct ( $app , $intern = false )
{
$this -> app = $app ;
if ( $intern ){
return ;
}
$this -> tmpl = $this -> app -> Container -> get ( 'Template' );
$this -> tmpl -> setDefaultNamespace ( 'Modules/Chat' );
$this -> app -> ActionHandlerInit ( $this );
$this -> app -> ActionHandler ( " list " , " ChatList " );
$this -> app -> DefaultActionHandler ( " list " );
$this -> app -> ActionHandlerListen ( $app );
}
public function Install ()
{
$this -> app -> erp -> CheckTable ( " chat " );
$this -> app -> erp -> CheckColumn ( " id " , " int(11) " , " chat " , " NOT NULL AUTO_INCREMENT " );
$this -> app -> erp -> CheckColumn ( " user_from " , " INT(11) " , " chat " , " DEFAULT '0' NOT NULL " );
$this -> app -> erp -> CheckColumn ( " user_to " , " INT(11) " , " chat " , " DEFAULT '0' NOT NULL " );
$this -> app -> erp -> CheckColumn ( " message " , " TEXT " , " chat " , " DEFAULT '' NOT NULL " );
$this -> app -> erp -> CheckColumn ( " prio " , " TINYINT(1) " , " chat " , " DEFAULT '0' NOT NULL " );
$this -> app -> erp -> CheckColumn ( " zeitstempel " , " DATETIME " , " chat " );
$this -> app -> erp -> CheckIndex ( " chat " , " user_from " );
$this -> app -> erp -> CheckIndex ( " chat " , " user_to " );
if ( ! $this -> app -> DB -> CheckTableExistence ( " chat_gelesen " )){
$this -> InstallGelesenTable ();
}
}
protected function InstallGelesenTable ()
{
// Neue Gelesen-Tabelle anlegen
$this -> app -> erp -> CheckTable ( " chat_gelesen " );
$this -> app -> erp -> CheckColumn ( " id " , " int(11) " , " chat_gelesen " , " NOT NULL AUTO_INCREMENT " );
$this -> app -> erp -> CheckColumn ( " user " , " INT(11) " , " chat_gelesen " , " DEFAULT '0' NOT NULL " );
$this -> app -> erp -> CheckColumn ( " message " , " INT(11) " , " chat_gelesen " , " DEFAULT '0' NOT NULL " );
$this -> app -> erp -> CheckColumn ( " zeitstempel " , " DATETIME " , " chat_gelesen " , " DEFAULT NULL " );
$this -> app -> erp -> CheckIndex ( " chat_gelesen " , " message " );
//$this->app->DB->Query("ALTER TABLE chat_gelesen ADD UNIQUE (`user`, `message`)");
$this -> app -> erp -> CheckIndex ( " chat_gelesen " , array ( 'user' , 'message' ), true );
$this -> app -> DB -> Insert ( " INSERT INTO chat_gelesen (message, `user`, zeitstempel) SELECT DISTINCT id, user_to, NULL FROM chat WHERE gelesen = 1 OR user_to = 0 " );
if ( $this -> app -> DB -> error ())
{
// Alte Gelesen-Markierungen in neue Tabelle übernehmen
$readMessages = $this -> app -> DB -> SelectArr ( " SELECT c.id, c.user_to FROM chat AS c WHERE c.gelesen = '1' AND c.user_to > 0 " );
foreach ( $readMessages as $readMessage ) {
$sql = " INSERT INTO chat_gelesen (message, `user`, zeitstempel) " ;
$sql .= " VALUES (' " . $readMessage [ 'id' ] . " ', ' " . $readMessage [ 'user_to' ] . " ', NULL) " ;
$this -> app -> DB -> Insert ( $sql );
}
// Gelesen-Markierungen für öffentlichen Nachrichten übernehmen
$publicMessages = $this -> app -> DB -> SelectArr ( " SELECT c.id, c.user_to FROM chat AS c WHERE c.user_to = 0 " );
foreach ( $publicMessages as $publicMessage ) {
$sql = " INSERT INTO chat_gelesen (message, `user`, zeitstempel) " ;
$sql .= " VALUES (' " . $publicMessage [ 'id' ] . " ', ' " . $publicMessage [ 'user_to' ] . " ', NULL) " ;
$this -> app -> DB -> Insert ( $sql );
}
}
// Alte Gelesen-Spalte löschen
$this -> app -> DB -> Query ( " ALTER TABLE chat DROP COLUMN gelesen " );
}
public function ChatList ()
{
$cmd = $this -> app -> Secure -> GetGET ( 'cmd' );
switch ( $cmd ) {
case 'userlist' :
$data = array ();
$data [ 'users' ] = $this -> GetUserlist ();
$data [ 'rooms' ] = $this -> GetRoomlist ();
header ( 'Content-Type: application/json' );
echo json_encode ( $data );
exit ;
case 'messages' :
$user_id = ( int ) $this -> app -> Secure -> GetPOST ( 'user_id' );
$before_message_id = ( int ) $this -> app -> Secure -> GetPOST ( 'before_message_id' );
$after_message_id = ( int ) $this -> app -> Secure -> GetPOST ( 'after_message_id' );
$after_readmark_id = ( int ) $this -> app -> Secure -> GetPOST ( 'after_readmark_id' );
$data = $this -> GetMessages ( $user_id , $after_message_id , $after_readmark_id , $before_message_id );
header ( 'Content-Type: application/json' );
echo json_encode ( $data );
exit ;
case 'sendmessage' :
$this -> ChatSubmit ();
exit ;
case 'markread' :
$messageIds = $this -> app -> Secure -> GetPOST ( 'messages' );
$data = $this -> MarkAsRead ( $messageIds );
header ( 'Content-Type: application/json' );
echo json_encode ( $data );
exit ;
}
$this -> app -> erp -> StartseiteMenu ();
if ( $this -> app -> DB -> Select ( " SELECT chat_popup FROM `user` WHERE id = ' " . $this -> app -> User -> GetID () . " ' LIMIT 1 " ))
{
$this -> app -> BuildNavigation = false ;
$this -> app -> PopupJS = true ;
$this -> tmpl -> assign ( 'chatStandaloneClass' , 'chat-standalone' );
}
$this -> tmpl -> assign ( 'tabText' , 'Chat' );
$this -> tmpl -> display ( 'list.tpl' );
}
protected function GetRoomList ()
{
$userId = $this -> app -> User -> GetID ();
$registrierDatum = $this -> app -> DB -> Select ( " SELECT u.logdatei FROM `user` AS u WHERE u.id = ' " . $userId . " ' " );
// Öffentliche Nachrichten erst ab Registrierdatum zählen
$ungelesen = $this -> app -> DB -> Select (
" SELECT COUNT(c.id)
FROM chat AS c
LEFT JOIN chat_gelesen AS g ON c . id = g . message AND ( g . user = '".$userId."' OR g . user = 0 )
WHERE c . user_to = '0' AND c . zeitstempel > '".$registrierDatum."'
AND g . id IS NULL "
);
$data = array (
array (
'id' => 0 ,
'name' => 'Öffentlich' ,
'unread' => $ungelesen ,
)
);
return $data ;
}
protected function GetUserlist ()
{
$userId = $this -> app -> User -> GetID ();
$users = $this -> app -> DB -> SelectArr (
" SELECT DISTINCT u.id, a.name, uo.login, DATE_ADD(uo.time, INTERVAL 30 MINUTE) > NOW() AS recently_online
FROM user u
INNER JOIN adresse a ON a . id = u . adresse
INNER JOIN adresse_rolle ar ON ar . adresse = a . id
LEFT JOIN useronline uo ON uo . user_id = u . id AND uo . login = 1
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 . hwtoken <> 4 ) OR u . hwtoken IS NULL )
ORDER BY a . name ASC "
);
$data = array ();
$cusers = ! empty ( $users ) ? count ( $users ) : 0 ;
for ( $i = 0 ; $i < $cusers ; $i ++ )
{
$ungelesen = $this -> app -> DB -> Select (
" SELECT COUNT(c.id) FROM chat AS c
LEFT JOIN chat_gelesen AS g ON c . id = g . message
WHERE c . user_to = '" . $userId . "'
AND c . user_from = '" . $users[$i][' id '] . "'
AND g . id IS NULL " // Kein Eintrag in chat_gelesen = ungelesen
);
$data [ $i ][ 'id' ] = $users [ $i ][ 'id' ];
$data [ $i ][ 'name' ] = $users [ $i ][ 'name' ];
$data [ $i ][ 'unread' ] = ( int ) $ungelesen ;
$data [ $i ][ 'online' ] = ( int ) $users [ $i ][ 'login' ] === 1 && ( int ) $users [ $i ][ 'recently_online' ] === 1 ? true : false ;
$data [ $i ][ 'self' ] = ( $users [ $i ][ 'id' ] == $this -> app -> User -> GetID ()) ? true : false ;
}
return $data ;
}
protected function GetMessages ( $fromUserId , $afterMessageId = null , $afterReadmarkId = null , $beforeMessageId = null )
{
$fromUserId = ( int ) $fromUserId ;
$selfUserId = ( int ) $this -> app -> User -> GetID ();
$andWhere = '' ;
if ( $beforeMessageId !== null && $beforeMessageId !== 0 ) {
$andWhere = " AND c.id < " . ( int ) $beforeMessageId . " " ;
}
if ( $afterMessageId !== null && $afterMessageId !== 0 ) {
$andWhere = " AND c.id > " . ( int ) $afterMessageId . " " ;
}
if ( $fromUserId === 0 ) {
// Chat mit "Öffentlich"
$sql = " SELECT c.id, c.user_from, a.name AS user_from_name, g.id AS gelesen_id, g.zeitstempel AS gelesen_zeitstempel, c.message, c.user_to,
DATE_FORMAT ( c . zeitstempel , '%d.%m.%Y' ) AS datum , DATE_FORMAT ( c . zeitstempel , '%H:%i:%s' ) AS uhrzeit
FROM chat AS c
LEFT JOIN chat_gelesen AS g ON c . id = g . message AND ( g . user = '".$selfUserId."' OR g . user = 0 )
INNER JOIN `user` AS u ON c . user_from = u . id
INNER JOIN adresse AS a ON u . adresse = a . id
WHERE c . user_to = 0 " ;
$sql .= $andWhere ;
$sql .= " GROUP BY c.id " ;
$sql .= " ORDER BY c.id DESC LIMIT 0, 20 " ;
$messages = $this -> app -> DB -> SelectArr ( $sql );
// Gelesen-Markierungen gibt es nicht im öffentlichen Chat
$readmarks = array ();
} else {
// Chat mit Benutzer
// Nachrichten abrufen
$sql = " SELECT c.id, c.user_from, a.name AS user_from_name, g.id AS gelesen_id, c.message, c.prio, c.user_to,
DATE_FORMAT ( c . zeitstempel , '%d.%m.%Y' ) AS datum , DATE_FORMAT ( c . zeitstempel , '%H:%i:%s' ) AS uhrzeit
FROM chat AS c
LEFT JOIN chat_gelesen AS g ON c . id = g . message AND c . user_to = g . user
INNER JOIN `user` AS u ON c . user_from = u . id
INNER JOIN adresse AS a ON u . adresse = a . id
WHERE (( c . user_to = '" . $fromUserId . "' AND user_from = '" . $selfUserId . "' )
OR ( c . user_from = '" . $fromUserId . "' AND user_to = '" . $selfUserId . "' )) " ;
$sql .= $andWhere ;
$sql .= " ORDER by c.id DESC LIMIT 0, 20 " ;
$messages = $this -> app -> DB -> SelectArr ( $sql );
// Gelesen-Markierungen abrufen
$sql = " SELECT g.id, g.message
FROM chat_gelesen AS g
WHERE g . user = '".$fromUserId."' " ;
if ( $afterReadmarkId > 0 ) {
$sql .= " AND g.id > ' " . $afterReadmarkId . " ' " ;
$sql .= " ORDER BY g.id ASC LIMIT 0, 20 " ;
} else {
// Nur die neueste Markierung mitschicken
$sql .= " ORDER BY g.id DESC LIMIT 0, 1 " ;
}
$readmarks = $this -> app -> DB -> SelectArr ( $sql );
}
$data = array (
'messages' => array (), // Chat-Nachrichten
'readmark' => array () // Gelesen-Markierungen
);
// Nachrichten aufbereiten
foreach ( $messages as $message ) {
$data [ 'messages' ][] = array (
'id' => ( int ) $message [ 'id' ],
'read' => (( int ) $message [ 'gelesen_id' ] > 0 ) ? true : false ,
'prio' => ( ! empty ( $message [ 'prio' ]) && $message [ 'prio' ] === '1' ) ? true : false ,
'text' => $this -> MakeLinks ( $message [ 'message' ]),
'user' => ( int ) $message [ 'user_from' ],
'name' => $message [ 'user_from_name' ],
'date' => $message [ 'datum' ],
'time' => $message [ 'uhrzeit' ]
);
}
$data [ 'messages' ] = array_reverse ( $data [ 'messages' ]);
// Gelesen-Markierungen aufbereiten
if ( is_array ( $readmarks )) {
foreach ( $readmarks as $readmark ) {
$data [ 'readmark' ][] = array (
'id' => ( int ) $readmark [ 'id' ],
'message' => ( int ) $readmark [ 'message' ],
);
}
}
return $data ;
}
protected function ChatSubmit ()
{
/** @var \Xentral\Modules\SystemNotification\Service\NotificationServiceInterface $notification */
$notification = $this -> app -> Container -> get ( 'NotificationService' );
$nachricht = $this -> app -> Secure -> GetPOST ( " nachricht " );
$empfaenger = $this -> app -> Secure -> GetPOST ( " empfaenger " );
$prio = $this -> app -> Secure -> GetPOST ( " prio " );
$nachricht = htmlspecialchars ( $nachricht );
if ( $nachricht != " " )
{
$this -> app -> DB -> Insert ( " INSERT INTO chat (id,user_from,user_to,message,zeitstempel,prio) VALUES ('',' " . $this -> app -> User -> GetID () . " ',' " . $empfaenger . " ',' $nachricht ',NOW(),'. $prio .') " );
if ( $prio == " 1 " ) {
$name = $this -> app -> DB -> Select ( " SELECT a.name FROM user u LEFT JOIN adresse a ON a.id=u.adresse WHERE u.id= " . $this -> app -> User -> GetID ());
if ( $empfaenger )
{
$notification -> create ( $empfaenger , 'default' , " $name ( " . date ( 'd.m' ) . " um " . date ( 'H:i' ) . " ) " , $nachricht , true );
$notification -> createPushNotification ( $empfaenger , 'Neue Chat-Nachricht von ' . $name , $nachricht , false );
} else {
$users = $this -> app -> DB -> SelectArr ( " SELECT DISTINCT u.id, a.name,u.type,
uo . login FROM user u LEFT JOIN adresse a ON a . id = u . adresse LEFT JOIN useronline uo ON uo . user_id = u . id AND uo . login = 1
LEFT JOIN adresse_rolle ar ON ar . adresse = a . id
WHERE u . activ = 1 AND uo . login = 1 AND u . kalender_ausblenden != 1 AND ar . subjekt = 'Mitarbeiter' AND ( ar . bis = '0000-00-00' OR ar . bis <= NOW ())
AND u . id != '".$this->app->User->GetID()."' AND (( u . hwtoken <> 4 ) OR u . hwtoken IS NULL ) group by u . id " );
if ( $users )
{
foreach ( $users as $user )
{
if ( $user [ 'type' ] == 'admin' || $this -> app -> DB -> Select ( " SELECT id FROM userrights WHERE user = ' " . $user [ 'id' ] . " ' AND module='chat' && action='list' and permission='1' LIMIT 1 " ))
{
$notification -> create ( $user [ 'id' ], 'default' , " $name ( " . date ( 'd.m' ) . " um " . date ( 'H:i' ) . " ) " , $nachricht , true );
$notification -> createPushNotification ( $user [ 'id' ], 'Neue Chat-Nachricht von ' . $name , $nachricht , false );
}
}
}
}
}
}
exit ;
}
protected function MarkAsRead ( $messageIds )
{
if ( ! is_array ( $messageIds )) {
return array ();
}
$data = array ();
$userId = $this -> app -> User -> GetID ();
foreach ( $messageIds as $messageId ) {
if (( int ) $messageId > 0 ) {
$sql = " INSERT INTO chat_gelesen(`user`, message, zeitstempel) VALUES (' " . $userId . " ', ' " . $messageId . " ', NOW()) " ;
$this -> app -> DB -> Insert ( $sql );
$data [] = $messageId ;
}
}
// IDs der gelesen-gesetzten Nachrichten zurücksenden
return $data ;
}
protected function MakeLinks ( $str ) {
$reg_exUrl = " /(http|https|ftp|ftps) \ : \ / \ /[a-zA-Z0-9 \ - \ .]+ \ .[a-zA-Z] { 2,3}( \ / \ S*)?/ " ;
$urls = array ();
$urlsToReplace = array ();
if ( preg_match_all ( $reg_exUrl , $str , $urls )) {
$numOfMatches = count ( $urls [ 0 ]);
$numOfUrlsToReplace = 0 ;
for ( $i = 0 ; $i < $numOfMatches ; $i ++ ) {
$alreadyAdded = false ;
2022-06-10 11:28:28 +02:00
$numOfUrlsToReplace = ( ! empty ( $urlsToReplace ) ? count ( $urlsToReplace ) : 0 );
2021-05-21 08:49:41 +02:00
for ( $j = 0 ; $j < $numOfUrlsToReplace ; $j ++ ) {
if ( $urlsToReplace [ $j ] == $urls [ 0 ][ $i ]) {
$alreadyAdded = true ;
}
}
if ( ! $alreadyAdded ) {
array_push ( $urlsToReplace , $urls [ 0 ][ $i ]);
}
}
2022-06-10 11:28:28 +02:00
$numOfUrlsToReplace = ( ! empty ( $urlsToReplace ) ? count ( $urlsToReplace ) : 0 );
2021-05-21 08:49:41 +02:00
for ( $i = 0 ; $i < $numOfUrlsToReplace ; $i ++ ) {
$str = str_replace ( $urlsToReplace [ $i ], " <a href= \" " . $urlsToReplace [ $i ] . " \" target= \" _blank \" > " . $urlsToReplace [ $i ] . " </a> " , $str );
}
return $str ;
} else {
return $str ;
}
}
}