mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-11-23 00:13:35 +01:00
* Notifications: fix notification sub messages (grouped entries) would still show up even though their parent message once been deleted
This commit is contained in:
parent
e6aef87a62
commit
9134a0bc51
@ -145,11 +145,12 @@ class notifications_ajax {
|
|||||||
/**
|
/**
|
||||||
* Remove given notification id(s) from the table
|
* Remove given notification id(s) from the table
|
||||||
*
|
*
|
||||||
* @param array|int $notify_ids one or multiple notify_id(s)
|
* @param array $notifymessages one or multiple notify_id(s)
|
||||||
*/
|
*/
|
||||||
public function delete_message($notify_ids)
|
public function delete_message($notifymessages)
|
||||||
{
|
{
|
||||||
if ($notify_ids)
|
$notify_ids = $this->fetch_notify_ids($notifymessages);
|
||||||
|
if (!empty($notify_ids))
|
||||||
{
|
{
|
||||||
$this->db->delete(self::_notification_table,array(
|
$this->db->delete(self::_notification_table,array(
|
||||||
'notify_id' => $notify_ids,
|
'notify_id' => $notify_ids,
|
||||||
@ -157,12 +158,13 @@ class notifications_ajax {
|
|||||||
'notify_type' => self::_type
|
'notify_type' => self::_type
|
||||||
),__LINE__,__FILE__,self::_appname);
|
),__LINE__,__FILE__,self::_appname);
|
||||||
}
|
}
|
||||||
|
$this->response->data(['deleted'=>$notify_ids]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method to update message(s) status
|
* Method to update message(s) status
|
||||||
*
|
*
|
||||||
* @param int|array $notify_ids one or more notify_id(s)
|
* @param array $notifymessages one or more notify_id(s)
|
||||||
* @param string $status = SEEN, status of message:
|
* @param string $status = SEEN, status of message:
|
||||||
* - SEEN: message has been seen
|
* - SEEN: message has been seen
|
||||||
* - UNSEEN: message has not been seen
|
* - UNSEEN: message has not been seen
|
||||||
@ -170,9 +172,10 @@ class notifications_ajax {
|
|||||||
* this status has been used more specifically for browser type
|
* this status has been used more specifically for browser type
|
||||||
* of notifications.
|
* of notifications.
|
||||||
*/
|
*/
|
||||||
public function update_status($notify_ids,$status = "SEEN")
|
public function update_status($notifymessages, $status = "SEEN")
|
||||||
{
|
{
|
||||||
if ($notify_ids)
|
$notify_ids = $this->fetch_notify_ids($notifymessages);
|
||||||
|
if (!empty($notify_ids))
|
||||||
{
|
{
|
||||||
$this->db->update(self::_notification_table,array('notify_status' => $status),array(
|
$this->db->update(self::_notification_table,array('notify_status' => $status),array(
|
||||||
'notify_id' => $notify_ids,
|
'notify_id' => $notify_ids,
|
||||||
@ -182,43 +185,76 @@ class notifications_ajax {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gets all relevant notify ids based on given notify message data
|
||||||
|
* @param $notifymessages
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function fetch_notify_ids ($notifymessages)
|
||||||
|
{
|
||||||
|
$notify_ids = [];
|
||||||
|
|
||||||
|
foreach ($notifymessages as $data)
|
||||||
|
{
|
||||||
|
if (is_array($data) && $data['id'])
|
||||||
|
{
|
||||||
|
array_push($notify_ids, (string)$data['id']);
|
||||||
|
if (is_array($data['data'])) $notify_ids = array_unique(array_merge($notify_ids, $this->search_in_notify_data($data['data']['id'], $data['data']['app'])));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
array_push($notify_ids, (string)$data);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return $notify_ids;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches all notify_ids relevant to the entry
|
||||||
|
* @param $_id
|
||||||
|
* @param $_appname
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function search_in_notify_data($_id, $_appname)
|
||||||
|
{
|
||||||
|
$ret = [];
|
||||||
|
if ($_id && $_appname)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
// mariaDB supported query
|
||||||
|
$ret = $this->db->select(self::_notification_table, 'notify_id', array(
|
||||||
|
'account_id' => $this->recipient->account_id,
|
||||||
|
'notify_type' => self::_type,
|
||||||
|
'notify_data->"$.appname"' => $_appname,
|
||||||
|
'notify_data->"$.data.id"' => $_id
|
||||||
|
),
|
||||||
|
__LINE__,__FILE__,0 ,'ORDER BY notify_id DESC',self::_appname);
|
||||||
|
}
|
||||||
|
catch (Api\Db\Exception $e) {
|
||||||
|
// do it manual for all other DB
|
||||||
|
foreach($this->db->select(self::_notification_table, '*', array(
|
||||||
|
'account_id' => $this->recipient->account_id,
|
||||||
|
'notify_type' => self::_type
|
||||||
|
),
|
||||||
|
__LINE__,__FILE__,0 ,'ORDER BY notify_id DESC',self::_appname) as $row)
|
||||||
|
{
|
||||||
|
$data = json_decode($row['notify_data'], true);
|
||||||
|
if ($data['appname'] == $_appname && $data['data']['id'] == $_id) $ret[] = $row['notify_id'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* gets all egwpopup notifications for calling user
|
* gets all egwpopup notifications for calling user
|
||||||
*
|
*
|
||||||
* @return boolean true or false
|
* @return boolean true or false
|
||||||
*/
|
*/
|
||||||
private function get_egwpopup($browserNotify = false) {
|
private function get_egwpopup($browserNotify = false)
|
||||||
$rs = $this->db->select(self::_notification_table, '*', array(
|
{
|
||||||
'account_id' => $this->recipient->account_id,
|
$entries = notifications_popup::read($this->recipient->account_id);
|
||||||
'notify_type' => self::_type
|
$this->response->apply('app.notifications.append', array($entries['rows'], $browserNotify, $entries['total']));
|
||||||
),
|
|
||||||
__LINE__,__FILE__,0 ,'ORDER BY notify_id DESC',self::_appname, 100);
|
|
||||||
$result = array();
|
|
||||||
if ($rs->NumRows() > 0) {
|
|
||||||
foreach ($rs as $notification) {
|
|
||||||
$actions = null;
|
|
||||||
$data = json_decode($notification['notify_data'], true);
|
|
||||||
if ($data['appname'] && $data['data'])
|
|
||||||
{
|
|
||||||
$_actions = Api\Hooks::process (array(
|
|
||||||
'location' => 'notifications_actions',
|
|
||||||
'data' => $data['data']
|
|
||||||
), $data['appname'], true);
|
|
||||||
$actions = $_actions[$data['appname']];
|
|
||||||
}
|
|
||||||
$result[] = array(
|
|
||||||
'id' => $notification['notify_id'],
|
|
||||||
'message' => $notification['notify_message'],
|
|
||||||
'status' => $notification['notify_status'],
|
|
||||||
'created' => Api\DateTime::to($notification['notify_created']),
|
|
||||||
'current' => new DateTime(),
|
|
||||||
'actions' => is_array($actions)?$actions:NULL,
|
|
||||||
'extra_data' => ($data['data'] ? $data['data'] : array())
|
|
||||||
);
|
|
||||||
|
|
||||||
}
|
|
||||||
$this->response->apply('app.notifications.append', array($result, $browserNotify));
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,21 +130,31 @@ class notifications_popup implements notifications_iface {
|
|||||||
), 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");
|
||||||
$push = new Api\Json\Push($this->recipient->account_id);
|
$push = new Api\Json\Push($this->recipient->account_id);
|
||||||
$push->call('app.notifications.append', $this->read());
|
$entries = self::read($this->recipient->account_id);
|
||||||
|
$push->call('app.notifications.append', $entries['rows'], null, $entries['total']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* read all notification messages for current recipient
|
* read all notification messages for given recipient
|
||||||
* @return type
|
* @param $_account_id
|
||||||
|
* @return array
|
||||||
*/
|
*/
|
||||||
private function read()
|
public static function read($_account_id)
|
||||||
{
|
{
|
||||||
$rs = $this->db->select(self::_notification_table, '*', array(
|
if (!$_account_id) return [];
|
||||||
'account_id' => $this->recipient->account_id,
|
|
||||||
|
$rs = $GLOBALS['egw']->db->select(self::_notification_table, '*', array(
|
||||||
|
'account_id' => $_account_id,
|
||||||
'notify_type' => self::_type
|
'notify_type' => self::_type
|
||||||
),
|
),
|
||||||
__LINE__,__FILE__,0 ,'ORDER BY notify_id DESC',self::_appname, 100);
|
__LINE__,__FILE__,0 ,'ORDER BY notify_id DESC',self::_appname, 100);
|
||||||
|
// Fetch the total
|
||||||
|
$total = $GLOBALS['egw']->db->select(self::_notification_table, 'COUNT(*)', array(
|
||||||
|
'account_id' => $_account_id,
|
||||||
|
'notify_type' => self::_type
|
||||||
|
),
|
||||||
|
__LINE__,__FILE__,0 ,'',self::_appname)->fetchColumn();
|
||||||
$result = array();
|
$result = array();
|
||||||
if ($rs->NumRows() > 0) {
|
if ($rs->NumRows() > 0) {
|
||||||
foreach ($rs as $notification) {
|
foreach ($rs as $notification) {
|
||||||
@ -169,7 +179,7 @@ class notifications_popup implements notifications_iface {
|
|||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
return $result;
|
return ['rows' => $result, 'total'=> $total];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,7 +92,8 @@
|
|||||||
this.run_notifications();
|
this.run_notifications();
|
||||||
|
|
||||||
this.filter = '';
|
this.filter = '';
|
||||||
|
// total number of notifications
|
||||||
|
this.total = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
notifications.prototype.run_notifications = function ()
|
notifications.prototype.run_notifications = function ()
|
||||||
@ -516,14 +517,9 @@
|
|||||||
_event.stopPropagation();
|
_event.stopPropagation();
|
||||||
var egwpopup_message = _node[0];
|
var egwpopup_message = _node[0];
|
||||||
var id = egwpopup_message[0].id.replace(/egwpopup_message_/ig,'');
|
var id = egwpopup_message[0].id.replace(/egwpopup_message_/ig,'');
|
||||||
var ids = [id];
|
|
||||||
if (notifymessages[id]['children'])
|
|
||||||
{
|
|
||||||
ids = ids.concat(Object.keys(notifymessages[id]['children']));
|
|
||||||
}
|
|
||||||
if (notifymessages[id]['status'] !='SEEN')
|
if (notifymessages[id]['status'] !='SEEN')
|
||||||
{
|
{
|
||||||
var request = egw.json("notifications.notifications_ajax.update_status", [ids, "SEEN"]);
|
var request = egw.json("notifications.notifications_ajax.update_status", [[notifymessages[id]], "SEEN"]);
|
||||||
request.sendRequest(true);
|
request.sendRequest(true);
|
||||||
this.update_message_status(id, "SEEN");
|
this.update_message_status(id, "SEEN");
|
||||||
if (notifymessages[id]['extra_data']['onSeenAction'])
|
if (notifymessages[id]['extra_data']['onSeenAction'])
|
||||||
@ -537,9 +533,7 @@
|
|||||||
notifications.prototype.mark_all_seen = function()
|
notifications.prototype.mark_all_seen = function()
|
||||||
{
|
{
|
||||||
if (!notifymessages || Object.keys(notifymessages).length == 0) return false;
|
if (!notifymessages || Object.keys(notifymessages).length == 0) return false;
|
||||||
var ids = Object.keys(notifymessages);
|
egw.json("notifications.notifications_ajax.update_status", [notifymessages, "SEEN"]).sendRequest(true);
|
||||||
ids = ids.concat(this.findAllChildrenIds());
|
|
||||||
egw.json("notifications.notifications_ajax.update_status", [ids, "SEEN"]).sendRequest(true);
|
|
||||||
for (var id in notifymessages)
|
for (var id in notifymessages)
|
||||||
{
|
{
|
||||||
this.update_message_status(id, "SEEN");
|
this.update_message_status(id, "SEEN");
|
||||||
@ -568,12 +562,13 @@
|
|||||||
|
|
||||||
notifications.prototype.delete_all = function () {
|
notifications.prototype.delete_all = function () {
|
||||||
if (!notifymessages || Object.entries(notifymessages).length == 0) return false;
|
if (!notifymessages || Object.entries(notifymessages).length == 0) return false;
|
||||||
var ids = Object.keys(notifymessages);
|
var self = this;
|
||||||
ids = ids.concat(this.findAllChildrenIds());
|
egw.json("notifications.notifications_ajax.delete_message", [notifymessages], function(_data){
|
||||||
egw.json("notifications.notifications_ajax.delete_message", [ids]).sendRequest(true);
|
if (_data && _data['deleted']) self.total -= Object.keys(_data['deleted']).length;
|
||||||
|
self.counterUpdate();
|
||||||
|
}).sendRequest(true);
|
||||||
notifymessages = {};
|
notifymessages = {};
|
||||||
jQuery("#egwpopup_list").empty();
|
jQuery("#egwpopup_list").empty();
|
||||||
this.counterUpdate();
|
|
||||||
egw.loading_prompt('popup_notifications', false);
|
egw.loading_prompt('popup_notifications', false);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -584,12 +579,11 @@
|
|||||||
_event.stopPropagation();
|
_event.stopPropagation();
|
||||||
var egwpopup_message = _node[0];
|
var egwpopup_message = _node[0];
|
||||||
var id = egwpopup_message[0].id.replace(/egwpopup_message_/ig,'');
|
var id = egwpopup_message[0].id.replace(/egwpopup_message_/ig,'');
|
||||||
var ids = [id];
|
var self = this;
|
||||||
if (notifymessages[id]['children'])
|
var request = egw.json("notifications.notifications_ajax.delete_message", [[notifymessages[id]]],function(_data){
|
||||||
{
|
if (_data && _data['deleted']) self.total -= Object.keys(_data['deleted']).length;
|
||||||
ids = ids.concat(Object.keys(notifymessages[id]['children']));
|
self.counterUpdate();
|
||||||
}
|
});
|
||||||
var request = egw.json("notifications.notifications_ajax.delete_message", [ids]);
|
|
||||||
request.sendRequest(true);
|
request.sendRequest(true);
|
||||||
var nextNode = egwpopup_message.next();
|
var nextNode = egwpopup_message.next();
|
||||||
var keepLoadingPrompt = false;
|
var keepLoadingPrompt = false;
|
||||||
@ -604,8 +598,6 @@
|
|||||||
if (keepLoadingPrompt && !egwIsMobile()) egw.loading_prompt('popup_notifications', true);
|
if (keepLoadingPrompt && !egwIsMobile()) egw.loading_prompt('popup_notifications', true);
|
||||||
egwpopup_message.remove();
|
egwpopup_message.remove();
|
||||||
this.bell("inactive");
|
this.bell("inactive");
|
||||||
this.counterUpdate();
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -661,16 +653,18 @@
|
|||||||
* @param _rowData
|
* @param _rowData
|
||||||
* @param _browser_notify
|
* @param _browser_notify
|
||||||
*/
|
*/
|
||||||
notifications.prototype.append = function(_rawData, _browser_notify) {
|
notifications.prototype.append = function(_rawData, _browser_notify, _total) {
|
||||||
|
|
||||||
var hasUnseen = [];
|
var hasUnseen = [];
|
||||||
|
_rawData = _rawData || [];
|
||||||
// Dont process the data if they're the same as it could get very expensive to
|
// Dont process the data if they're the same as it could get very expensive to
|
||||||
// proccess html their content.
|
// proccess html their content.
|
||||||
if (_currentRawData.length>0 && _currentRawData.length == _rawData.length) return;
|
if (_currentRawData.length>0 && _currentRawData.length == _rawData.length) return;
|
||||||
_currentRawData = _rawData;
|
_currentRawData = _rawData || [];
|
||||||
let old_notifymessages = notifymessages;
|
var old_notifymessages = notifymessages;
|
||||||
notifymessages = {};
|
notifymessages = {};
|
||||||
var browser_notify = _browser_notify || this.check_browser_notify();
|
var browser_notify = _browser_notify || this.check_browser_notify();
|
||||||
|
this.total = _total || 0;
|
||||||
for (var i=0; i < _rawData.length; i++)
|
for (var i=0; i < _rawData.length; i++)
|
||||||
{
|
{
|
||||||
var data = this.getData(_rawData[i]['message'], _rawData[i]['extra_data']);
|
var data = this.getData(_rawData[i]['message'], _rawData[i]['extra_data']);
|
||||||
@ -699,7 +693,8 @@
|
|||||||
status: _rawData[i]['status'],
|
status: _rawData[i]['status'],
|
||||||
created: _rawData[i]['created'],
|
created: _rawData[i]['created'],
|
||||||
current: _rawData[i]['current'],
|
current: _rawData[i]['current'],
|
||||||
extra_data: _rawData[i]['extra_data']
|
extra_data: _rawData[i]['extra_data'],
|
||||||
|
id: _rawData[i]['id']
|
||||||
};
|
};
|
||||||
if (_rawData[i]['actions'] && _rawData[i]['actions'].length > 0) notifymessages[_rawData[i]['id']]['data']['actions'] = _rawData[i]['actions'];
|
if (_rawData[i]['actions'] && _rawData[i]['actions'].length > 0) notifymessages[_rawData[i]['id']]['data']['actions'] = _rawData[i]['actions'];
|
||||||
// Notification API
|
// Notification API
|
||||||
@ -714,7 +709,7 @@
|
|||||||
// notification id
|
// notification id
|
||||||
var id = this.tag.split(":");
|
var id = this.tag.split(":");
|
||||||
// delete the message
|
// delete the message
|
||||||
var request = egw.json("notifications.notifications_ajax.update_status", [id[1], 'DISPLAYED']);
|
var request = egw.json("notifications.notifications_ajax.update_status", [[id[1]], 'DISPLAYED']);
|
||||||
request.sendRequest();
|
request.sendRequest();
|
||||||
},
|
},
|
||||||
onclick:function(e){
|
onclick:function(e){
|
||||||
@ -740,12 +735,12 @@
|
|||||||
}
|
}
|
||||||
if (!_rawData[i]['status'])
|
if (!_rawData[i]['status'])
|
||||||
{
|
{
|
||||||
egw.json("notifications.notifications_ajax.update_status", [_rawData[i]['id'], 'DISPLAYED']);
|
egw.json("notifications.notifications_ajax.update_status", [[_rawData[i]['id']], 'DISPLAYED']);
|
||||||
hasUnseen.push(_rawData[i]['id']);
|
hasUnseen.push(_rawData[i]['id']);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
let egwpopup = document.getElementById('egwpopup');
|
var egwpopup = document.getElementById('egwpopup');
|
||||||
switch(egw.preference('egwpopup_verbosity', 'notifications'))
|
switch(egw.preference('egwpopup_verbosity', 'notifications'))
|
||||||
{
|
{
|
||||||
case 'low':
|
case 'low':
|
||||||
@ -854,6 +849,10 @@
|
|||||||
var counter = 0;
|
var counter = 0;
|
||||||
var apps = {};
|
var apps = {};
|
||||||
|
|
||||||
|
// set total number
|
||||||
|
document.getElementById("egwpopup_header").childNodes[0].textContent = (egw.lang("Notifications")+" ("+this.total+")");
|
||||||
|
document.getElementById('topmenu_info_notifications').title = egw.lang('total')+":"+this.total;
|
||||||
|
|
||||||
for (var id in notifymessages)
|
for (var id in notifymessages)
|
||||||
{
|
{
|
||||||
if (typeof apps[notifymessages[id]['extra_data']['app']] == 'undefined')
|
if (typeof apps[notifymessages[id]['extra_data']['app']] == 'undefined')
|
||||||
|
Loading…
Reference in New Issue
Block a user