fixed JSON error "contains script tags! Aborting ..." when confirming a popup:

- adding id to notifications table to use it to identify a notification (sending back the message incl. onclick="..." caused the problem)
- adding a timestamp when message was added, to identify older messages
- close button --> send all ids in one ajax request, not one per id
This commit is contained in:
Ralf Becker 2011-04-14 13:43:16 +00:00
parent 42bf4dbc3c
commit c3170b44bd
6 changed files with 82 additions and 63 deletions

View File

@ -1,6 +1,6 @@
<?php <?php
/** /**
* eGroupWare - Notifications * EGroupware - Notifications
* *
* @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
@ -128,14 +128,18 @@ class notifications_ajax {
/** /**
* Let the user confirm that they have seen the message. * Let the user confirm that they have seen the message.
* After they've seen it, remove it from the database * After they've seen it, remove it from the database
*
* @param int|array $notify_id one or more notify_id's
*/ */
public function confirm_message($message) { public function confirm_message($notify_id)
//error_log( html_entity_decode($message)); {
$myval=$this->db->delete(self::_notification_table,array( if ($notify_id)
'account_id' => $this->recipient->account_id, {
'message' => html_entity_decode($message) $this->db->delete(self::_notification_table,array(
'notify_id' => $notify_id,
),__LINE__,__FILE__,self::_appname); ),__LINE__,__FILE__,self::_appname);
} }
}
/** /**
* checks users mailbox and sends a notification if new mails have arrived * checks users mailbox and sends a notification if new mails have arrived
@ -231,14 +235,13 @@ class notifications_ajax {
*/ */
private function get_egwpopup() { private function get_egwpopup() {
$message = ''; $message = '';
$rs = $this->db->select(self::_notification_table, $rs = $this->db->select(self::_notification_table, '*', array(
'*', array(
'account_id' => $this->recipient->account_id, 'account_id' => $this->recipient->account_id,
), ),
__LINE__,__FILE__,false,'',self::_appname); __LINE__,__FILE__,false,'',self::_appname);
if ($rs->NumRows() > 0) { if ($rs->NumRows() > 0) {
foreach ($rs as $notification) { foreach ($rs as $notification) {
$this->response->addScriptCall('append_notification_message',$notification['message']); $this->response->addScriptCall('append_notification_message',$notification['notify_id'],$notification['notify_message']);
} }
switch($this->preferences[self::_appname]['egwpopup_verbosity']) { switch($this->preferences[self::_appname]['egwpopup_verbosity']) {

View File

@ -1,6 +1,6 @@
<?php <?php
/** /**
* eGroupWare - Notifications * EGroupware - Notifications
* *
* @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
@ -18,17 +18,6 @@
* In the second stage a request from the client reads * 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. The second stage is done in class.notifications_ajax.inc.php * client. The second stage is done in class.notifications_ajax.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 notifications_popup implements notifications_iface { class notifications_popup implements notifications_iface {
@ -86,13 +75,14 @@ class notifications_popup implements notifications_iface {
* @param object $_preferences * @param object $_preferences
*/ */
public function __construct($_sender, $_recipient, $_config = null, $_preferences = null) { public function __construct($_sender, $_recipient, $_config = null, $_preferences = null) {
//error_log(__METHOD__."(".array2string($_sender).', '.array2string($_recipient).', '.array2string($config).',...)');
if(!is_object($_sender)) { throw new Exception("no sender given."); } if(!is_object($_sender)) { throw new Exception("no sender given."); }
if(!is_object($_recipient)) { throw new Exception("no recipient given."); } if(!is_object($_recipient)) { throw new Exception("no recipient given."); }
$this->sender = $_sender; $this->sender = $_sender;
$this->recipient = $_recipient; $this->recipient = $_recipient;
$this->config = $_config; $this->config = $_config;
$this->preferences = $_preferences; $this->preferences = $_preferences;
$this->db = &$GLOBALS['egw']->db; $this->db = $GLOBALS['egw']->db;
} }
/** /**
@ -127,7 +117,7 @@ class notifications_popup implements notifications_iface {
private function save( $_message ) { private function save( $_message ) {
$result = $this->db->insert( self::_notification_table, array( $result = $this->db->insert( self::_notification_table, array(
'account_id' => $this->recipient->account_id, 'account_id' => $this->recipient->account_id,
'message' => $_message 'notify_message' => $_message
), false,__LINE__,__FILE__,self::_appname); ), false,__LINE__,__FILE__,self::_appname);
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");
} }
@ -208,16 +198,8 @@ class notifications_popup implements notifications_iface {
* @param settings array with keys account_id and new_owner (new_owner is optional) * @param settings array with keys account_id and new_owner (new_owner is optional)
*/ */
public function deleteaccount($settings) { public function deleteaccount($settings) {
if($settings['new_owner']) {
$this->db->update( self::_notification_table, array(
'account_id' => $settings['new_owner']
), array(
'account_id' => $settings['account_id']
),__LINE__,__FILE__,self::_appname);
} else {
$this->db->delete( self::_notification_table, array( $this->db->delete( self::_notification_table, array(
'account_id' => $settings['account_id'] 'account_id' => $settings['account_id']
),__LINE__,__FILE__,self::_appname); ),__LINE__,__FILE__,self::_appname);
} }
} }
}

View File

@ -8,7 +8,7 @@
* @version $Id$ * @version $Id$
*/ */
var notifymessages = new Array(); var notifymessages = {};
function egwpopup_init(_i) { function egwpopup_init(_i) {
window.setTimeout("egwpopup_refresh(" + _i + ");", 1000); window.setTimeout("egwpopup_refresh(" + _i + ");", 1000);
@ -39,9 +39,12 @@ function egwpopup_display() {
egwpopup.style.left = (Browserwidth/2 - 250) + "px"; egwpopup.style.left = (Browserwidth/2 - 250) + "px";
egwpopup.style.top = (Browserheight/4) + "px"; egwpopup.style.top = (Browserheight/4) + "px";
egwpopup_message.style.maxHeight = (Browserheight/2) + "px"; egwpopup_message.style.maxHeight = (Browserheight/2) + "px";
egwpopup_message.innerHTML = notifymessages[0]; for(var show in notifymessages) break;
if(notifymessages.length-1 > 0 ) { egwpopup_message.innerHTML = notifymessages[show];
egwpopup_ok_button.value = "OK (" + (notifymessages.length-1) + ")"; var num = 0;
for(var id in notifymessages) ++num;
if(num-1 > 0 ) {
egwpopup_ok_button.value = "OK (" + (num-1) + ")";
} else { } else {
egwpopup_ok_button.value = "OK"; egwpopup_ok_button.value = "OK";
} }
@ -64,23 +67,30 @@ function egwpopup_button_ok() {
egwpopup = document.getElementById("egwpopup"); egwpopup = document.getElementById("egwpopup");
egwpopup_message = document.getElementById("egwpopup_message"); egwpopup_message = document.getElementById("egwpopup_message");
egwpopup_message.scrollTop = 0; egwpopup_message.scrollTop = 0;
xajax_doXMLHTTP("notifications.notifications_ajax.confirm_message", notifymessages[0]);
notifymessages.shift(); for(var confirmed in notifymessages) break;
if(notifymessages.length > 0) { xajax_doXMLHTTP("notifications.notifications_ajax.confirm_message", confirmed);
egwpopup_display(); delete notifymessages[confirmed];
} else {
for(var id in notifymessages) break;
if (id == undefined) {
egwpopup.style.display = "none"; egwpopup.style.display = "none";
egwpopup_message.innerHTML = ""; egwpopup_message.innerHTML = "";
notificationbell_switch("inactive"); notificationbell_switch("inactive");
} else {
egwpopup_display();
} }
} }
// Close and mark all as read // Close and mark all as read
function egwpopup_button_close() { function egwpopup_button_close() {
for(var i = 0; i < notifymessages.length; i++) { var ids = new Array();
xajax_doXMLHTTP("notifications.notifications_ajax.confirm_message", notifymessages[i]); for(var id in notifymessages) {
ids.push(id);
} }
notifymessages = new Array(); xajax_doXMLHTTP("notifications.notifications_ajax.confirm_message", ids);
notifymessages = {};
var egwpopup = document.getElementById("egwpopup"); var egwpopup = document.getElementById("egwpopup");
var egwpopup_message = document.getElementById("egwpopup_message"); var egwpopup_message = document.getElementById("egwpopup_message");
egwpopup.style.display = "none"; egwpopup.style.display = "none";
@ -88,9 +98,6 @@ function egwpopup_button_close() {
notificationbell_switch("inactive"); notificationbell_switch("inactive");
} }
function append_notification_message(_message) { function append_notification_message(_id, _message) {
// Check to prevent duplicates notifymessages[_id] = _message;
if(notifymessages.indexOf(_message) == -1) {
notifymessages.push(_message);
}
} }

View File

@ -15,7 +15,7 @@ if (!defined('NOTIFICATION_APP'))
} }
$setup_info[NOTIFICATION_APP]['name'] = NOTIFICATION_APP; $setup_info[NOTIFICATION_APP]['name'] = NOTIFICATION_APP;
$setup_info[NOTIFICATION_APP]['version'] = '1.9.002'; $setup_info[NOTIFICATION_APP]['version'] = '1.9.003';
$setup_info[NOTIFICATION_APP]['app_order'] = 1; $setup_info[NOTIFICATION_APP]['app_order'] = 1;
$setup_info[NOTIFICATION_APP]['tables'] = array('egw_notificationpopup'); $setup_info[NOTIFICATION_APP]['tables'] = array('egw_notificationpopup');
$setup_info[NOTIFICATION_APP]['enable'] = 2; $setup_info[NOTIFICATION_APP]['enable'] = 2;
@ -45,5 +45,3 @@ $setup_info[NOTIFICATION_APP]['depends'][] = array(
'appname' => 'etemplate', 'appname' => 'etemplate',
'versions' => Array('1.7','1.8','1.9') 'versions' => Array('1.7','1.8','1.9')
); );

View File

@ -1,6 +1,6 @@
<?php <?php
/** /**
* eGroupWare - Notifications * EGroupware - Notifications
* *
* @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
@ -12,12 +12,14 @@
$phpgw_baseline = array( $phpgw_baseline = array(
'egw_notificationpopup' => array( 'egw_notificationpopup' => array(
'fd' => array( 'fd' => array(
'account_id' => array('type' => 'int','precision' => '20','nullable' => False), 'notify_id' => array('type' => 'auto','nullable' => False,'comment' => 'primary key'),
'message' => array('type' => 'longtext') 'account_id' => array('type' => 'int','precision' => '20','nullable' => False,'comment' => 'user to notify'),
'notify_message' => array('type' => 'text','comment' => 'notification message'),
'notify_created' => array('type' => 'timestamp','default' => 'current_timestamp','comment' => 'creation time of notification')
), ),
'pk' => array(), 'pk' => array('notify_id'),
'fk' => array(), 'fk' => array(),
'ix' => array('account_id'), 'ix' => array('account_id','notify_created'),
'uc' => array() 'uc' => array()
) )
); );

View File

@ -1,6 +1,6 @@
<?php <?php
/** /**
* eGroupWare - Setup * EGroupware - Setup
* http://www.egroupware.org * http://www.egroupware.org
* Created by eTemplates DB-Tools written by ralfbecker@outdoor-training.de * Created by eTemplates DB-Tools written by ralfbecker@outdoor-training.de
* *
@ -55,6 +55,9 @@ function notifications_upgrade1_8()
return $GLOBALS['setup_info']['notifications']['currentver'] = '1.9.001'; return $GLOBALS['setup_info']['notifications']['currentver'] = '1.9.001';
} }
/**
* Empty notificaton table, as it can contain thousands of old entries, not delivered before
*/
function notifications_upgrade1_9_001() function notifications_upgrade1_9_001()
{ {
// empty notificationpopup table, as it can contain thousands of old entries, not delivered before // empty notificationpopup table, as it can contain thousands of old entries, not delivered before
@ -62,3 +65,27 @@ function notifications_upgrade1_9_001()
return $GLOBALS['setup_info']['notifications']['currentver'] = '1.9.002'; return $GLOBALS['setup_info']['notifications']['currentver'] = '1.9.002';
} }
/**
* Add primary key to easy identify notifications in ajax request, a automatic timestamp and table prefix
*/
function notifications_upgrade1_9_002()
{
$GLOBALS['egw_setup']->oProc->RefreshTable('egw_notificationpopup',array(
'fd' => array(
'notify_id' => array('type' => 'auto','nullable' => False,'comment' => 'primary key'),
'account_id' => array('type' => 'int','precision' => '20','nullable' => False,'comment' => 'user to notify'),
'notify_message' => array('type' => 'text','comment' => 'notification message'),
'notify_created' => array('type' => 'timestamp','default' => 'current_timestamp','comment' => 'creation time of notification')
),
'pk' => array('notify_id'),
'fk' => array(),
'ix' => array('account_id','notify_created'),
'uc' => array()
),array(
'notify_message' => 'message',
));
return $GLOBALS['setup_info']['notifications']['currentver'] = '1.9.003';
}