From bfff821e188ad511c30e58ecf893798ae9c7e4b9 Mon Sep 17 00:00:00 2001 From: Christian Binder Date: Mon, 10 Dec 2007 08:26:29 +0000 Subject: [PATCH] notification-app is now ready for non-eGW users as sender and recipients. deleted the old-style sending part from bo_tracking. this is not needed anymore. --- etemplate/inc/class.bo_tracking.inc.php | 89 +++-------- notifications/inc/class.notification.inc.php | 141 +++++++++++++++--- .../inc/class.notification_email.inc.php | 25 ++-- .../inc/class.notification_popup.inc.php | 20 +-- .../inc/class.notification_winpopup.inc.php | 15 +- 5 files changed, 168 insertions(+), 122 deletions(-) diff --git a/etemplate/inc/class.bo_tracking.inc.php b/etemplate/inc/class.bo_tracking.inc.php index b907de2c4b..d2bdffb02f 100644 --- a/etemplate/inc/class.bo_tracking.inc.php +++ b/etemplate/inc/class.bo_tracking.inc.php @@ -366,25 +366,21 @@ class bo_tracking $GLOBALS['egw']->translation->init(); } - $sender = $this->get_sender($data,$old); - $subject = $this->get_subject($data,$old); - $attachments = $this->get_attachments($data,$old); - /* send over notification_app or alternative old-style mail class - * in future, we can make the notification app able to send mails - * for non-system users, so the else part below could be dropped - */ - if (is_numeric($user_or_lang) && $GLOBALS['egw_info']['apps']['notifications']['enabled']) { + // send over notification_app + if ($GLOBALS['egw_info']['apps']['notifications']['enabled']) { // send via notification_app + $receiver = is_numeric($user_or_lang) ? $user_or_lang : $email; require_once(EGW_INCLUDE_ROOT. '/notifications/inc/class.notification.inc.php'); try { $notification = new notification(); - $notification->set_receivers(array($user_or_lang)); + $notification->set_receivers(array($receiver)); $notification->set_message($this->get_body(false,$data,$old)); // set message as plaintext $notification->set_message($this->get_body(true,$data,$old)); // and html - $notification->set_sender($this->user); - $notification->set_subject($subject); + $notification->set_sender($this->get_sender($data,$old,true)); + $notification->set_subject($this->get_subject($data,$old)); // does not work atm //$notification->set_links(array($this->get_notification_link($data,$old))); + $attachments = $this->get_attachments($data,$old); if(is_array($attachments)) { $notification->set_attachments($attachments); } $notification->send(); } @@ -393,61 +389,7 @@ class bo_tracking return false; } } else { - // PHPMailer aka send-class, seems not to be able to send more then one mail, IF we need to authenticate to the SMTP server - // There for the object is newly created for ever mail, 'til this get fixed in PHPMailer. - $notification_sent = false; - //if(!is_object($GLOBALS['egw']->send)) - //{ - require_once(EGW_API_INC.'/class.send.inc.php'); - $GLOBALS['egw']->send = $send =& new send(); - //} - - $send->ClearAddresses(); - $send->ClearAttachments(); - - $send->IsHTML($html_email); - - if (preg_match('/^(.+) *<(.+)>/',$email,$matches)) // allow to use eg. "Ralf Becker " as address - { - $send->AddAddress($matches[2],$matches[1]); - } - else - { - $send->AddAddress($email,is_numeric($user_or_lang) ? $GLOBALS['egw']->accounts->id2name($user_or_lang,'account_fullname') : ''); - } - $send->AddCustomHeader("X-eGroupWare-type: {$this->app}update"); - - if (preg_match('/^(.+) *<(.+)>/',$sender,$matches)) // allow to use eg. "Ralf Becker " as sender - { - $send->From = $matches[2]; - $send->FromName = $matches[1]; - } - else - { - $send->From = $sender; - $send->FromName = ''; - } - $send->Subject = $subject; - $send->Body = "\n\n".$this->get_body(true,$data,$old)."\n\n"; - - foreach($attachments as $attachment) - { - if (isset($attachment['content'])) - { - $send->AddStringAttachment($attachment['content'],$attachment['filename'],$attachment['encoding'],$attachment['mimetype']); - } - elseif (isset($attachment['path'])) - { - $send->AddAttachment($attachment['path'],$attachment['filename'],$attachment['encoding'],$attachment['$mimetype']); - } - } - - //echo "

bo_trackering::send_notification(): sending

".print_r($send,true)."
\n"; - $notification_sent = $send->Send(); - if(!$notification_sent) { - $this->errors[] = lang('Error while notifying %1: %2',$email,$send->ErrorInfo); - return false; - } + error_log('tracking: cannot send any notifications because notification-app is not installed'); } return true; @@ -482,9 +424,10 @@ class bo_tracking * @param int $user account_lid of user * @param array $data * @param array $old - * @return string + * @param bool $prefer_id returns the userid rather than email + * @return string or userid */ - function get_sender($data,$old) + function get_sender($data,$old,$prefer_id=false) { $sender = $this->get_config('sender',$data,$old); //echo "

bo_tracking::get_sender() get_config('sender',...)='".htmlspecialchars($sender)."'

\n"; @@ -494,7 +437,11 @@ class bo_tracking { $name = $GLOBALS['egw']->accounts->id2name($this->user,'account_fullname'); - $sender = $name ? $name.' <'.$email.'>' : $email; + if($prefer_id) { + $sender = $this->user; + } else { + $sender = $name ? $name.' <'.$email.'>' : $email; + } } elseif(!$sender) { @@ -722,7 +669,9 @@ class bo_tracking if ($html_mail) { - $content .= $this->html->a_href($link,$link,'','target="_blank"'); + // the link is often too long for html boxes + // chunk-split allows to break lines if needed + $content .= $this->html->a_href(chunk_split($link,40,'​'),$link,'','target="_blank"'); } else { diff --git a/notifications/inc/class.notification.inc.php b/notifications/inc/class.notification.inc.php index 34d3ece8a3..b8c3167177 100644 --- a/notifications/inc/class.notification.inc.php +++ b/notifications/inc/class.notification.inc.php @@ -125,26 +125,70 @@ final class notification { * Set sender for the current notification * * @param $_sender object of account - * as long as the accounts class isn't a nice object, it's an int with the account id :-( + * as long as the accounts class isn't a nice object, + * it's an int with the account id or the e-mail address of a non-eGW user */ public function set_sender($_sender) { - $this->sender = is_object($_sender) ? $_sender : (object) $GLOBALS['egw']->accounts->get_account_data($_sender); - return true; + if(is_object($_sender)) { + $this->sender = $_sender; + return true; + } else { + // no object atm, we have to handle this and make a pseudo-object + if(is_numeric($_sender)) { + $this->sender = (object) $GLOBALS['egw']->accounts->read($_sender); + return true; + } + if(is_string($_sender) && strpos($_sender,'@')) { + $this->sender = (object) array ( + 'account_email' => $this->get_addresspart($_sender,'email'), + 'account_fullname' => $this->get_addresspart($_sender,'fullname'), + ); + return true; + } + } + return false; } /** * Set receivers for the current notification * * @param array $_receivers array with objects of accounts - * as long as the accounts class isn't a nice object, it's an array of account id's :-( + * as long as the accounts class isn't a nice object, + * it's an array with the int of the account id or the e-mail address of a non-eGW user */ public function set_receivers(array $_receivers) { - foreach ($_receivers as $receiver_id) { - $receiver = $GLOBALS['egw']->accounts->get_account_data($receiver_id); - $receiver[$receiver_id]['id'] = $receiver_id; - $this->receivers[$receiver_id] = (object)$receiver[$receiver_id]; + $this->receivers = array(); + foreach ($_receivers as $receiver) { + $this->add_receiver($receiver); } - return true; + } + + /** + * Add single receiver for the current notification + * + * @param $_receiver object of account + * as long as the accounts class isn't a nice object, + * it's an int with the account id or the e-mail address of a non-eGW user + */ + public function add_receiver($_receiver) { + if(is_object($_receiver)) { + $this->receivers[] = $_receiver; + return true; + } else { + // no object atm, we have to handle this and make a pseudo-object + if(is_numeric($_receiver)) { + $this->receivers[] = (object) $GLOBALS['egw']->accounts->read($_receiver); + return true; + } + if(is_string($_receiver) && strpos($_receiver,'@')) { + $this->receivers[] = (object) array ( + 'account_email' => $this->get_addresspart($_receiver,'email'), + 'account_fullname' => $this->get_addresspart($_receiver,'fullname'), + ); + return true; + } + } + return false; } /** @@ -260,19 +304,29 @@ final class notification { $user_notified = false; $backend_errors = array(); try { - // check if the receiver has rights to run the notifcation app - $ids = $GLOBALS['egw']->accounts->memberships($receiver->id,true); - $ids[] = $receiver->id; - if (!$GLOBALS['egw']->acl->get_specific_rights_for_account($ids,'run','notifications')) { - throw new Exception('Could not send notification to user '.$receiver->lid.' because of missing execute rights on notification-app.'); + // eGW user or external user + if($receiver->account_id && is_numeric($receiver->account_id)) { + // receiver is a eGW system-user + $receiver->handle = $receiver->account_lid; + // check if the receiver has rights to run the notifcation app + $ids = $GLOBALS['egw']->accounts->memberships($receiver->account_id,true); + $ids[] = $receiver->account_id; + if (!$GLOBALS['egw']->acl->get_specific_rights_for_account($ids,'run','notifications')) { + throw new Exception('Could not send notification to '.$receiver->handle.' because of missing execute rights on notification-app.'); + } + // read the users notification chain + $prefs = new preferences($receiver->account_id); + $preferences = $prefs->read(); + $preferences = (object)$preferences[self::_appname]; + $notification_chain = $this->notification_chains[$preferences->notification_chain]; + } else { + // receiver is not a eGW system-user + $receiver->handle = $receiver->account_email; + $notification_chain = $this->notification_chains['email_only']; } - $prefs = new preferences($receiver->id); - $preferences = $prefs->read(); - $preferences = (object)$preferences[self::_appname]; - $notification_chain = $this->notification_chains[$preferences->notification_chain]; if(!is_array($notification_chain)) { - throw new Exception('Could not send notification to user '.$receiver->lid.' because of missing notification settings.'); + throw new Exception('Could not send notification to '.$receiver->handle.' because of missing notification settings.'); } foreach($notification_chain as $notification_backend => $action) { @@ -298,7 +352,7 @@ final class notification { } // all backends failed - give error message if(!$user_notified) { - error_log('Error: notification of receiver '.$receiver->lid.' failed for the following reasons:'); + error_log('Error: notification of receiver '.$receiver->handle.' failed for the following reasons:'); foreach($backend_errors as $id=>$backend_error) { error_log($backend_error); } @@ -311,7 +365,7 @@ final class notification { } } catch (Exception $exception_user) { - error_log('Error: notification of receiver '.$receiver->lid.' failed: '.$exception_user->getMessage()); + error_log('Error: notification of receiver '.$receiver->handle.' failed: '.$exception_user->getMessage()); } } return true; @@ -329,7 +383,7 @@ final class notification { /** * gets receivers * - * @return array of account objects + * @return array of receiver objects */ public function get_receivers() { return $this->receivers; @@ -350,6 +404,7 @@ final class notification { $messages['plain'] = array(); $messages['html'] = array(); + // create the messages if(!empty($_message_plain)) { $messages['plain']['text'] = $_message_plain; } else { @@ -362,6 +417,7 @@ final class notification { $messages['html']['text'] = nl2br($_message_plain); } + // create the links if(is_array($_links)) { foreach($_links as $link) { $params = ''; @@ -379,6 +435,19 @@ final class notification { $messages['html']['link_jspopup'] .= '
'.$image.$link->text.'
'; } } + + // create additional formatted info for backends which do not use + // subject or sender as plain info + if(is_object($this->sender)) { + $sender = $this->sender->account_fullname ? $this->sender->account_fullname : $this->sender_account_email; + $messages['plain']['info_sender'] = lang('Message from').': '.$sender."\n"; + $messages['html']['info_sender'] = lang('Message from').': '.$sender.'
'; + } + if(!empty($this->subject)) { + $messages['plain']['info_subject'] = $this->subject."\n"; + $messages['html']['info_subject'] = $this->html->bold($this->subject).'
'; + } + return $messages; } @@ -397,4 +466,32 @@ final class notification { ($target == 'this.target' ? $target : "'".$target."'").",$width,$height,'yes')"; } + /** + * returns specified part from a given mailaddress + * + * @param string $_address + * @param string $_part + * @return string chosen part of the address + */ + private function get_addresspart($_address, $_part='email') { + if(strpos($_address,'<')) { // _address contains a fullname part + ereg('^(.*)[:space:]{0,1}<(.*)>',$_address,&$parts); + $fullname = trim(trim($parts[1]),'\"'); + $email = $parts[2]; + } else { + $fullname = false; + $email = $_address; + } + switch($_part) { + case 'fullname': + return $fullname; + break; + case 'email': + default: + return $email; + break; + } + return false; + } + } \ No newline at end of file diff --git a/notifications/inc/class.notification_email.inc.php b/notifications/inc/class.notification_email.inc.php index 4ab93a024a..225b087ffa 100644 --- a/notifications/inc/class.notification_email.inc.php +++ b/notifications/inc/class.notification_email.inc.php @@ -60,7 +60,9 @@ class notification_email implements iface_notification { /** * constructor of notification_email * + * @param object $_sender * @param object $_recipient + * @param object $_config * @param object $_preferences */ public function __construct( $_sender=false, $_recipient=false, $_config=false, $_preferences=false) { @@ -68,14 +70,12 @@ class notification_email implements iface_notification { // otherwise we have to fetch this objects for current user. if (!is_object($_sender)) { $this->sender = (object) $GLOBALS['egw']->accounts->read($_sender); - $this->sender->id =& $this->sender->account_id; } else { $this->sender = $_sender; } if (!is_object($_recipient)) { $this->recipient = (object) $GLOBALS['egw']->accounts->read($_recipient); - $this->recipient->id =& $this->recipient->account_id; } else { $this->recipient = $_recipient; @@ -87,7 +87,7 @@ class notification_email implements iface_notification { $this->config = $_config; } if(!is_object($_preferences)) { - $prefs = new preferences($this->recipient->id); + $prefs = new preferences($this->recipient->account_id); $preferences = $prefs->read(); $this->preferences = (object)$preferences[self::_appname ]; } else { @@ -107,15 +107,12 @@ class notification_email implements iface_notification { * @param array $_attachments */ public function send( $_subject = false, $_messages, $_attachments = false) { - $sender_email = $GLOBALS['egw']->accounts->id2name($this->sender->id,'account_email'); - $sender_fullname = $GLOBALS['egw']->accounts->id2name($this->sender->id,'account_fullname'); - $recipient_email = $GLOBALS['egw']->accounts->id2name($this->recipient->id,'account_email'); - $recipient_fullname = $GLOBALS['egw']->accounts->id2name($this->recipient->id,'account_fullname'); - if (!$sender_email || strpos($sender_email,'@') === false) { - throw new Exception("Failed sending notification message via email. No valid sender given."); + if(!is_object($this->sender)) { + throw new Exception("No sender given."); } - if (!$recipient_email || strpos($recipient_email,'@') === false) { - throw new Exception("Failed sending notification message via email. No valid recipient given."); + + if (!$this->recipient->account_email || strpos($this->recipient->account_email,'@') === false) { + throw new Exception("No valid recipient given."); } if($this->preferences->external_mailclient) { $body_plain = $_messages['plain']['text'].$_messages['plain']['link_external']; @@ -127,10 +124,10 @@ class notification_email implements iface_notification { $this->mail->ClearAddresses(); $this->mail->ClearAttachments(); $this->mail->IsHTML(true); - $this->mail->AddAddress($recipient_email, $recipient_fullname); + $this->mail->AddAddress($this->recipient->account_email, $this->recipient->account_fullname); $this->mail->AddCustomHeader('X-eGroupWare-type: notification-mail'); - $this->mail->From = $sender_email; - $this->mail->FromName = $sender_fullname; + $this->mail->From = $this->sender->account_email; + $this->mail->FromName = $this->sender->account_fullname; $this->mail->Subject = $this->mail->encode_subject($_subject); $this->mail->Body = $body_html; $this->mail->AltBody = $body_plain; diff --git a/notifications/inc/class.notification_popup.inc.php b/notifications/inc/class.notification_popup.inc.php index 4299d1b3f4..e93d41edcb 100644 --- a/notifications/inc/class.notification_popup.inc.php +++ b/notifications/inc/class.notification_popup.inc.php @@ -78,6 +78,7 @@ class notification_popup implements iface_notification { * * @param object $_sender * @param object $_recipient + * @param object $_config * @param object $_preferences */ public function __construct( $_sender=false, $_recipient=false, $_config=false, $_preferences=false) { @@ -85,14 +86,12 @@ class notification_popup implements iface_notification { // otherwise we have to fetch this objects for current user. if (!is_object($_sender)) { $this->sender = (object) $GLOBALS['egw']->accounts->read($_sender); - $this->sender->id =& $this->sender->account_id; } else { $this->sender = $_sender; } if (!is_object($_recipient)) { $this->recipient = (object) $GLOBALS['egw']->accounts->read($_recipient); - $this->recipient->id =& $this->recipient->account_id; } else { $this->recipient = $_recipient; @@ -104,7 +103,7 @@ class notification_popup implements iface_notification { $this->config = $_config; } if(!is_object($_preferences)) { - $prefs = new preferences($this->recipient->id); + $prefs = new preferences($this->recipient->account_id); $preferences = $prefs->read(); $this->preferences = (object)$preferences[self::_appname ]; } else { @@ -122,15 +121,18 @@ class notification_popup implements iface_notification { * @param array $_attachments */ public function send( $_subject = false, $_messages, $_attachments = false) { + if(!is_object($this->sender)) { + throw new Exception("No sender given."); + } $sessions = $GLOBALS['egw']->session->list_sessions(0, 'asc', 'session_dla', true); $user_sessions = array(); foreach ($sessions as $session) { - if ($session['session_lid'] == $this->recipient->lid. '@'. $GLOBALS['egw_info']['user']['domain']) { + if ($session['session_lid'] == $this->recipient->account_lid. '@'. $GLOBALS['egw_info']['user']['domain']) { $user_sessions[] = $session['session_id']; } } - if ( empty($user_sessions) ) throw new Exception("User {$this->recipient->lid} isn't online. Can't send notification via popup"); - $this->save( $_messages['html']['text'].$_messages['html']['link_jspopup'], $user_sessions ); + if ( empty($user_sessions) ) throw new Exception("User {$this->recipient->account_lid} isn't online. Can't send notification via popup"); + $this->save( $_messages['html']['info_sender'].$_messages['html']['info_subject'].$_messages['html']['text'].$_messages['html']['link_jspopup'], $user_sessions ); } /** @@ -145,7 +147,7 @@ class notification_popup implements iface_notification { $message = ''; $this->db->select(self::_notification_table, '*', array( - 'account_id' => $this->recipient->id, + 'account_id' => $this->recipient->account_id, 'session_id' => $session_id, ), __LINE__,__FILE__); @@ -161,7 +163,7 @@ class notification_popup implements iface_notification { } } $myval=$this->db->delete(self::_notification_table,array( - 'account_id' => $this->recipient->id, + 'account_id' => $this->recipient->account_id, 'session_id' => $session_id, ),__LINE__,__FILE__); @@ -199,7 +201,7 @@ class notification_popup implements iface_notification { private function save( $_message, array $_user_sessions ) { foreach ($_user_sessions as $user_session) { $result =& $this->db->insert( self::_notification_table, array( - 'account_id' => $this->recipient->id, + 'account_id' => $this->recipient->account_id, 'session_id' => $user_session, 'message' => $_message ), false,__LINE__,__FILE__); diff --git a/notifications/inc/class.notification_winpopup.inc.php b/notifications/inc/class.notification_winpopup.inc.php index e7df713e91..ece13a993d 100644 --- a/notifications/inc/class.notification_winpopup.inc.php +++ b/notifications/inc/class.notification_winpopup.inc.php @@ -85,14 +85,12 @@ class notification_winpopup implements iface_notification { // otherwise we have to fetch this objects for current user. if (!is_object($_sender)) { $this->sender = (object) $GLOBALS['egw']->accounts->read($_sender); - $this->sender->id =& $this->sender->account_id; } else { $this->sender = $_sender; } if (!is_object($_recipient)) { $this->recipient = (object) $GLOBALS['egw']->accounts->read($_recipient); - $this->recipient->id =& $this->recipient->account_id; } else { $this->recipient = $_recipient; @@ -104,7 +102,7 @@ class notification_winpopup implements iface_notification { $this->config = $_config; } if(!is_object($_preferences)) { - $prefs = new preferences($this->recipient->id); + $prefs = new preferences($this->recipient->account_id); $preferences = $prefs->read(); $this->preferences = (object)$preferences[self::_appname ]; } else { @@ -125,19 +123,22 @@ class notification_winpopup implements iface_notification { 'Please check var "netbios_command" in winpopup backend '. '('.EGW_INCLUDE_ROOT. SEP. self::_appname. SEP. 'inc'. SEP. 'class.notification_winpopup.inc.php).'); } + if(!is_object($this->sender)) { + throw new Exception("No sender given."); + } $sessions = $GLOBALS['egw']->session->list_sessions(0, 'asc', 'session_dla', true); $user_sessions = array(); foreach ($sessions as $session) { - if ($session['session_lid'] == $this->recipient->lid. '@'. $GLOBALS['egw_info']['user']['domain']) { + if ($session['session_lid'] == $this->recipient->account_lid. '@'. $GLOBALS['egw_info']['user']['domain']) { if($this->valid_ip($session['session_ip'])) { $user_sessions[] = $session['session_ip']; } } } - if ( empty($user_sessions) ) throw new Exception("User #{$this->recipient->id} isn't online. Can't send notification via winpopup"); + if ( empty($user_sessions) ) throw new Exception("User #{$this->recipient->account_id} isn't online. Can't send notification via winpopup"); - $this->send_winpopup( $_messages['plain']['text'], $user_sessions ); + $this->send_winpopup( $_messages['plain']['info_subject'].$_messages['plain']['text'], $user_sessions ); return true; } @@ -161,7 +162,7 @@ class notification_winpopup implements iface_notification { '/\[3\]/' => $ip_octets[2], '/\[4\]/' => $ip_octets[3], '/\[IP\]/' => $user_session, - '/\[SENDER\]/' => $GLOBALS['egw']->accounts->id2name($this->sender->id,'account_fullname'), + '/\[SENDER\]/' => $this->sender->account_fullname ? $this->sender->account_fullname : $this->sender->account_email, ); $command = preg_replace(array_keys($placeholders), $placeholders, $this->netbios_command); exec($command,$output,$returncode);