forked from extern/egroupware
enabled class autoloading for notifications, let admins enable or disable notification backends, security fixes for email and egwpopup backend, unified link arrays used for notifications
This commit is contained in:
parent
e657227035
commit
5b699573e4
@ -605,9 +605,8 @@ class bocalupdate extends bocal
|
||||
}
|
||||
// send via notification_app
|
||||
if($GLOBALS['egw_info']['apps']['notifications']['enabled']) {
|
||||
require_once(EGW_INCLUDE_ROOT. '/notifications/inc/class.notification.inc.php');
|
||||
try {
|
||||
$notification = new notification();
|
||||
$notification = new notifications();
|
||||
$notification->set_receivers(array($userid));
|
||||
$notification->set_message($body);
|
||||
$notification->set_sender($senderid);
|
||||
@ -621,7 +620,7 @@ class bocalupdate extends bocal
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
error_log('calendar: cannot send any notifications because notification-app is not installed');
|
||||
error_log('calendar: cannot send any notifications because notifications is not installed');
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -869,13 +868,15 @@ class bocalupdate extends bocal
|
||||
/* this is needed for notification-app
|
||||
* notification-app creates the link individual for
|
||||
* every user, so we must provide a neutral link-style
|
||||
* if calendar implements tracking in near future, this part can be deleted
|
||||
*/
|
||||
$link_arr = array();
|
||||
$link_arr['menuaction'] = 'calendar.uiforms.edit';
|
||||
$link_arr['params'] = array( 'cal_id' => $event['id'],
|
||||
'date' => $eventStart_arr['full'],
|
||||
);
|
||||
$link_arr['text'] = $event['title'];
|
||||
$link_arr['view'] = array( 'menuaction' => 'calendar.uiforms.edit',
|
||||
'cal_id' => $event['id'],
|
||||
'date' => $eventStart_arr['full'],
|
||||
);
|
||||
$link_arr['popup'] = '750x400';
|
||||
$details['link_arr'] = $link_arr;
|
||||
|
||||
$dis = array();
|
||||
|
@ -22,7 +22,7 @@ require_once(EGW_API_INC.'/class.html.inc.php');
|
||||
* 1. set the required class-vars: app, id_field
|
||||
* 2. optional set class-vars: creator_field, assigned_field, check2prefs
|
||||
* 3. implement the required methods: get_config, get_details
|
||||
* 4. optionally re-implement: get_subject, get_body, get_attachments, get_link, get_message
|
||||
* 4. optionally re-implement: get_title, get_subject, get_body, get_attachments, get_link, get_notification_link, get_message
|
||||
* They are all documented in this file via phpDocumentor comments.
|
||||
*/
|
||||
class bo_tracking
|
||||
@ -370,16 +370,14 @@ class bo_tracking
|
||||
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 = new notifications();
|
||||
$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_message($this->get_body(false,$data,$old,false)); // set message as plaintext
|
||||
$notification->set_message($this->get_body(true,$data,$old,false)); // and html
|
||||
$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)));
|
||||
$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();
|
||||
@ -389,7 +387,7 @@ class bo_tracking
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
error_log('tracking: cannot send any notifications because notification-app is not installed');
|
||||
error_log('tracking: cannot send any notifications because notifications is not installed');
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -450,6 +448,23 @@ class bo_tracking
|
||||
//echo "<p>bo_tracking::get_sender()='".htmlspecialchars($sender)."'</p>\n";
|
||||
return $sender;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the title for a given entry, can be reimplemented
|
||||
*
|
||||
* @param array $data
|
||||
* @param array $old
|
||||
* @return string
|
||||
*/
|
||||
function get_title($data,$old)
|
||||
{
|
||||
if (!is_object($GLOBALS['egw']->link))
|
||||
{
|
||||
require_once(EGW_API_INC.'/class.bolink.inc.php');
|
||||
$GLOBALS['egw']->link =& new bolink();
|
||||
}
|
||||
return $GLOBALS['egw']->link->title($this->app,$data[$this->id_field]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the subject for a given entry, can be reimplemented
|
||||
@ -532,7 +547,7 @@ class bo_tracking
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a link for notifications to view the entry
|
||||
* Get a link for notifications to view the entry, can be reimplemented
|
||||
*
|
||||
* @param array $data
|
||||
* @param array $old
|
||||
@ -542,21 +557,16 @@ class bo_tracking
|
||||
{
|
||||
if (!is_object($GLOBALS['egw']->link))
|
||||
{
|
||||
require_once(EGW_API_INC.'/class.bolink.inc.php');
|
||||
$GLOBALS['egw']->link =& new bolink();
|
||||
$GLOBALS['egw']->link = new bolink();
|
||||
}
|
||||
if($view = $GLOBALS['egw']->link->view($this->app,$data[$this->id_field])) {
|
||||
return array( 'menuaction' => $view['menuaction'],
|
||||
'params' => array ( 'action' => $view['action'],
|
||||
'action_id' => $view['action_id'],
|
||||
),
|
||||
'text' => $data['info_subject'],
|
||||
return array( 'text' => $this->get_title($data,$old),
|
||||
'view' => $view,
|
||||
'popup' => $GLOBALS['egw']->link->is_popup($this->app,'view'),
|
||||
);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the body of the notification message, can be reimplemented
|
||||
@ -564,9 +574,10 @@ class bo_tracking
|
||||
* @param boolean $html_email
|
||||
* @param array $data
|
||||
* @param array $old
|
||||
* @param boolean $integrate_link to have links embedded inside the body
|
||||
* @return string
|
||||
*/
|
||||
function get_body($html_email,$data,$old)
|
||||
function get_body($html_email,$data,$old,$integrate_link = true)
|
||||
{
|
||||
$body = '';
|
||||
if ($html_email)
|
||||
@ -578,7 +589,7 @@ class bo_tracking
|
||||
{
|
||||
$body .= $this->format_line($html_email,'message',false,$message);
|
||||
}
|
||||
if (($link = $this->get_link($data,$old)))
|
||||
if ($integrate_link && ($link = $this->get_link($data,$old)))
|
||||
{
|
||||
$body .= $this->format_line($html_email,'link',false,lang('You can respond by visiting:'),$link);
|
||||
}
|
||||
@ -621,7 +632,7 @@ class bo_tracking
|
||||
if (!$this->html_content_allow) $line = $this->html->htmlspecialchars($line); // XSS
|
||||
|
||||
$color = $modified ? 'red' : false;
|
||||
$size = '120%';
|
||||
$size = '110%';
|
||||
$bold = false;
|
||||
$background = '#FFFFF1';
|
||||
switch($type)
|
||||
@ -686,7 +697,7 @@ class bo_tracking
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attachments for a notification mail
|
||||
* Get the attachments for a notification
|
||||
*
|
||||
* @param array $data
|
||||
* @param array $old
|
||||
|
@ -20,11 +20,11 @@ require_once(EGW_INCLUDE_ROOT.'/phpgwapi/inc/class.config.inc.php');
|
||||
* This class takes care about the notification-routing. It chooses one or more backends for each
|
||||
* given recipient depending on its prefs or falls back to self::_fallback
|
||||
*
|
||||
* The classes doing the notifications are called notification_<backend> and should only be
|
||||
* The classes doing the notifications are called notifications_<backend> and should only be
|
||||
* called from this class. The backend's job is to deliver ONE message to ONE recipient.
|
||||
*
|
||||
*/
|
||||
final class notification {
|
||||
final class notifications {
|
||||
|
||||
/**
|
||||
* Appname
|
||||
@ -36,29 +36,58 @@ final class notification {
|
||||
*/
|
||||
const _fallback = 'email_only';
|
||||
|
||||
/**
|
||||
* registered backends
|
||||
* @var array
|
||||
*/
|
||||
private $backends = array('popup', 'winpopup', 'email');
|
||||
|
||||
/**
|
||||
* pre-defined notificaton chains
|
||||
* @abstract
|
||||
* arrays with name => chain pairs
|
||||
* the chain itself consists of an array with framework => action pairs
|
||||
* where action defines what to do after the framework has been executed:
|
||||
* stop: stop executing notifications
|
||||
* fail: do not stop if framework fails, otherwise stop
|
||||
* continue: execute next framework
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
* pre-defined notificaton chains
|
||||
* @abstract
|
||||
* arrays with name => chain pairs
|
||||
* the chain itself consists of an array with framework => action pairs
|
||||
* where action defines what to do after the framework has been executed:
|
||||
* stop: stop executing notifications
|
||||
* fail: do not stop if framework fails, otherwise stop
|
||||
* continue: execute next framework
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $notification_chains = array(
|
||||
'disable' => false,
|
||||
'popup_only' => array('popup' => 'stop'),
|
||||
'winpopup_only' => array('winpopup' => 'stop'),
|
||||
'email_only' => array('email' => 'stop'),
|
||||
'popup_or_email' => array('popup' => 'fail', 'email' => 'stop'),
|
||||
'winpopup_or_email' => array('winpopup' => 'fail', 'email' => 'stop'),
|
||||
'popup_and_email' => array('popup' => 'continue', 'email' => 'stop'),
|
||||
'winpopup_and_email' => array('winpopup' => 'continue', 'email' => 'stop'),
|
||||
'egwpopup_and_winpopup' => array('popup' => 'continue', 'winpopup' => 'stop'),
|
||||
'all' => array('popup' => 'continue', 'winpopup' => 'continue', 'email' => 'stop'),
|
||||
'disable' => false, // will be created by $this->get_available_chains
|
||||
'email_only' => false, // will be created by $this->get_available_chains
|
||||
'all' => false, // will be created by $this->get_available_chains
|
||||
'popup_only' => array('popup' => 'stop'),
|
||||
'popup_or_email' => array('popup' => 'fail', 'email' => 'stop'),
|
||||
//'popup_or_sms' => array('popup' => 'fail', 'sms' => 'stop'),
|
||||
'popup_and_email' => array('popup' => 'continue', 'email' => 'stop'),
|
||||
'popup_and_winpopup' => array('popup' => 'continue', 'winpopup' => 'stop'),
|
||||
'winpopup_only' => array('winpopup' => 'stop'),
|
||||
'winpopup_or_email' => array('winpopup' => 'fail', 'email' => 'stop'),
|
||||
//'winpopup_or_sms' => array('winpopup' => 'fail', 'sms' => 'stop'),
|
||||
'winpopup_and_email' => array('winpopup' => 'continue', 'email' => 'stop'),
|
||||
//'sms_only' => array('sms' => 'stop'),
|
||||
);
|
||||
|
||||
/**
|
||||
* human readable descriptions for the notification chains
|
||||
* @var array
|
||||
*/
|
||||
private $chains_descriptions = array(
|
||||
'disable' => 'do not notify me at all',
|
||||
'email_only' => 'E-Mail only',
|
||||
'all' => 'all possible notification backends',
|
||||
'popup_only' => 'eGroupWare-Popup only',
|
||||
'popup_or_email' => 'eGroupWare-Popup first, if that fails notify me by E-Mail',
|
||||
//'popup_or_sms' => 'eGroupware-Popup first, if that fails notify me by SMS',
|
||||
'popup_and_email' => 'eGroupWare-Popup and E-Mail',
|
||||
'popup_and_winpopup' => 'eGroupWare-Popup and Windows-Popup',
|
||||
'winpopup_only' => 'Windows-Popup only',
|
||||
'winpopup_or_email' => 'Windows-Popup first, if that fails notify me by E-Mail',
|
||||
//'winpopup_or_sms' => 'Windows-Popup first, if that fails notify me by SMS',
|
||||
'winpopup_and_email' => 'Windows-Popup and E-Mail',
|
||||
//'sms_only' => 'SMS only',
|
||||
);
|
||||
|
||||
/**
|
||||
@ -111,7 +140,7 @@ final class notification {
|
||||
private $config;
|
||||
|
||||
/**
|
||||
* constructor of notification
|
||||
* constructor of notifications
|
||||
*
|
||||
*/
|
||||
public function __construct() {
|
||||
@ -221,13 +250,13 @@ final class notification {
|
||||
/**
|
||||
* sets the notification links
|
||||
*
|
||||
* @param array $links link array (like defined in $this->add_link)
|
||||
* @param array $_links link array (like defined in $this->add_link)
|
||||
*/
|
||||
public function set_links(array $_links) {
|
||||
$this->links = array(); // clear array if set
|
||||
foreach($_links as $link) {
|
||||
if(is_array($link)) {
|
||||
$this->add_link($link['menuaction'], $link['params'], $link['text']);
|
||||
$this->add_link($link['text'], $link['view'], $link['popup']);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@ -235,16 +264,16 @@ final class notification {
|
||||
|
||||
/**
|
||||
* adds a notification link
|
||||
*
|
||||
* @param string $menuaction egw menuaction (appname.classname.functionname)
|
||||
* @param array $params params to append (name => value pairs)
|
||||
* @param string $text a descriptive text for the link
|
||||
*
|
||||
* @param string $_text a descriptive text for the link
|
||||
* @param array $_view all params needed to view the link (name => value pairs)
|
||||
* @param string $_popup if link can be viewed in a popup something like '300x200' otherwise false
|
||||
*/
|
||||
public function add_link($_menuaction, $_params, $_text) {
|
||||
if(!$_menuaction || !$_params || !$_text) { return false; }
|
||||
$this->links[] = (object)array( 'menuaction' => $_menuaction,
|
||||
'params' => $_params,
|
||||
'text' => $_text,
|
||||
public function add_link($_text, $_view, $_popup = false) {
|
||||
if(!$_view || !$_text) { return false; }
|
||||
$this->links[] = (object)array( 'text' => $_text,
|
||||
'view' => $_view,
|
||||
'popup' => $_popup,
|
||||
);
|
||||
return true;
|
||||
}
|
||||
@ -252,7 +281,7 @@ final class notification {
|
||||
/**
|
||||
* sets the notification attachments
|
||||
*
|
||||
* @param array $attachments attachment array (like defined in $this->add_attachment
|
||||
* @param array $_attachments attachment array (like defined in $this->add_attachment)
|
||||
*/
|
||||
public function set_attachments(array $_attachments) {
|
||||
$this->attachments = array(); // clear array if set
|
||||
@ -273,10 +302,10 @@ final class notification {
|
||||
* This method can be used to attach ascii or binary data,
|
||||
* such as a BLOB record from a database.
|
||||
*
|
||||
* @param string $string Attachment data.
|
||||
* @param string $filename Name of the attachment.
|
||||
* @param string $encoding File encoding (see $Encoding).
|
||||
* @param string $type File extension (MIME) type.
|
||||
* @param string $_string Attachment data.
|
||||
* @param string $_filename Name of the attachment.
|
||||
* @param string $_encoding File encoding (see $Encoding).
|
||||
* @param string $_type File extension (MIME) type.
|
||||
*/
|
||||
public function add_attachment($_string, $_filename, $_encoding = "base64", $_type = "application/octet-stream") {
|
||||
if(!$_string || !$_filename) { return false; }
|
||||
@ -289,20 +318,24 @@ final class notification {
|
||||
}
|
||||
|
||||
/**
|
||||
* sends notification
|
||||
* sends notifications
|
||||
*/
|
||||
public function send() {
|
||||
if (!is_object($this->sender)) {
|
||||
throw new Exception('Error: cannot send notification. No sender supplied');
|
||||
throw new Exception('Error: cannot send notifications. No sender supplied');
|
||||
}
|
||||
if (!is_array($this->receivers) || count($this->receivers) == 0) {
|
||||
throw new Exception('Error: cannot send notification. No receivers supplied');
|
||||
throw new Exception('Error: cannot send notifications. No receivers supplied');
|
||||
}
|
||||
if(!$messages = $this->create_messages($this->message_plain, $this->message_html)) {
|
||||
throw new Exception('Error: cannot send notification. No valid messages supplied');
|
||||
throw new Exception('Error: cannot send notifications. No valid messages supplied');
|
||||
}
|
||||
|
||||
$available_chains = $this->get_available_chains('routing');
|
||||
|
||||
foreach ($this->receivers as $receiver) {
|
||||
$user_notified = false;
|
||||
$prepend_message = '';
|
||||
$backend_errors = array();
|
||||
try {
|
||||
// system or non-system user
|
||||
@ -318,37 +351,42 @@ final class notification {
|
||||
$preferences = $prefs->read();
|
||||
$preferences = (object)$preferences[self::_appname];
|
||||
if($preferences->notification_chain) {
|
||||
$notification_chain = $this->notification_chains[$preferences->notification_chain];
|
||||
// fallback: admin disabled user-chosen chain
|
||||
if(!$notification_chain = $available_chains[$preferences->notification_chain]) {
|
||||
$prepend_message .= lang( 'This eGroupWare notification has been sent to you by mail because your'
|
||||
.' chosen notification-chain has been disabled by the administrator.'
|
||||
.' Please choose another notification-chain in your preferences!');
|
||||
$notification_chain = $available_chains[self::_fallback];
|
||||
}
|
||||
} else {
|
||||
$notification_chain = $this->notification_chains[self::_fallback]; // fallback: no prefs
|
||||
$notification_chain = $available_chains[self::_fallback]; // fallback: no prefs
|
||||
}
|
||||
} else {
|
||||
$notification_chain = $this->notification_chains[self::_fallback]; // fallback: no rights to app
|
||||
$notification_chain = $available_chains[self::_fallback]; // fallback: no rights to app
|
||||
}
|
||||
} else {
|
||||
// non-system user
|
||||
$receiver->handle = $receiver->account_email;
|
||||
$notification_chain = $this->notification_chains[self::_fallback]; // fallback: non-system user
|
||||
$notification_chain = $available_chains[self::_fallback]; // fallback: non-system user
|
||||
}
|
||||
|
||||
if($notification_chain === false) {
|
||||
if($notification_chain == 'disable') {
|
||||
continue; //user disabled notifications
|
||||
}
|
||||
|
||||
foreach($notification_chain as $notification_backend => $action) {
|
||||
try {
|
||||
$notification_backend = 'notification_'.$notification_backend;
|
||||
$notification_backend = self::_appname.'_'.$notification_backend;
|
||||
if(!file_exists(EGW_INCLUDE_ROOT. SEP. self::_appname. SEP. 'inc'. SEP. 'class.'. $notification_backend. '.inc.php')) {
|
||||
throw new Exception('file for '.$notification_backend. ' does not exist');
|
||||
}
|
||||
require_once(EGW_INCLUDE_ROOT. SEP. self::_appname. SEP. 'inc'. SEP. 'class.'. $notification_backend. '.inc.php');
|
||||
$obj = @new $notification_backend( $this->sender, $receiver, $this->config, $preferences );
|
||||
if ( !is_a( $obj, iface_notification )) {
|
||||
$obj = new $notification_backend( $this->sender, $receiver, $this->config, $preferences );
|
||||
if ( !($obj instanceof notifications_iface) ) {
|
||||
unset ( $obj );
|
||||
throw new Exception($notification_backend. ' is no implementation of iface_notification');
|
||||
throw new Exception($notification_backend. ' is no implementation of notifications_iface');
|
||||
}
|
||||
|
||||
$obj->send($messages, $this->subject, $this->links, $this->attachments);
|
||||
$obj->send($this->prepend_message($messages, $prepend_message), $this->subject, $this->links, $this->attachments);
|
||||
}
|
||||
catch (Exception $exception) {
|
||||
$backend_errors[] = $notification_backend.' failed: '.$exception->getMessage();
|
||||
@ -378,18 +416,15 @@ final class notification {
|
||||
}
|
||||
|
||||
/**
|
||||
* this function creates an array with the message as plaintext and html
|
||||
* creates an array with the message as plaintext and html
|
||||
*
|
||||
* @param string $message_plain
|
||||
* @param string $message_html
|
||||
* @param array $links
|
||||
* @return array $messages
|
||||
* @param string $_message_plain
|
||||
* @param string $_message_html
|
||||
* @return plain and html message in one array, $messages['plain'] and $messages['html']
|
||||
*/
|
||||
private function create_messages($_message_plain = '', $_message_html = '') {
|
||||
if(empty($_message_plain) && empty($_message_html)) { return false; } // no message set
|
||||
$messages = array();
|
||||
$messages['plain'] = array();
|
||||
$messages['html'] = array();
|
||||
|
||||
// create the messages
|
||||
if(!empty($_message_plain)) {
|
||||
@ -407,6 +442,33 @@ final class notification {
|
||||
return $messages;
|
||||
}
|
||||
|
||||
/**
|
||||
* prepends another message to the messages array
|
||||
*
|
||||
* @param array $_messages the messages array from create_messages()
|
||||
* @param string $_prepend just a plain message to prepend, no html!
|
||||
* @return plain and html message in one array including the prepended message, $messages['plain'] and $messages['html']
|
||||
*/
|
||||
private function prepend_message(array $_messages, $_prepend = null) {
|
||||
if(strlen($_prepend) > 0) {
|
||||
foreach($_messages as $key => $value) {
|
||||
switch($key) {
|
||||
case 'plain':
|
||||
$_messages[$key] = $_prepend."\n\n".$value;
|
||||
break;
|
||||
case 'html':
|
||||
// ToDo: move stylesheet to a nicer place
|
||||
$_messages[$key] = '<div style="margin:0; padding:1em; margin-bottom: 1em; background-color:orange; border:1px solid red;">'.$_prepend.'</div>'.$value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $_messages;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns specified part from a given mailaddress
|
||||
*
|
||||
@ -434,5 +496,99 @@ final class notification {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* returns notification chains based on admin prefs
|
||||
* @abstract the available chains can be retrieved in two different output formats:
|
||||
* routing: array with common and enabled chains, chain-name as key and the chain-array as value (used for message-routing)
|
||||
* human: array with common, enabled and disabled chains, chain-name as key and a human-readable description as value (used for config)
|
||||
*
|
||||
* @param string $_output one of: 'routing' or 'human', defaults to 'routing'
|
||||
* @return array containing notification chains, output like given in $_output
|
||||
*/
|
||||
public function get_available_chains($_output = 'routing') {
|
||||
// determine enabled backends from config
|
||||
$enabled_backends = array();
|
||||
foreach($this->backends as $id => $backend) {
|
||||
switch($backend) {
|
||||
case 'email':
|
||||
$enabled_backends[$backend] = true; // fallback must always be enabled
|
||||
break;
|
||||
default:
|
||||
$param = $backend.'_enable';
|
||||
$enabled_backends[$backend] = $this->config->{$param} == true ? true : false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$enabled_chains = array();
|
||||
$disabled_chains = array();
|
||||
foreach($this->notification_chains as $key => $chain) {
|
||||
$allow_chain = true;
|
||||
if(is_array($chain)) {
|
||||
foreach($chain as $name => $action) {
|
||||
if(!$enabled_backends[$name]) {
|
||||
$allow_chain = false; // disable whole chain if one backend is disabled
|
||||
}
|
||||
}
|
||||
if($allow_chain) {
|
||||
$enabled_chains[$key] = $chain;
|
||||
} else {
|
||||
$disabled_chains[$key] = $chain;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// common chain
|
||||
$common_chains = array();
|
||||
$common_chains['disable'] = 'disable';
|
||||
$common_chains['email_only'] = array('email' => 'stop');
|
||||
// create the 'all' chain from the enabled backends
|
||||
$chain_all = array();
|
||||
$backend_count = 1;
|
||||
foreach($enabled_backends as $backend => $enabled) {
|
||||
if($enabled) {
|
||||
$chain_all[$backend] = count($enabled_backends) == $backend_count ? 'stop' : 'continue';
|
||||
}
|
||||
$backend_count++;
|
||||
}
|
||||
$common_chains['all'] = $chain_all;
|
||||
|
||||
switch($_output) {
|
||||
case 'human':
|
||||
$chain_groups = array(
|
||||
lang('Common chains') => 'common_chains',
|
||||
lang('Enabled chains') => 'enabled_chains',
|
||||
lang('Disabled chains') => 'disabled_chains',
|
||||
);
|
||||
$suffix = '_human';
|
||||
// create descriptions for each chain key in each group
|
||||
foreach($chain_groups as $name => $arr_name) {
|
||||
${$arr_name.$suffix} = array();
|
||||
foreach(${$arr_name} as $key => $value) {
|
||||
if($arr_name == 'disabled_chains') {
|
||||
${$arr_name.$suffix}[$key] = '('.lang('Disabled').') '.lang($this->chains_descriptions[$key]);
|
||||
} else {
|
||||
${$arr_name.$suffix}[$key] = lang($this->chains_descriptions[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
// summarize all groups with minimum one chain to the final array
|
||||
$chains_final = array();
|
||||
foreach($chain_groups as $name => $arr_name) {
|
||||
if(is_array(${$arr_name.$suffix}) && count(${$arr_name.$suffix}) > 0) {
|
||||
$chains_final[$name] = ${$arr_name.$suffix};
|
||||
}
|
||||
}
|
||||
return $chains_final;
|
||||
break;
|
||||
|
||||
case 'routing':
|
||||
default:
|
||||
return array_merge($common_chains, $enabled_chains);
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
@ -9,14 +9,10 @@
|
||||
* @author Christian Binder <christian@jaytraxx.de>
|
||||
*/
|
||||
|
||||
require_once('class.iface_notification.inc.php');
|
||||
require_once(EGW_INCLUDE_ROOT.'/phpgwapi/inc/class.html.inc.php');
|
||||
require_once(EGW_INCLUDE_ROOT. '/phpgwapi/inc/class.send.inc.php');
|
||||
|
||||
/**
|
||||
* User notification via email.
|
||||
*/
|
||||
class notification_email implements iface_notification {
|
||||
class notifications_email implements notifications_iface {
|
||||
|
||||
/**
|
||||
* Appname
|
||||
@ -66,7 +62,7 @@ class notification_email implements iface_notification {
|
||||
private $html;
|
||||
|
||||
/**
|
||||
* constructor of notification_email
|
||||
* constructor of notifications_email
|
||||
*
|
||||
* @param object $_sender
|
||||
* @param object $_recipient
|
||||
@ -84,7 +80,7 @@ class notification_email implements iface_notification {
|
||||
{
|
||||
$this->mail = new send();
|
||||
}
|
||||
$this->html = & html::singleton();
|
||||
$this->html = html::singleton();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -97,7 +93,7 @@ class notification_email implements iface_notification {
|
||||
*/
|
||||
public function send(array $_messages, $_subject = false, $_links = false, $_attachments = false) {
|
||||
$body_plain = $_messages['plain'].$this->render_links($_links, false, $this->preferences->external_mailclient);
|
||||
$body_html = "<html>\n<body>\n".$_messages['html'].$this->render_links($_links, true, $this->preferences->external_mailclient)."</body>\n</html>\n";
|
||||
$body_html = "<html><body>\n".$_messages['html'].$this->render_links($_links, true, $this->preferences->external_mailclient)."</body>\n</html>\n";
|
||||
|
||||
$this->mail->ClearAddresses();
|
||||
$this->mail->ClearAttachments();
|
||||
@ -118,7 +114,7 @@ class notification_email implements iface_notification {
|
||||
throw new Exception("Failed sending notification message via email.$error");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* renders plaintext/html links from given link array
|
||||
*
|
||||
@ -134,18 +130,24 @@ class notification_email implements iface_notification {
|
||||
// php distinguishes between missing and present(null) arguments
|
||||
if(is_null($_render_html)) { $_render_html = false; }
|
||||
if(is_null($_render_external)) { $_render_external = true; }
|
||||
$newline = $_render_html ? "<br />" : "\n";
|
||||
$hruler = $_render_html ? $this->html->hr() : '';
|
||||
|
||||
$newline = $_render_html ? "<br />" : "\n";
|
||||
$link_array = array();
|
||||
$rendered_links = array();
|
||||
foreach($_links as $link) {
|
||||
if($_render_external) {
|
||||
$link->params['no_popup'] = 1;
|
||||
if($_render_external || ! $link->popup) { $link->view['no_popup'] = 1; }
|
||||
$url = $this->html->link('/index.php', $link->view);
|
||||
// do not expose sensitive data
|
||||
$url = preg_replace('/(sessionid|kp3|domain)=[^&]+&?/','',$url);
|
||||
// complete missing protocol and domain part if needed
|
||||
if ($url{0} == '/' && $_render_external) {
|
||||
$url = ($_SERVER['HTTPS'] || $GLOBALS['egw_info']['server']['enforce_ssl'] ? 'https://' : 'http://').
|
||||
($GLOBALS['egw_info']['server']['hostname'] ? $GLOBALS['egw_info']['server']['hostname'] : $_SERVER['HTTP_HOST']).$url;
|
||||
}
|
||||
$url = $this->html->link('/index.php?menuaction='.$link->menuaction, $link->params);
|
||||
$link_array[] = $_render_html ? $this->html->a_href($link->text, $url) : $url;
|
||||
$rendered_links[] = $_render_html ? $this->html->a_href($link->text, $url, false, 'target="_blank"') : $url;
|
||||
}
|
||||
|
||||
return lang('Linked entries:').$newline.implode($newline,$link_array);
|
||||
return $hruler.$newline.lang('Linked entries:').$newline.implode($newline,$rendered_links);
|
||||
}
|
||||
|
||||
}
|
@ -12,7 +12,7 @@
|
||||
/**
|
||||
* Instant user notification
|
||||
*/
|
||||
interface iface_notification {
|
||||
interface notifications_iface {
|
||||
|
||||
/**
|
||||
* constructor
|
||||
@ -25,7 +25,7 @@ interface iface_notification {
|
||||
public function __construct($_sender, $_recipient, $_config = null, $_preferences = null);
|
||||
|
||||
/**
|
||||
* sends notification
|
||||
* sends one notification to one recipient
|
||||
*
|
||||
* @abstract NOTE, $_messages is an array that contains
|
||||
* the notification message in plain and html
|
@ -6,25 +6,31 @@
|
||||
* @package notifications
|
||||
* @subpackage backends
|
||||
* @link http://www.egroupware.org
|
||||
* @author Cornelius Weiss <nelius@cwtech.de>
|
||||
* @author Cornelius Weiss <nelius@cwtech.de>, Christian Binder <christian@jaytraxx.de>
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
require_once('class.iface_notification.inc.php');
|
||||
require_once(EGW_INCLUDE_ROOT.'/phpgwapi/inc/class.html.inc.php');
|
||||
|
||||
/**
|
||||
* Instant user notification with egroupware popup.
|
||||
*
|
||||
* @abstract egwpopup is a two stage notification. In the first stage
|
||||
* notification is written into self::_notification_egwpopup
|
||||
* table. In the second stage a request from the client reads
|
||||
* notification is written into self::_notification_table.
|
||||
* In the second stage a request from the client reads
|
||||
* out the table to look if there is a notificaton for this
|
||||
* client. The second stage is done in class.ajaxnotifications.inc.php
|
||||
*
|
||||
* Todo:
|
||||
* - save the messages by uid instead of sessionid into the notification table, this
|
||||
* has several advantages (users poll the messages via ajax from multiple logins, and
|
||||
* do not have to read one message twice, poll after re-login with different sessionid)
|
||||
* - delete message from the table only if the user has really seen it
|
||||
* - if the above things are done we should get rid of rendering the links here,
|
||||
* instead it should be done by the ajax class, so sessionids in links could be possible then
|
||||
*
|
||||
* (multidisplay is supported)
|
||||
*
|
||||
*/
|
||||
class notification_popup implements iface_notification {
|
||||
class notifications_popup implements notifications_iface {
|
||||
|
||||
/**
|
||||
* Appname
|
||||
@ -79,7 +85,7 @@ class notification_popup implements iface_notification {
|
||||
private $html;
|
||||
|
||||
/**
|
||||
* constructor of notification_egwpopup
|
||||
* constructor of notifications_egwpopup
|
||||
*
|
||||
* @param object $_sender
|
||||
* @param object $_recipient
|
||||
@ -95,7 +101,7 @@ class notification_popup implements iface_notification {
|
||||
$this->preferences = $_preferences;
|
||||
$this->db = &$GLOBALS['egw']->db;
|
||||
$this->db->set_app( self::_appname );
|
||||
$this->html = & html::singleton();
|
||||
$this->html = html::singleton();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -126,8 +132,7 @@ class notification_popup implements iface_notification {
|
||||
}
|
||||
|
||||
/**
|
||||
* saves notification into database so that the client can fetch it from
|
||||
* there via notification->get
|
||||
* saves notification into database so that the client can fetch it from there
|
||||
*
|
||||
* @param string $_message
|
||||
* @param array $_user_sessions
|
||||
@ -145,24 +150,41 @@ class notification_popup implements iface_notification {
|
||||
|
||||
/**
|
||||
* renders plaintext/html links from given link array
|
||||
* should be moved to the ajax class later - like mentioned in the Todo
|
||||
*
|
||||
* @param array $_links
|
||||
* @return html rendered link(s) as complete string (jspopup)
|
||||
* @return html rendered link(s) as complete string with jspopup or a new window
|
||||
*/
|
||||
private function render_links($_links = false) {
|
||||
if(!is_array($_links) || count($_links) == 0) { return false; }
|
||||
$newline = "<br />";
|
||||
$newline = "<br />";
|
||||
|
||||
$link_array = array();
|
||||
$rendered_links = array();
|
||||
foreach($_links as $link) {
|
||||
$url = $this->html->link('/index.php?menuaction='.$link->menuaction, $link->params);
|
||||
$menuaction_arr = explode('.',$link->menuaction);
|
||||
$application = $menuaction_arr[0];
|
||||
$image = $application ? $this->html->image($application,'navbar',$link->text,'align="middle" style="width: 24px; margin-right: 0.5em;"') : '';
|
||||
$link_array[] = $this->html->div($image.$link->text,'onclick="'.$this->jspopup($url).'"','jspopup');
|
||||
if(!$link->popup) { $link->view['no_popup'] = 1; }
|
||||
|
||||
$url = $this->html->link('/index.php', $link->view);
|
||||
// do not expose sensitive data
|
||||
$url = preg_replace('/(sessionid|kp3|domain)=[^&]+&?/','',$url);
|
||||
// extract application-icon from menuaction
|
||||
if($link->view['menuaction']) {
|
||||
$menuaction_arr = explode('.',$link->view['menuaction']);
|
||||
$application = $menuaction_arr[0];
|
||||
$image = $application ? $this->html->image($application,'navbar',$link->text,'align="middle" style="width: 24px; margin-right: 0.5em;"') : '';
|
||||
} else {
|
||||
$image = '';
|
||||
}
|
||||
if($link->popup) {
|
||||
$dimensions = explode('x', $link->popup);
|
||||
$rendered_links[] = $this->html->div($image.$link->text,'onclick="'.$this->jspopup($url, '_blank', $dimensions[0], $dimensions[1]).'"','link');
|
||||
} else {
|
||||
$rendered_links[] = $this->html->div($this->html->a_href($image.$link->text, $url, false, 'target="_blank"'),'','link');
|
||||
}
|
||||
|
||||
}
|
||||
if(count($rendered_links) > 0) {
|
||||
return $this->html->bold(lang('Linked entries:')).$newline.implode($newline,$rendered_links);
|
||||
}
|
||||
|
||||
return $this->html->bold(lang('Linked entries:')).$newline.implode($newline,$link_array);
|
||||
}
|
||||
|
||||
/**
|
@ -9,12 +9,10 @@
|
||||
* @author Christian Binder <christian@jaytraxx.de>
|
||||
*/
|
||||
|
||||
require_once('class.iface_notification.inc.php');
|
||||
|
||||
/**
|
||||
* User notification via winpopup.
|
||||
*/
|
||||
class notification_winpopup implements iface_notification {
|
||||
class notifications_winpopup implements notifications_iface {
|
||||
|
||||
/**
|
||||
* Appname
|
||||
@ -69,10 +67,10 @@ class notification_winpopup implements iface_notification {
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $netbios_command;
|
||||
private $netbios_command = "/bin/echo [MESSAGE] >> /Users/jaytraxx/winpopup.out";
|
||||
|
||||
/**
|
||||
* constructor of notification_winpopup
|
||||
* constructor of notifications_winpopup
|
||||
*
|
||||
* @param object $_sender
|
||||
* @param object $_recipient
|
||||
@ -85,7 +83,7 @@ class notification_winpopup implements iface_notification {
|
||||
if(!$this->netbios_command) {
|
||||
throw new Exception( 'Winpopup plugin not configured yet. Skipped sending notification message. '.
|
||||
'Please check var "netbios_command" in winpopup backend '.
|
||||
'('.EGW_INCLUDE_ROOT. SEP. self::_appname. SEP. 'inc'. SEP. 'class.notification_winpopup.inc.php).');
|
||||
'('.EGW_INCLUDE_ROOT. SEP. self::_appname. SEP. 'inc'. SEP. 'class.notifications_winpopup.inc.php).');
|
||||
}
|
||||
$this->sender = $_sender;
|
||||
$this->recipient = $_recipient;
|
@ -8,9 +8,10 @@
|
||||
* @author Christian Binder <christian@jaytraxx.de>
|
||||
* @version $Id: hook_preferences.inc.php 22498 2006-09-25 10:20:46Z jaytraxx $
|
||||
*/
|
||||
|
||||
$title = $appname;
|
||||
|
||||
$file = Array( 'Site Configuration' => $GLOBALS['egw']->link('/index.php','menuaction=admin.uiconfig.index&appname=notifications'));
|
||||
display_section($appname,$title,$file);
|
||||
$file = Array( 'Site Configuration' => $GLOBALS['egw']->link('/index.php', array(
|
||||
'menuaction' => 'admin.uiconfig.index',
|
||||
'appname' => $appname,
|
||||
)));
|
||||
display_section($appname,$file);
|
||||
?>
|
||||
|
@ -8,10 +8,10 @@
|
||||
* @author Cornelius Weiss <nelius@cwtech.de>
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
$title = $appname;
|
||||
|
||||
$file = Array( 'Preferences' => $GLOBALS['egw']->link('/index.php',array('menuaction'=>'preferences.uisettings.index','appname'=>'notifications')),
|
||||
);
|
||||
display_section($appname,$title,$file);
|
||||
$file = Array( 'Preferences' => $GLOBALS['egw']->link('/index.php',array(
|
||||
'menuaction' => 'preferences.uisettings.index',
|
||||
'appname' => $appname,
|
||||
)));
|
||||
display_section($appname,$file);
|
||||
?>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* eGroupWare - Notification - Preferences
|
||||
* eGroupWare - Notifications - Preferences
|
||||
*
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
* @package notifications
|
||||
@ -8,29 +8,24 @@
|
||||
* @author Christian Binder <christian@jaytraxx.de>
|
||||
*/
|
||||
|
||||
$notification_chains = array( 'disable' => lang('do not notify me at all'),
|
||||
'popup_only' => lang('eGroupware-Popup only'),
|
||||
'winpopup_only' => lang('Windows-Popup only'),
|
||||
'email_only' => lang('E-Mail only'),
|
||||
'popup_or_email' => lang('eGroupware-Popup first, if that fails notify me by E-Mail'),
|
||||
'winpopup_or_email' => lang('Windows-Popup first, if that fails notify me by E-Mail'),
|
||||
'popup_and_email' => lang('eGroupware-Popup and E-Mail'),
|
||||
'winpopup_and_email' => lang('Windows-Popup and E-Mail'),
|
||||
'egwpopup_and_winpopup' => lang('eGroupware-Poupup and Windows-Popup'),
|
||||
'all' => lang('all possible notification extensions'),
|
||||
);
|
||||
$verbosity_values = array( 'low' => lang('low'),
|
||||
'medium' => lang('medium'),
|
||||
'high' => lang('high'),
|
||||
);
|
||||
$notifications = new notifications();
|
||||
$available_chains = $notifications->get_available_chains('human');
|
||||
|
||||
$verbosity_values = array(
|
||||
'low' => lang('low'),
|
||||
'medium' => lang('medium'),
|
||||
'high' => lang('high'),
|
||||
);
|
||||
|
||||
$GLOBALS['settings'] = array(
|
||||
'notification_chain' => array(
|
||||
'type' => 'select',
|
||||
'label' => 'Notify me by',
|
||||
'name' => 'notification_chain',
|
||||
'values' => $notification_chains,
|
||||
'help' => 'Choose a notification-chain. You will be notified over the chosen extensions.',
|
||||
'values' => $available_chains,
|
||||
'help' => 'Choose a notification-chain. You will be notified over the backends included in the chain.<br />'
|
||||
.'Note: If a notification-chain is marked as "disabled", your Administrator does not allow one or'
|
||||
.' more of the backends included in the chain and notifications falls back to "E-Mail" while notifying you.',
|
||||
'xmlrpc' => True,
|
||||
'admin' => False
|
||||
),
|
||||
|
@ -27,7 +27,7 @@ $setup_info[NOTIFICATION_APP]['maintainer'] = array(
|
||||
);
|
||||
$setup_info[NOTIFICATION_APP]['license'] = 'GPL';
|
||||
$setup_info[NOTIFICATION_APP]['description'] =
|
||||
'Instant norification of users via various channels.';
|
||||
'Instant notification of users via various channels.';
|
||||
|
||||
/* The hooks this app includes, needed for hooks registration */
|
||||
$setup_info[NOTIFICATION_APP]['hooks'][] = 'after_navbar';
|
||||
|
@ -11,9 +11,54 @@
|
||||
<!-- END header -->
|
||||
<!-- BEGIN body -->
|
||||
<tr class="th">
|
||||
<td colspan="2"> <b>{lang_Notification_backends</b>_(Preferences_for_enabling/disabling_will_follow_soon)}</td>
|
||||
<td colspan="2"> <b>{lang_eGroupware-Popup_backend}</b></td>
|
||||
</tr>
|
||||
<!-- END body -->
|
||||
<tr bgcolor="{row_on}">
|
||||
<td>{lang_Enable_eGroupWare-Popup_backend}</td>
|
||||
<td>
|
||||
<select name="newsettings[popup_enable]">
|
||||
<option value=""{selected_popup_enable_False}>{lang_No}</option>
|
||||
<option value="True"{selected_popup_enable_True}>{lang_Yes}</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="th">
|
||||
<td colspan="2"> <b>{lang_Windows-Popup_backend}</b></td>
|
||||
</tr>
|
||||
<tr bgcolor="{row_on}">
|
||||
<td>{lang_Enable_Windows-Popup_backend}</td>
|
||||
<td>
|
||||
<select name="newsettings[winpopup_enable]">
|
||||
<option value=""{selected_winpopup_enable_False}>{lang_No}</option>
|
||||
<option value="True"{selected_winpopup_enable_True}>{lang_Yes}</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- future SMS backend - currently disabled
|
||||
<tr class="th">
|
||||
<td colspan="2"> <b>{lang_SMS_backend}</b></td>
|
||||
</tr>
|
||||
<tr bgcolor="{row_on}">
|
||||
<td>{lang_Enable_SMS_backend}</td>
|
||||
<td>
|
||||
<select name="newsettings[sms_enable]">
|
||||
<option value=""{selected_sms_enable_False}>{lang_No}</option>
|
||||
<option value="True"{selected_sms_enable_True}>{lang_Yes}</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr bgcolor="{row_off}">
|
||||
<td>{lang_Maximum_SMS_messages_per_notification}</td>
|
||||
<td>
|
||||
<select name="newsettings[sms_maxmessages]">
|
||||
<option value="1">1</option>
|
||||
<option value="2">2</option>
|
||||
<option value="3">3</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
-->
|
||||
<!-- END body -->
|
||||
<!-- BEGIN footer -->
|
||||
<tr valign="bottom" style="height: 30px;">
|
||||
<td colspan="2" align="center">
|
||||
|
@ -463,7 +463,7 @@ Preferences tabs
|
||||
*/
|
||||
#notificationwindow_message > table
|
||||
{
|
||||
font-size: 90%;
|
||||
font-size: 95%;
|
||||
}
|
||||
|
||||
#notificationwindow_message hr
|
||||
@ -473,7 +473,7 @@ Preferences tabs
|
||||
height: 1px;
|
||||
}
|
||||
|
||||
#notificationwindow_message .jspopup
|
||||
#notificationwindow_message .link
|
||||
{
|
||||
cursor: pointer;
|
||||
}
|
||||
|
@ -722,7 +722,7 @@ body {
|
||||
*/
|
||||
#notificationwindow_message > table
|
||||
{
|
||||
font-size: 90%;
|
||||
font-size: 95%;
|
||||
}
|
||||
|
||||
#notificationwindow_message hr
|
||||
@ -732,7 +732,7 @@ body {
|
||||
height: 1px;
|
||||
}
|
||||
|
||||
#notificationwindow_message .jspopup
|
||||
#notificationwindow_message .link
|
||||
{
|
||||
cursor: pointer;
|
||||
}
|
||||
|
@ -646,7 +646,7 @@ body {
|
||||
*/
|
||||
#notificationwindow_message > table
|
||||
{
|
||||
font-size: 90%;
|
||||
font-size: 95%;
|
||||
}
|
||||
|
||||
#notificationwindow_message hr
|
||||
@ -656,7 +656,7 @@ body {
|
||||
height: 1px;
|
||||
}
|
||||
|
||||
#notificationwindow_message .jspopup
|
||||
#notificationwindow_message .link
|
||||
{
|
||||
cursor: pointer;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user