mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-11-07 08:34:42 +01:00
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