mirror of
https://github.com/EGroupware/egroupware.git
synced 2025-06-26 12:51:52 +02:00
little re-design of notifications: cleaned up relation between main class and backends. main class is responsible for notification routing. backends are responsible for sending one message to one user. relocated ajax functions to a separate file.
This commit is contained in:
parent
e0217cfabd
commit
40a68b6cfd
114
notifications/inc/class.ajaxnotifications.inc.php
Normal file
114
notifications/inc/class.ajaxnotifications.inc.php
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* eGroupWare - Notifications
|
||||||
|
*
|
||||||
|
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||||
|
* @package notifications
|
||||||
|
* @subpackage ajaxpopup
|
||||||
|
* @link http://www.egroupware.org
|
||||||
|
* @author Cornelius Weiss <nelius@cwtech.de>, Christian Binder <christian@jaytraxx.de>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ajax methods for notifications
|
||||||
|
*/
|
||||||
|
class ajaxnotifications {
|
||||||
|
/**
|
||||||
|
* Appname
|
||||||
|
*/
|
||||||
|
const _appname = 'notifications';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notification table in SQL database
|
||||||
|
*/
|
||||||
|
const _notification_table = 'egw_notificationpopup';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* holds account object for user to notify
|
||||||
|
*
|
||||||
|
* @var object
|
||||||
|
*/
|
||||||
|
private $recipient;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* holds config object (sitewide application config)
|
||||||
|
*
|
||||||
|
* @var object
|
||||||
|
*/
|
||||||
|
private $config;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* holds preferences object of user to notify
|
||||||
|
*
|
||||||
|
* @var object
|
||||||
|
*/
|
||||||
|
private $preferences;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* holds db object of SQL database
|
||||||
|
*
|
||||||
|
* @var egw_db
|
||||||
|
*/
|
||||||
|
private $db;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* constructor of ajaxnotifications
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function __construct() {
|
||||||
|
$this->recipient = (object)$GLOBALS['egw']->accounts->read();
|
||||||
|
|
||||||
|
$config = new config(self::_appname);
|
||||||
|
$this->config = (object)$config->read_repository();
|
||||||
|
|
||||||
|
$prefs = new preferences($this->recipient->account_id);
|
||||||
|
$preferences = $prefs->read();
|
||||||
|
$this->preferences = (object)$preferences[self::_appname];
|
||||||
|
|
||||||
|
$this->db = &$GLOBALS['egw']->db;
|
||||||
|
$this->db->set_app(self::_appname);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets all egwpopup notification for calling user.
|
||||||
|
* Requests and response is done via xajax
|
||||||
|
*
|
||||||
|
* @return xajax response
|
||||||
|
*/
|
||||||
|
public function get_popup_notifications() {
|
||||||
|
$response =& new xajaxResponse();
|
||||||
|
$session_id = $GLOBALS['egw_info']['user']['sessionid'];
|
||||||
|
$message = '';
|
||||||
|
$this->db->select(self::_notification_table,
|
||||||
|
'*', array(
|
||||||
|
'account_id' => $this->recipient->account_id,
|
||||||
|
'session_id' => $session_id,
|
||||||
|
),
|
||||||
|
__LINE__,__FILE__);
|
||||||
|
if ($this->db->num_rows() != 0) {
|
||||||
|
while ($notification = $this->db->row(true)) {
|
||||||
|
$response->addScriptCall('append_notification_message',$notification['message']);
|
||||||
|
}
|
||||||
|
$myval=$this->db->delete(self::_notification_table,array(
|
||||||
|
'account_id' => $this->recipient->account_id,
|
||||||
|
'session_id' => $session_id,
|
||||||
|
),__LINE__,__FILE__);
|
||||||
|
|
||||||
|
switch($this->preferences->egwpopup_verbosity) {
|
||||||
|
case 'low':
|
||||||
|
$response->addScript('notificationbell_switch("active");');
|
||||||
|
break;
|
||||||
|
case 'high':
|
||||||
|
$response->addAlert(lang('eGroupWare has notifications for you'));
|
||||||
|
$response->addScript('notificationwindow_display();');
|
||||||
|
break;
|
||||||
|
case 'medium':
|
||||||
|
default:
|
||||||
|
$response->addScript('notificationwindow_display();');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $response->getXML();
|
||||||
|
}
|
||||||
|
}
|
@ -19,16 +19,20 @@ interface iface_notification {
|
|||||||
*
|
*
|
||||||
* @param object $_sender
|
* @param object $_sender
|
||||||
* @param object $_recipient
|
* @param object $_recipient
|
||||||
|
* @param object $_config
|
||||||
* @param object $_preferences
|
* @param object $_preferences
|
||||||
*/
|
*/
|
||||||
public function __construct( $_sender=false, $_recipient=false, $_config=false, $_preferences=false );
|
public function __construct($_sender, $_recipient, $_config = null, $_preferences = null);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* sends notification
|
* sends notification
|
||||||
*
|
*
|
||||||
* @abstract NOTE, $_message contains some html-tags (<p><a><b><br>)
|
* @abstract NOTE, $_messages is an array that contains
|
||||||
* implementing class needs to handle them somehow.
|
* the notification message in plain and html
|
||||||
* @param string $_message
|
* @param array $_messages
|
||||||
|
* @param string $_subject
|
||||||
|
* @param array $_links
|
||||||
|
* @param array $_attachments
|
||||||
*/
|
*/
|
||||||
public function send( $_subject = false, $_messages, $_attachments = false);
|
public function send(array $_messages, $_subject = false, $_links = false, $_attachments = false);
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,6 @@
|
|||||||
* @version $Id$
|
* @version $Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
require_once(EGW_INCLUDE_ROOT.'/phpgwapi/inc/class.html.inc.php');
|
|
||||||
require_once(EGW_INCLUDE_ROOT.'/phpgwapi/inc/class.config.inc.php');
|
require_once(EGW_INCLUDE_ROOT.'/phpgwapi/inc/class.config.inc.php');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -18,9 +17,11 @@ require_once(EGW_INCLUDE_ROOT.'/phpgwapi/inc/class.config.inc.php');
|
|||||||
* @abstract NOTE: This is for instant notifications. If you need time dependend notifications use the
|
* @abstract NOTE: This is for instant notifications. If you need time dependend notifications use the
|
||||||
* asyncservices wrapper!
|
* asyncservices wrapper!
|
||||||
*
|
*
|
||||||
* The classes doing the notifications are called notification_<method> and should only be
|
* This class takes care about the notification-routing. It chooses one or more backends for each
|
||||||
* called from this class.
|
* given recipient depending on its prefs or falls back to self::_fallback
|
||||||
* The <method> gets extractd out of the preferences labels.
|
*
|
||||||
|
* The classes doing the notifications are called notification_<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 notification {
|
||||||
@ -67,7 +68,7 @@ final class notification {
|
|||||||
private $receivers = array();
|
private $receivers = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* objects of sender
|
* object of sender
|
||||||
* @var object
|
* @var object
|
||||||
*/
|
*/
|
||||||
private $sender;
|
private $sender;
|
||||||
@ -102,13 +103,6 @@ final class notification {
|
|||||||
*/
|
*/
|
||||||
private $attachments = array();
|
private $attachments = array();
|
||||||
|
|
||||||
/**
|
|
||||||
* holds html object to render elements
|
|
||||||
*
|
|
||||||
* @var object
|
|
||||||
*/
|
|
||||||
private $html;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* holds config object (sitewide configuration of app)
|
* holds config object (sitewide configuration of app)
|
||||||
*
|
*
|
||||||
@ -121,7 +115,6 @@ final class notification {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public function __construct() {
|
public function __construct() {
|
||||||
$this->html = & html::singleton();
|
|
||||||
$config = new config(self::_appname);
|
$config = new config(self::_appname);
|
||||||
$this->config = (object) $config->read_repository();
|
$this->config = (object) $config->read_repository();
|
||||||
}
|
}
|
||||||
@ -299,11 +292,14 @@ final class notification {
|
|||||||
* sends notification
|
* sends notification
|
||||||
*/
|
*/
|
||||||
public function send() {
|
public function send() {
|
||||||
if (empty($this->receivers) || (empty($this->message_plain) && empty($this->message_html))) {
|
if (!is_object($this->sender)) {
|
||||||
throw new Exception('Error: Could not send notification. No receiver or no message where supplied');
|
throw new Exception('Error: cannot send notification. No sender supplied');
|
||||||
}
|
}
|
||||||
if(!$messages = $this->create_messages($this->message_plain, $this->message_html, $this->links)) {
|
if (!is_array($this->receivers) || count($this->receivers) == 0) {
|
||||||
throw new Exception('Error: Could not send notification. Generating the messages failed');
|
throw new Exception('Error: cannot send notification. 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');
|
||||||
}
|
}
|
||||||
foreach ($this->receivers as $receiver) {
|
foreach ($this->receivers as $receiver) {
|
||||||
$user_notified = false;
|
$user_notified = false;
|
||||||
@ -352,7 +348,7 @@ final class notification {
|
|||||||
throw new Exception($notification_backend. ' is no implementation of iface_notification');
|
throw new Exception($notification_backend. ' is no implementation of iface_notification');
|
||||||
}
|
}
|
||||||
|
|
||||||
$obj->send($this->subject, $messages, $this->attachments);
|
$obj->send($messages, $this->subject, $this->links, $this->attachments);
|
||||||
}
|
}
|
||||||
catch (Exception $exception) {
|
catch (Exception $exception) {
|
||||||
$backend_errors[] = $notification_backend.' failed: '.$exception->getMessage();
|
$backend_errors[] = $notification_backend.' failed: '.$exception->getMessage();
|
||||||
@ -381,34 +377,15 @@ final class notification {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* gets message
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function get_message() {
|
|
||||||
return $this->message;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* gets receivers
|
|
||||||
*
|
|
||||||
* @return array of receiver objects
|
|
||||||
*/
|
|
||||||
public function get_receivers() {
|
|
||||||
return $this->receivers;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* this function creates an array with the message as plaintext and html
|
* this function creates an array with the message as plaintext and html
|
||||||
* including given links for internal usage or external mailers
|
|
||||||
*
|
*
|
||||||
* @param string $message_plain
|
* @param string $message_plain
|
||||||
* @param string $message_html
|
* @param string $message_html
|
||||||
* @param array $links
|
* @param array $links
|
||||||
* @return array $messages
|
* @return array $messages
|
||||||
*/
|
*/
|
||||||
private function create_messages($_message_plain = '', $_message_html = '', $_links = false) {
|
private function create_messages($_message_plain = '', $_message_html = '') {
|
||||||
if(empty($_message_plain) && empty($_message_html)) { return false; } // no message set
|
if(empty($_message_plain) && empty($_message_html)) { return false; } // no message set
|
||||||
$messages = array();
|
$messages = array();
|
||||||
$messages['plain'] = array();
|
$messages['plain'] = array();
|
||||||
@ -416,66 +393,20 @@ final class notification {
|
|||||||
|
|
||||||
// create the messages
|
// create the messages
|
||||||
if(!empty($_message_plain)) {
|
if(!empty($_message_plain)) {
|
||||||
$messages['plain']['text'] = $_message_plain;
|
$messages['plain'] = $_message_plain;
|
||||||
} else {
|
} else {
|
||||||
$messages['plain']['text'] = strip_tags($_message_html);
|
$messages['plain'] = strip_tags($_message_html);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!empty($_message_html)) {
|
if(!empty($_message_html)) {
|
||||||
$messages['html']['text'] = $_message_html;
|
$messages['html'] = $_message_html;
|
||||||
} else {
|
} else {
|
||||||
$messages['html']['text'] = nl2br($_message_plain);
|
$messages['html'] = nl2br($_message_plain);
|
||||||
}
|
|
||||||
|
|
||||||
// create the links
|
|
||||||
if(is_array($_links)) {
|
|
||||||
foreach($_links as $link) {
|
|
||||||
$params = '';
|
|
||||||
foreach($link->params as $param => $value) {
|
|
||||||
$params.='&'.$param.'='.$value;
|
|
||||||
}
|
|
||||||
$url = $GLOBALS['egw_info']['server']['webserver_url'].'/index.php?menuaction='.$link->menuaction.$params;
|
|
||||||
$menuaction_arr = explode('.',$link->menuaction);
|
|
||||||
$application = $menuaction_arr[0];
|
|
||||||
$image = $application ? $this->html->image($application,'navbar',$link->text,'align="middle"').' ' : '';
|
|
||||||
$messages['plain']['link_internal'] .= "\n".$url;
|
|
||||||
$messages['plain']['link_external'] .= "\n".$url.'&no_popup=1';
|
|
||||||
$messages['html']['link_internal'] .= '<br /><a href="'.$url.'" target="_blank">'.$image.$link->text.'</a>';
|
|
||||||
$messages['html']['link_external'] .= '<br /><a href="'.$url.'&no_popup=1" target="_blank">'.$link->text.'</a>';
|
|
||||||
$messages['html']['link_jspopup'] .= '<br /><div onclick="'.$this->popup($url).'">'.$image.$link->text.'</div>';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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.'<br />';
|
|
||||||
}
|
|
||||||
if(!empty($this->subject)) {
|
|
||||||
$messages['plain']['info_subject'] = $this->subject."\n";
|
|
||||||
$messages['html']['info_subject'] = $this->html->bold($this->subject).'<br />';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $messages;
|
return $messages;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* returns javascript to open a popup window: window.open(...)
|
|
||||||
*
|
|
||||||
* @param string $link link or this.href
|
|
||||||
* @param string $target='_blank' name of target or this.target
|
|
||||||
* @param int $width=750 width of the window
|
|
||||||
* @param int $height=400 height of the window
|
|
||||||
* @return string javascript (using single quotes)
|
|
||||||
*/
|
|
||||||
private function popup($link,$target='_blank',$width=750,$height=410)
|
|
||||||
{
|
|
||||||
return 'egw_openWindowCentered2('.($link == 'this.href' ? $link : "'".$link."'").','.
|
|
||||||
($target == 'this.target' ? $target : "'".$target."'").",$width,$height,'yes')";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* returns specified part from a given mailaddress
|
* returns specified part from a given mailaddress
|
||||||
*
|
*
|
||||||
|
@ -4,13 +4,14 @@
|
|||||||
*
|
*
|
||||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||||
* @package notifications
|
* @package notifications
|
||||||
|
* @subpackage backends
|
||||||
* @link http://www.egroupware.org
|
* @link http://www.egroupware.org
|
||||||
* @author Christian Binder <christian@jaytraxx.de>
|
* @author Christian Binder <christian@jaytraxx.de>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
require_once('class.iface_notification.inc.php');
|
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');
|
require_once(EGW_INCLUDE_ROOT. '/phpgwapi/inc/class.send.inc.php');
|
||||||
require_once(EGW_INCLUDE_ROOT.'/phpgwapi/inc/class.config.inc.php');
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User notification via email.
|
* User notification via email.
|
||||||
@ -57,6 +58,13 @@ class notification_email implements iface_notification {
|
|||||||
*/
|
*/
|
||||||
private $mail;
|
private $mail;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* holds html object to render elements
|
||||||
|
*
|
||||||
|
* @var object
|
||||||
|
*/
|
||||||
|
private $html;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* constructor of notification_email
|
* constructor of notification_email
|
||||||
*
|
*
|
||||||
@ -65,62 +73,32 @@ class notification_email implements iface_notification {
|
|||||||
* @param object $_config
|
* @param object $_config
|
||||||
* @param object $_preferences
|
* @param object $_preferences
|
||||||
*/
|
*/
|
||||||
public function __construct( $_sender=false, $_recipient=false, $_config=false, $_preferences=false) {
|
public function __construct($_sender, $_recipient, $_config = null, $_preferences = null) {
|
||||||
// If we are called from class notification sender, recipient, config and prefs are objects.
|
if(!is_object($_sender)) { throw new Exception("no sender given."); }
|
||||||
// otherwise we have to fetch this objects for current user.
|
if(!is_object($_recipient)) { throw new Exception("no recipient given."); }
|
||||||
if (!is_object($_sender)) {
|
|
||||||
$this->sender = (object) $GLOBALS['egw']->accounts->read($_sender);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$this->sender = $_sender;
|
$this->sender = $_sender;
|
||||||
}
|
|
||||||
if (!is_object($_recipient)) {
|
|
||||||
$this->recipient = (object) $GLOBALS['egw']->accounts->read($_recipient);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$this->recipient = $_recipient;
|
$this->recipient = $_recipient;
|
||||||
}
|
|
||||||
if(!is_object($_config)) {
|
|
||||||
$config = new config(self::_appname);
|
|
||||||
$this->config = (object) $config->read_repository();
|
|
||||||
} else {
|
|
||||||
$this->config = $_config;
|
$this->config = $_config;
|
||||||
}
|
|
||||||
if(!is_object($_preferences)) {
|
|
||||||
$prefs = new preferences($this->recipient->account_id);
|
|
||||||
$preferences = $prefs->read();
|
|
||||||
$this->preferences = (object)$preferences[self::_appname ];
|
|
||||||
} else {
|
|
||||||
$this->preferences = $_preferences;
|
$this->preferences = $_preferences;
|
||||||
}
|
|
||||||
if(!is_object($this->mail))
|
if(!is_object($this->mail))
|
||||||
{
|
{
|
||||||
$this->mail = new send();
|
$this->mail = new send();
|
||||||
}
|
}
|
||||||
|
$this->html = & html::singleton();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* sends notification
|
* sends notification
|
||||||
*
|
*
|
||||||
* @param string $_subject
|
|
||||||
* @param array $_messages
|
* @param array $_messages
|
||||||
|
* @param string $_subject
|
||||||
|
* @param array $_links
|
||||||
* @param array $_attachments
|
* @param array $_attachments
|
||||||
*/
|
*/
|
||||||
public function send( $_subject = false, $_messages, $_attachments = false) {
|
public function send(array $_messages, $_subject = false, $_links = false, $_attachments = false) {
|
||||||
if(!is_object($this->sender)) {
|
$body_plain = $_messages['plain'].$this->render_links($_links, false, $this->preferences->external_mailclient);
|
||||||
throw new Exception("No sender given.");
|
$body_html = "<html>\n<body>\n".$_messages['html'].$this->render_links($_links, true, $this->preferences->external_mailclient)."</body>\n</html>\n";
|
||||||
}
|
|
||||||
|
|
||||||
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'];
|
|
||||||
$body_html = "<html>\n<body>\n".$_messages['html']['text'].$_messages['html']['link_external']."</body>\n</html>\n";
|
|
||||||
} else {
|
|
||||||
$body_plain = $_messages['plain']['text'].$_messages['plain']['link_internal'];
|
|
||||||
$body_html = "<html>\n<body>\n".$_messages['html']['text'].$_messages['html']['link_internal']."</body>\n</html>\n";
|
|
||||||
}
|
|
||||||
$this->mail->ClearAddresses();
|
$this->mail->ClearAddresses();
|
||||||
$this->mail->ClearAttachments();
|
$this->mail->ClearAttachments();
|
||||||
$this->mail->IsHTML(true);
|
$this->mail->IsHTML(true);
|
||||||
@ -131,7 +109,7 @@ class notification_email implements iface_notification {
|
|||||||
$this->mail->Subject = $this->mail->encode_subject($_subject);
|
$this->mail->Subject = $this->mail->encode_subject($_subject);
|
||||||
$this->mail->Body = $body_html;
|
$this->mail->Body = $body_html;
|
||||||
$this->mail->AltBody = $body_plain;
|
$this->mail->AltBody = $body_plain;
|
||||||
if(is_array($_attachments)) {
|
if(is_array($_attachments) && count($_attachments) > 0) {
|
||||||
foreach($_attachments as $attachment) {
|
foreach($_attachments as $attachment) {
|
||||||
$this->mail->AddStringAttachment($attachment->string, $attachment->filename, $attachment->encoding, $attachment->type);
|
$this->mail->AddStringAttachment($attachment->string, $attachment->filename, $attachment->encoding, $attachment->type);
|
||||||
}
|
}
|
||||||
@ -141,4 +119,33 @@ class notification_email implements iface_notification {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* renders plaintext/html links from given link array
|
||||||
|
*
|
||||||
|
* @param array $_links
|
||||||
|
* @param boolean $_render_html
|
||||||
|
* @param boolean $_render_external
|
||||||
|
* @return plain or html rendered link(s) as complete string
|
||||||
|
*/
|
||||||
|
private function render_links($_links = false, $_render_html = false, $_render_external = true) {
|
||||||
|
if(!is_array($_links) || count($_links) == 0) { return false; }
|
||||||
|
|
||||||
|
// provide defaults if given arguments are null
|
||||||
|
// 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";
|
||||||
|
$link_array = array();
|
||||||
|
foreach($_links as $link) {
|
||||||
|
if($_render_external) {
|
||||||
|
$link->params['no_popup'] = 1;
|
||||||
|
}
|
||||||
|
$url = $this->html->link('/index.php?menuaction='.$link->menuaction, $link->params);
|
||||||
|
$link_array[] = $_render_html ? $this->html->a_href($link->text, $url) : $url;
|
||||||
|
}
|
||||||
|
|
||||||
|
return lang('Linked entries:').$newline.implode($newline,$link_array);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,30 +4,28 @@
|
|||||||
*
|
*
|
||||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||||
* @package notifications
|
* @package notifications
|
||||||
* @subpackage ajaxpopup
|
* @subpackage backends
|
||||||
* @link http://www.egroupware.org
|
* @link http://www.egroupware.org
|
||||||
* @author Cornelius Weiss <nelius@cwtech.de>
|
* @author Cornelius Weiss <nelius@cwtech.de>
|
||||||
* @version $Id$
|
* @version $Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
require_once('class.iface_notification.inc.php');
|
require_once('class.iface_notification.inc.php');
|
||||||
require_once(EGW_INCLUDE_ROOT.'/phpgwapi/inc/class.config.inc.php');
|
require_once(EGW_INCLUDE_ROOT.'/phpgwapi/inc/class.html.inc.php');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instant user notification with egroupware popup.
|
* Instant user notification with egroupware popup.
|
||||||
* egwpopup is a two stage notification. In the first stage
|
*
|
||||||
|
* @abstract egwpopup is a two stage notification. In the first stage
|
||||||
* notification is written into self::_notification_egwpopup
|
* notification is written into self::_notification_egwpopup
|
||||||
* table. In the second stage a request from the client reads
|
* table. In the second stage a request from the client reads
|
||||||
* out the table to look if there is a notificaton for this
|
* out the table to look if there is a notificaton for this
|
||||||
* client. (multidisplay is supported)
|
* client. The second stage is done in class.ajaxnotifications.inc.php
|
||||||
|
* (multidisplay is supported)
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
class notification_popup implements iface_notification {
|
class notification_popup implements iface_notification {
|
||||||
|
|
||||||
/**
|
|
||||||
* Notification window {div|alert}
|
|
||||||
*/
|
|
||||||
const _window = 'div';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Appname
|
* Appname
|
||||||
*/
|
*/
|
||||||
@ -73,6 +71,13 @@ class notification_popup implements iface_notification {
|
|||||||
*/
|
*/
|
||||||
private $db;
|
private $db;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* holds html object to render elements
|
||||||
|
*
|
||||||
|
* @var object
|
||||||
|
*/
|
||||||
|
private $html;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* constructor of notification_egwpopup
|
* constructor of notification_egwpopup
|
||||||
*
|
*
|
||||||
@ -81,49 +86,27 @@ class notification_popup implements iface_notification {
|
|||||||
* @param object $_config
|
* @param object $_config
|
||||||
* @param object $_preferences
|
* @param object $_preferences
|
||||||
*/
|
*/
|
||||||
public function __construct( $_sender=false, $_recipient=false, $_config=false, $_preferences=false) {
|
public function __construct($_sender, $_recipient, $_config = null, $_preferences = null) {
|
||||||
// If we are called from class notification sender, recipient, config and prefs are objects.
|
if(!is_object($_sender)) { throw new Exception("no sender given."); }
|
||||||
// otherwise we have to fetch this objects for current user.
|
if(!is_object($_recipient)) { throw new Exception("no recipient given."); }
|
||||||
if (!is_object($_sender)) {
|
|
||||||
$this->sender = (object) $GLOBALS['egw']->accounts->read($_sender);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$this->sender = $_sender;
|
$this->sender = $_sender;
|
||||||
}
|
|
||||||
if (!is_object($_recipient)) {
|
|
||||||
$this->recipient = (object) $GLOBALS['egw']->accounts->read($_recipient);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$this->recipient = $_recipient;
|
$this->recipient = $_recipient;
|
||||||
}
|
|
||||||
if(!is_object($_config)) {
|
|
||||||
$config = new config(self::_appname);
|
|
||||||
$this->config = (object) $config->read_repository();
|
|
||||||
} else {
|
|
||||||
$this->config = $_config;
|
$this->config = $_config;
|
||||||
}
|
|
||||||
if(!is_object($_preferences)) {
|
|
||||||
$prefs = new preferences($this->recipient->account_id);
|
|
||||||
$preferences = $prefs->read();
|
|
||||||
$this->preferences = (object)$preferences[self::_appname ];
|
|
||||||
} else {
|
|
||||||
$this->preferences = $_preferences;
|
$this->preferences = $_preferences;
|
||||||
}
|
|
||||||
$this->db = &$GLOBALS['egw']->db;
|
$this->db = &$GLOBALS['egw']->db;
|
||||||
$this->db->set_app( self::_appname );
|
$this->db->set_app( self::_appname );
|
||||||
|
$this->html = & html::singleton();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* sends notification if user is online
|
* sends notification if user is online
|
||||||
*
|
*
|
||||||
* @param string $_subject
|
|
||||||
* @param array $_messages
|
* @param array $_messages
|
||||||
|
* @param string $_subject
|
||||||
|
* @param array $_links
|
||||||
* @param array $_attachments
|
* @param array $_attachments
|
||||||
*/
|
*/
|
||||||
public function send( $_subject = false, $_messages, $_attachments = false) {
|
public function send(array $_messages, $_subject = false, $_links = false, $_attachments = false) {
|
||||||
if(!is_object($this->sender)) {
|
|
||||||
throw new Exception("No sender given.");
|
|
||||||
}
|
|
||||||
$sessions = $GLOBALS['egw']->session->list_sessions(0, 'asc', 'session_dla', true);
|
$sessions = $GLOBALS['egw']->session->list_sessions(0, 'asc', 'session_dla', true);
|
||||||
$user_sessions = array();
|
$user_sessions = array();
|
||||||
foreach ($sessions as $session) {
|
foreach ($sessions as $session) {
|
||||||
@ -132,63 +115,14 @@ class notification_popup implements iface_notification {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( empty($user_sessions) ) throw new Exception("User {$this->recipient->account_lid} isn't online. Can't send notification via popup");
|
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 );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
$message = $this->render_infos($_subject)
|
||||||
* Gets all notification for current user.
|
.$this->html->hr()
|
||||||
* Requests and response is done via xajax
|
.$_messages['html']
|
||||||
*
|
.$this->html->hr()
|
||||||
* @return xajax response
|
.$this->render_links($_links);
|
||||||
*/
|
|
||||||
public function ajax_get_notifications() {
|
|
||||||
$response =& new xajaxResponse();
|
|
||||||
$session_id = $GLOBALS['egw_info']['user']['sessionid'];
|
|
||||||
$message = '';
|
|
||||||
$this->db->select(self::_notification_table,
|
|
||||||
'*', array(
|
|
||||||
'account_id' => $this->recipient->account_id,
|
|
||||||
'session_id' => $session_id,
|
|
||||||
),
|
|
||||||
__LINE__,__FILE__);
|
|
||||||
if ($this->db->num_rows() != 0) {
|
|
||||||
while ($notification = $this->db->row(true)) {
|
|
||||||
switch (self::_window ) {
|
|
||||||
case 'div' :
|
|
||||||
$response->addScriptCall('append_notification_message',$notification['message']);
|
|
||||||
break;
|
|
||||||
case 'alert' :
|
|
||||||
$response->addAlert($notification['message']);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$myval=$this->db->delete(self::_notification_table,array(
|
|
||||||
'account_id' => $this->recipient->account_id,
|
|
||||||
'session_id' => $session_id,
|
|
||||||
),__LINE__,__FILE__);
|
|
||||||
|
|
||||||
switch (self::_window) {
|
$this->save( $message, $user_sessions );
|
||||||
case 'div' :
|
|
||||||
switch($this->preferences->egwpopup_verbosity) {
|
|
||||||
case 'low':
|
|
||||||
$response->addScript('notificationbell_switch("active");');
|
|
||||||
break;
|
|
||||||
case 'high':
|
|
||||||
$response->addAlert(lang('eGroupware has some notifications for you'));
|
|
||||||
$response->addScript('notificationwindow_display();');
|
|
||||||
break;
|
|
||||||
case 'medium':
|
|
||||||
default:
|
|
||||||
$response->addScript('notificationwindow_display();');
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'alert' :
|
|
||||||
// nothing to do for now
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $response->getXML();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -208,4 +142,57 @@ class notification_popup implements iface_notification {
|
|||||||
}
|
}
|
||||||
if ($result === false) throw new Exception("Can't save notification into SQL table");
|
if ($result === false) throw new Exception("Can't save notification into SQL table");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* renders plaintext/html links from given link array
|
||||||
|
*
|
||||||
|
* @param array $_links
|
||||||
|
* @return html rendered link(s) as complete string (jspopup)
|
||||||
|
*/
|
||||||
|
private function render_links($_links = false) {
|
||||||
|
if(!is_array($_links) || count($_links) == 0) { return false; }
|
||||||
|
$newline = "<br />";
|
||||||
|
|
||||||
|
$link_array = 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');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->html->bold(lang('Linked entries:')).$newline.implode($newline,$link_array);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns javascript to open a popup window: window.open(...)
|
||||||
|
*
|
||||||
|
* @param string $link link or this.href
|
||||||
|
* @param string $target='_blank' name of target or this.target
|
||||||
|
* @param int $width=750 width of the window
|
||||||
|
* @param int $height=400 height of the window
|
||||||
|
* @return string javascript (using single quotes)
|
||||||
|
*/
|
||||||
|
private function jspopup($link,$target='_blank',$width=750,$height=410)
|
||||||
|
{
|
||||||
|
return 'egw_openWindowCentered2('.($link == 'this.href' ? $link : "'".$link."'").','.
|
||||||
|
($target == 'this.target' ? $target : "'".$target."'").",$width,$height,'yes')";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* renders additional infos from sender and subject
|
||||||
|
*
|
||||||
|
* @param string $_subject
|
||||||
|
* @return html rendered info as complete string
|
||||||
|
*/
|
||||||
|
private function render_infos($_subject = false) {
|
||||||
|
$infos = array();
|
||||||
|
$newline = "<br />";
|
||||||
|
|
||||||
|
$sender = $this->sender->account_fullname ? $this->sender->account_fullname : $this->sender_account_email;
|
||||||
|
$infos[] = lang('Message from').': '.$sender;
|
||||||
|
if(!empty($_subject)) { $infos[] = $this->html->bold($_subject); }
|
||||||
|
return implode($newline,$infos);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,12 +4,12 @@
|
|||||||
*
|
*
|
||||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||||
* @package notifications
|
* @package notifications
|
||||||
|
* @subpackage backends
|
||||||
* @link http://www.egroupware.org
|
* @link http://www.egroupware.org
|
||||||
* @author Christian Binder <christian@jaytraxx.de>
|
* @author Christian Binder <christian@jaytraxx.de>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
require_once('class.iface_notification.inc.php');
|
require_once('class.iface_notification.inc.php');
|
||||||
require_once(EGW_INCLUDE_ROOT.'/phpgwapi/inc/class.config.inc.php');
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User notification via winpopup.
|
* User notification via winpopup.
|
||||||
@ -58,7 +58,7 @@ class notification_winpopup implements iface_notification {
|
|||||||
* holds the netbios command to be executed on notification
|
* holds the netbios command to be executed on notification
|
||||||
*
|
*
|
||||||
* @abstract
|
* @abstract
|
||||||
* Example: /bin/echo [MESSAGE] | /usr/bin/smbclient -M computer-[4] -I [IP] -U [SENDER]
|
* Example: $netbios_command = "/bin/echo [MESSAGE] | /usr/bin/smbclient -M computer-[4] -I [IP] -U [SENDER]";
|
||||||
*
|
*
|
||||||
* Placeholders are:
|
* Placeholders are:
|
||||||
* [MESSAGE] is the notification message itself
|
* [MESSAGE] is the notification message itself
|
||||||
@ -66,7 +66,6 @@ class notification_winpopup implements iface_notification {
|
|||||||
* [IP] is the IP-Adress of the windows machine to notify
|
* [IP] is the IP-Adress of the windows machine to notify
|
||||||
* [SENDER] is the sender of the message
|
* [SENDER] is the sender of the message
|
||||||
* Note: the webserver-user needs execute rights for this command
|
* Note: the webserver-user needs execute rights for this command
|
||||||
* Don't forget to enclose placeholders containing whitespaces with single apostrophes
|
|
||||||
*
|
*
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
@ -80,53 +79,29 @@ class notification_winpopup implements iface_notification {
|
|||||||
* @param object $_config
|
* @param object $_config
|
||||||
* @param object $_preferences
|
* @param object $_preferences
|
||||||
*/
|
*/
|
||||||
public function __construct($_sender=false, $_recipient=false, $_config=false, $_preferences=false) {
|
public function __construct($_sender, $_recipient, $_config = null, $_preferences = null) {
|
||||||
// If we are called from class notification sender, recipient, config and prefs are objects.
|
if(!is_object($_sender)) { throw new Exception("no sender given."); }
|
||||||
// otherwise we have to fetch this objects for current user.
|
if(!is_object($_recipient)) { throw new Exception("no recipient given."); }
|
||||||
if (!is_object($_sender)) {
|
|
||||||
$this->sender = (object) $GLOBALS['egw']->accounts->read($_sender);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$this->sender = $_sender;
|
|
||||||
}
|
|
||||||
if (!is_object($_recipient)) {
|
|
||||||
$this->recipient = (object) $GLOBALS['egw']->accounts->read($_recipient);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$this->recipient = $_recipient;
|
|
||||||
}
|
|
||||||
if(!is_object($_config)) {
|
|
||||||
$config = new config(self::_appname);
|
|
||||||
$this->config = (object) $config->read_repository();
|
|
||||||
} else {
|
|
||||||
$this->config = $_config;
|
|
||||||
}
|
|
||||||
if(!is_object($_preferences)) {
|
|
||||||
$prefs = new preferences($this->recipient->account_id);
|
|
||||||
$preferences = $prefs->read();
|
|
||||||
$this->preferences = (object)$preferences[self::_appname ];
|
|
||||||
} else {
|
|
||||||
$this->preferences = $_preferences;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* sends notification
|
|
||||||
*
|
|
||||||
* @param string $_subject
|
|
||||||
* @param array $_messages
|
|
||||||
* @param array $_attachments
|
|
||||||
*/
|
|
||||||
public function send( $_subject = false, $_messages, $_attachments = false) {
|
|
||||||
if(!$this->netbios_command) {
|
if(!$this->netbios_command) {
|
||||||
throw new Exception( 'Winpopup plugin not configured yet. Skipped sending notification message. '.
|
throw new Exception( 'Winpopup plugin not configured yet. Skipped sending notification message. '.
|
||||||
'Please check var "netbios_command" in winpopup backend '.
|
'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.notification_winpopup.inc.php).');
|
||||||
}
|
}
|
||||||
if(!is_object($this->sender)) {
|
$this->sender = $_sender;
|
||||||
throw new Exception("No sender given.");
|
$this->recipient = $_recipient;
|
||||||
|
$this->config = $_config;
|
||||||
|
$this->preferences = $_preferences;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sends notification
|
||||||
|
*
|
||||||
|
* @param array $_messages
|
||||||
|
* @param string $_subject
|
||||||
|
* @param array $_links
|
||||||
|
* @param array $_attachments
|
||||||
|
*/
|
||||||
|
public function send(array $_messages, $_subject = false, $_links = false, $_attachments = false) {
|
||||||
$sessions = $GLOBALS['egw']->session->list_sessions(0, 'asc', 'session_dla', true);
|
$sessions = $GLOBALS['egw']->session->list_sessions(0, 'asc', 'session_dla', true);
|
||||||
$user_sessions = array();
|
$user_sessions = array();
|
||||||
foreach ($sessions as $session) {
|
foreach ($sessions as $session) {
|
||||||
@ -138,7 +113,7 @@ class notification_winpopup implements iface_notification {
|
|||||||
}
|
}
|
||||||
if ( empty($user_sessions) ) throw new Exception("User #{$this->recipient->account_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']['info_subject'].$_messages['plain']['text'], $user_sessions );
|
$this->send_winpopup( $this->render_infos($_subject).$_messages['plain'], $user_sessions );
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -156,7 +131,7 @@ class notification_winpopup implements iface_notification {
|
|||||||
if(strlen($ip_octet)==1) { $ip_octets[$id] = '00'.$ip_octet; }
|
if(strlen($ip_octet)==1) { $ip_octets[$id] = '00'.$ip_octet; }
|
||||||
if(strlen($ip_octet)==2) { $ip_octets[$id] = '0'.$ip_octet; }
|
if(strlen($ip_octet)==2) { $ip_octets[$id] = '0'.$ip_octet; }
|
||||||
}
|
}
|
||||||
$placeholders = array( '/\[MESSAGE\]/' => escapeshellarg($_message), // XSS prevention
|
$placeholders = array( '/\[MESSAGE\]/' => escapeshellarg($_message), // prevent code injection
|
||||||
'/\[1\]/' => $ip_octets[0],
|
'/\[1\]/' => $ip_octets[0],
|
||||||
'/\[2\]/' => $ip_octets[1],
|
'/\[2\]/' => $ip_octets[1],
|
||||||
'/\[3\]/' => $ip_octets[2],
|
'/\[3\]/' => $ip_octets[2],
|
||||||
@ -181,4 +156,16 @@ class notification_winpopup implements iface_notification {
|
|||||||
private function valid_ip($_ip) {
|
private function valid_ip($_ip) {
|
||||||
return eregi('^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$',$_ip);
|
return eregi('^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$',$_ip);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* renders additional info from subject
|
||||||
|
*
|
||||||
|
* @param string $_subject
|
||||||
|
* @return plain rendered info as complete string
|
||||||
|
*/
|
||||||
|
private function render_infos($_subject = false) {
|
||||||
|
$newline = "\n";
|
||||||
|
if(!empty($_subject)) { return $_subject.$newline; }
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
@ -18,7 +18,7 @@ function notificationwindow_setTimeout() {
|
|||||||
window.setTimeout("notificationwindow_refresh();", 60000);
|
window.setTimeout("notificationwindow_refresh();", 60000);
|
||||||
}
|
}
|
||||||
function notificationwindow_refresh() {
|
function notificationwindow_refresh() {
|
||||||
xajax_doXMLHTTP("notifications.notification_popup.ajax_get_notifications");
|
xajax_doXMLHTTP("notifications.ajaxnotifications.get_popup_notifications");
|
||||||
notificationwindow_setTimeout();
|
notificationwindow_setTimeout();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -459,10 +459,21 @@ Preferences tabs
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Tables inside notification window
|
notification window
|
||||||
*/
|
*/
|
||||||
#notificationwindow_message > table
|
#notificationwindow_message > table
|
||||||
{
|
{
|
||||||
font-size: 90%
|
font-size: 90%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#notificationwindow_message hr
|
||||||
|
{
|
||||||
|
border: none;
|
||||||
|
border-top: 1px solid black;
|
||||||
|
height: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#notificationwindow_message .jspopup
|
||||||
|
{
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
@ -718,10 +718,21 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Tables inside notification window
|
notification window
|
||||||
*/
|
*/
|
||||||
#notificationwindow_message > table
|
#notificationwindow_message > table
|
||||||
{
|
{
|
||||||
font-size: 90%
|
font-size: 90%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#notificationwindow_message hr
|
||||||
|
{
|
||||||
|
border: none;
|
||||||
|
border-top: 1px solid black;
|
||||||
|
height: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#notificationwindow_message .jspopup
|
||||||
|
{
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
@ -642,9 +642,21 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Tables inside notification window
|
notification window
|
||||||
*/
|
*/
|
||||||
#notificationwindow_message > table
|
#notificationwindow_message > table
|
||||||
{
|
{
|
||||||
font-size: 90%
|
font-size: 90%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#notificationwindow_message hr
|
||||||
|
{
|
||||||
|
border: none;
|
||||||
|
border-top: 1px solid black;
|
||||||
|
height: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#notificationwindow_message .jspopup
|
||||||
|
{
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user