Commit 394defc5 authored by Robert Lyon's avatar Robert Lyon Committed by Gerrit Code Review
Browse files

Merge "Bug: 1369569 New filter/search for notification list"

parents 511b7daa d665ec9a
......@@ -44,6 +44,7 @@ $string['alltypes'] = 'All types';
$string['nodelete'] = 'No notifications to delete';
$string['youroutboxisempty'] = 'Your outbox is empty.';
$string['yourinboxisempty'] = 'Your inbox is empty.';
$string['noresultsfound'] = 'No messages found matching your search criteria.';
$string['markedasread'] = 'Marked your notifications as read';
$string['failedtomarkasread'] = 'Failed to mark your notifications as read';
......
......@@ -92,6 +92,23 @@ $paginationjavascript = <<<JAVASCRIPT
// NOTE: most js is in the notification.js file, but we found
// this part much more difficult to relocate
function changeactivitytype() {
var delallform = document.forms['delete_all_notifications'];
delallform.elements['type'].value = this.options[this.selectedIndex].value;
var params = {'type': this.options[this.selectedIndex].value};
sendjsonrequest('indexin.json.php', params, 'GET', function(data) {
jQuery("#activitylist span.countresults").remove();
jQuery("#activitylist th").each(function() {
var link = jQuery(this).find('a');
if (link.length >= 1) {
var headertext = link.text().trim();
jQuery(this).html(headertext);
}
});
jQuery("input#search").val('');
paginator.updateResults(data);
});
}
jQuery(function($) {
// We want the paginator to tell us when a page gets changed.
......@@ -225,6 +242,27 @@ $smarty->assign('INLINEJAVASCRIPT', $paginationjavascript);
define('NOTIFICATION_SUBPAGE', 'inbox');
$smarty->assign('SUBPAGENAV', PluginModuleMultirecipientnotification::submenu_items());
$searchtext = param_variable('search', null);
$searcharea = param_variable('searcharea', null);
$searchdata = new stdClass();
$searchdata->searchtext = $searchtext;
$searchdata->searcharea = $searcharea;
$searchdata->searchurl = 'inbox.php?type=' . $type . '&search=' . $searchtext . '&searcharea=';
$searchdata->all_count = 0;
$searchdata->sender_count = 0;
$searchdata->recipient_count = 0;
$searchdata->sub_count = 0;
$searchdata->mes_count = 0;
if ($searchtext !== null) {
$searchresults = get_message_search($searchtext, $type, 0, null, "inbox.php", $USER->get('id'));
$searchdata->all_count = $searchresults['All_data']['count'];
$searchdata->sender_count = $searchresults['Sender']['count'];
$searchdata->recipient_count = $searchresults['Recipient']['count'];
$searchdata->sub_count = $searchresults['Subject']['count'];
$searchdata->mes_count = $searchresults['Message']['count'];
}
$smarty->assign('searchdata', $searchdata);
$smarty->assign('deleteall', $deleteall);
$smarty->assign('activitylist', $activitylist);
......
......@@ -45,3 +45,7 @@ $string['replybuttonplaceholder'] = '...';
$string['selectallread'] = 'All unread notifications';
$string['selectalldelete'] = 'All notifications for deletion';
$string['clickformore'] = '(Press \'Enter\' to display more information)';
$string['labelsearch'] = 'Search';
$string['labelall'] = 'All';
$string['labelmessage'] = 'Message';
......@@ -10,7 +10,9 @@
*
*/
require_once(dirname(__FILE__) . '/multirecipientnotification.php');
require_once(dirname(__FILE__) . '/multirecipientnotificationsearch.php');
/**
* returns an object containing a list of ids of notifications the user has
......@@ -27,60 +29,73 @@ function activitylistin($type='all', $limit=10, $offset=0) {
global $USER;
$result = new stdClass();
$userid = $USER->get('id');
$typesql = '';
if ($type != 'all') {
// Treat as comma-separated list of activity type names
$types = explode(',', preg_replace('/[^a-z,]+/', '', $type));
if ($types) {
$typesql = ' at.name IN (' . join(',', array_map('db_quote', $types)) . ')';
if (in_array('adminmessages', $types)) {
$typesql = '(' . $typesql . ' OR at.admin = 1)';
$searchtext = param_variable('search', null);
$searcharea = param_variable('searcharea', 'All_data');
if (isset($searchtext) AND $searchtext !== null) {
$type = param_variable('type', 'all');
$searchresults = get_message_search($searchtext, $type, $offset, $limit, "inbox.php", $userid);
$result->msgidrecords = $searchresults[$searcharea]['data'];
$result->count = $searchresults[$searcharea]['count'];
$result->search = true;
}
else {
$typesql = '';
if ($type != 'all') {
// Treat as comma-separated list of activity type names
$types = explode(',', preg_replace('/[^a-z,]+/', '', $type));
if ($types) {
$typesql = ' at.name IN (' . join(',', array_map('db_quote', $types)) . ')';
if (in_array('adminmessages', $types)) {
$typesql = '(' . $typesql . ' OR at.admin = 1)';
}
$typesql = ' AND ' . $typesql;
}
$typesql = ' AND ' . $typesql;
}
}
$notificationtargetcolumn = 'usr';
$notificationtargetrole = 'recipient';
$notificationtargetcolumn = 'usr';
$notificationtargetrole = 'recipient';
if (is_postgres()) {
$readsqlstr = 'CAST(b.read AS INT)';
}
else {
$readsqlstr = 'b.read';
}
if (is_postgres()) {
$readsqlstr = 'CAST(b.read AS INT)';
}
else {
$readsqlstr = 'b.read';
}
$msgidquery = "
(
SELECT a.id, a.read, a.ctime, 'notification_internal_activity' AS msgtable, subject
FROM {notification_internal_activity} AS a
INNER JOIN {activity_type} AS at ON a.type = at.id
WHERE a." . $notificationtargetcolumn . " = ?
" . $typesql . "
)
UNION
(
SELECT a.id, " . $readsqlstr . ", a.ctime, 'module_multirecipient_notification' AS msgtable, subject
FROM {module_multirecipient_notification} AS a
INNER JOIN {module_multirecipient_userrelation} AS b
ON a.id = b.notification
INNER JOIN {activity_type} AS at ON a.type = at.id
WHERE b.usr = ?
AND b.deleted = '0'
AND b.role = '" . $notificationtargetrole . "'
" . $typesql . "
)";
$countquery = 'SELECT COUNT(*) FROM (' . $msgidquery . ') AS dummytable';
$result->count = count_records_sql($countquery, array($userid, $userid));
$msgidquery .= "
ORDER BY \"read\" ASC, ctime DESC, subject ASC";
$result->msgidrecords = get_records_sql_array($msgidquery, array($userid, $userid), $offset, $limit);
$msgidquery = "
(
SELECT a.id, a.read, a.ctime, 'notification_internal_activity' AS msgtable, subject
FROM {notification_internal_activity} AS a
INNER JOIN {activity_type} AS at ON a.type = at.id
WHERE a." . $notificationtargetcolumn . " = ?
" . $typesql . "
)
UNION
(
SELECT a.id, " . $readsqlstr . ", a.ctime, 'module_multirecipient_notification' AS msgtable, subject
FROM {module_multirecipient_notification} AS a
INNER JOIN {module_multirecipient_userrelation} AS b
ON a.id = b.notification
INNER JOIN {activity_type} AS at ON a.type = at.id
WHERE b.usr = ?
AND b.deleted = '0'
AND b.role = '" . $notificationtargetrole . "'
" . $typesql . "
)";
$countquery = 'SELECT COUNT(*) FROM (' . $msgidquery . ') AS dummytable';
$result->count = count_records_sql($countquery, array($userid, $userid));
$msgidquery .= "
ORDER BY \"read\" ASC, ctime DESC, subject ASC";
$result->msgidrecords = get_records_sql_array($msgidquery, array($userid, $userid), $offset, $limit);
$result->search = false;
}
if (!is_array($result->msgidrecords)) {
$result->msgidrecords = array();
$result->count = 0;
}
return $result;
}
......@@ -387,6 +402,83 @@ function activityblocklistin($type='all', $limit=10, $offset=0) {
return ($return);
}
/**
* returns an object containing a list of ids of notifications the user has
* sent and the tables where to find the dataelements. Also returns the
* count of the found notifications
*
* @param string $type
* @param int $limit
* @param int $offset
* @return \stdClass
*/
function activitylistout($type='all', $limit=10, $offset=0) {
global $USER;
$result = new stdClass();
$userid = $USER->get('id');
$searchtext = param_variable('search', null);
$searcharea = param_variable('searcharea', 'All_data');
if (isset($searchtext) AND $searchtext !== null) {
$type = param_variable('type', 'all');
$searchresults = get_message_search($searchtext, $type, $offset, $limit, "outbox.php", $userid);
$result->msgidrecords = $searchresults[$searcharea]['data'];
$result->count = $searchresults[$searcharea]['count'];
$result->search = true;
}
else {
$typesql = '';
if ($type != 'all') {
// Treat as comma-separated list of activity type names
$types = explode(',', preg_replace('/[^a-z,]+/', '', $type));
if ($types) {
$typesql = ' at.name IN (' . join(',', array_map('db_quote', $types)) . ')';
if (in_array('adminmessages', $types)) {
$typesql = '(' . $typesql . ' OR at.admin = 1)';
}
$typesql = ' AND ' . $typesql;
}
}
$notificationtargetcolumn = 'from';
$notificationtargetrole = 'sender';
$msgidquery = "
(
SELECT a.id, a.ctime, 'notification_internal_activity' AS msgtable, subject
FROM {notification_internal_activity} AS a
INNER JOIN {activity_type} AS at ON a.type = at.id
WHERE a." . $notificationtargetcolumn . " = ?
" . $typesql . "
AND at.name != 'newpost'
)
UNION
(
SELECT a.id, a.ctime, 'module_multirecipient_notification' AS msgtable, subject
FROM {module_multirecipient_notification} AS a
INNER JOIN {module_multirecipient_userrelation} AS b
ON a.id = b.notification
INNER JOIN {activity_type} AS at ON a.type = at.id
WHERE b.usr = ?
AND b.deleted = '0'
AND b.role = '" . $notificationtargetrole . "'
" . $typesql . "
)";
$countquery = 'SELECT COUNT(*) FROM (' . $msgidquery . ') AS dummytable';
$result->count = count_records_sql($countquery, array($userid, $userid));
$msgidquery .= "
ORDER BY ctime DESC, subject ASC";
$result->msgidrecords = get_records_sql_array($msgidquery, array($userid, $userid), $offset, $limit);
$result->search = false;
}
if (!is_array($result->msgidrecords)) {
$result->msgidrecords = array();
$result->count = 0;
}
return $result;
}
/**
* creates a result-array with the number, limit, offset and notification-type(s)
* of the returned htmlrepresentation of the notifications in the outbox, as well
......@@ -410,55 +502,15 @@ function activityblocklistin($type='all', $limit=10, $offset=0) {
*/
function activitylistout_html($type='all', $limit=10, $offset=0) {
global $USER;
$userid = $USER->get('id');
$typesql = '';
if ($type != 'all') {
// Treat as comma-separated list of activity type names
$types = explode(',', preg_replace('/[^a-z,]+/', '', $type));
if ($types) {
$typesql = ' at.name IN (' . join(',', array_map('db_quote', $types)) . ')';
if (in_array('adminmessages', $types)) {
$typesql = '(' . $typesql . ' OR at.admin = 1)';
}
$typesql = ' AND ' . $typesql;
}
}
$notificationtargetcolumn = 'from';
$notificationtargetrole = 'sender';
$msgidquery = "
(
SELECT a.id, a.ctime, 'notification_internal_activity' AS msgtable
FROM {notification_internal_activity} AS a
INNER JOIN {activity_type} AS at ON a.type = at.id
WHERE a." . $notificationtargetcolumn . " = ?
" . $typesql . "
AND at.name != 'newpost'
)
UNION
(
SELECT a.id, a.ctime, 'module_multirecipient_notification' AS msgtable
FROM {module_multirecipient_notification} AS a
INNER JOIN {module_multirecipient_userrelation} AS b
ON a.id = b.notification
INNER JOIN {activity_type} AS at ON a.type = at.id
WHERE b.usr = ?
AND b.deleted = '0'
AND b.role = '" . $notificationtargetrole . "'
" . $typesql . "
)";
$countquery = 'SELECT COUNT(*) FROM (' . $msgidquery . ') AS dummytable';
$count = count_records_sql($countquery, array($userid, $userid));
$activitylist = activitylistout($type, $limit, $offset);
$pagination = build_pagination(array(
'id' => 'activitylist_pagination',
'url' => get_config('wwwroot') . 'module/multirecipientnotification/outbox.php?type=' . hsc($type),
'jsonscript' => 'module/multirecipientnotification/indexout.json.php',
'datatable' => 'activitylist',
'count' => $count,
'count' => $activitylist->count,
'limit' => $limit,
'offset' => $offset,
'jumplinks' => 6,
......@@ -467,7 +519,7 @@ function activitylistout_html($type='all', $limit=10, $offset=0) {
));
$result = array(
'count' => $count,
'count' => $activitylist->count,
'limit' => $limit,
'offset' => $offset,
'type' => $type,
......@@ -476,19 +528,11 @@ function activitylistout_html($type='all', $limit=10, $offset=0) {
'pagination_js' => $pagination['javascript'],
);
if ($count < 1) {
if ($activitylist->count < 1) {
return $result;
}
$records = array();
$msgidquery .= "
ORDER BY ctime DESC";
$msgidrecords = get_records_sql_array($msgidquery, array($userid, $userid), $offset, $limit);
if (!is_array($msgidrecords)) {
$msgidrecords = array();
}
foreach ($msgidrecords as $msgidrecord ) {
foreach ($activitylist->msgidrecords as $msgidrecord ) {
if ($msgidrecord->msgtable == 'notification_internal_activity') {
$recordsarray = get_records_sql_array("SELECT a.*, at.name AS type, at.plugintype, at.pluginname
FROM {notification_internal_activity} a
......
<?php
/**
* Mahara: Electronic portfolio, weblog, resume builder and social networking
* Copyright (C) 2011 Copyright Holder
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package mahara
* @subpackage module-multirecipientnotification
* @author David Ballhausen
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL
*/
defined('INTERNAL') || die();
/**
* At first step it reads out the ids from all messages which where
* recieved or send by the user with the id $usr.
* After this it is searching for the searchterm in the recieved
* messages with the ids
*
* example result:
* array (
* All_data =>
* stdClass Object(
* [count] => 1
* [data] => array(
* [id] => 1
* [ctime] => 2013-11-28 20:41:40
* [msgtable] => notification_internal_activity
* [in_subject] => 0
* [in_message] => 0
* [in_sender] => 0
* [in_recipient] => 1
* )
* )
* Recipient =>
* stdClass Object(
* [count] => 0
* [data] => null
* )
* Sender =>
* stdClass Object(
* [count] => 02
* [data] => null
* )
* Subject =>
* stdClass Object(
* [count] => 0
* [data] => null
* )
* Message =>
* stdClass Object(
* [count] => 0
* [data] => null
* )
* )
*
* @param int $searchstring what should be searched for
* @param int $activitytype the messagetype which is shown
* @param int $offset offset of the first row to return
* @param int $limit limits the number of results - for paginations for example
* @param int $location where is to search (Inbox / Outbox)
* @param int $usr who is searching
* @return array
*/
function get_message_search($searchstring, $type, $offset, $limit, $location, $usr = null) {
global $USER;
$result = null;
$return = null;
$searchstring = '%' . strtolower(trim($searchstring)) . '%';
$categories = array('in_subject', 'in_message', 'in_sender', 'in_recipient');
if (null === $usr) {
$usr = $USER->get('id');
}
$typesql = '';
if ($type != 'all') {
// Treat as comma-separated list of activity type names
$types = explode(',', preg_replace('/[^a-z,]+/', '', $type));
if ($types) {
$typesql = ' atype.name IN (' . join(',', array_map('db_quote', $types)) . ')';
if (in_array('adminmessages', $types)) {
$typesql = '(' . $typesql . ' OR atype.admin = 1)';
}
$typesql = ' AND ' . $typesql;
}
}
if ($location=="inbox.php") {
$query_old_where = "notif.usr = '" . $usr . "'";
$query_new_where = "relation.usr = '" . $usr . "' AND relation.role = 'recipient'";
}
else {
$query_old_where = "notif.from = '" . $usr . "'";
$query_new_where = "relation.usr = '" . $usr . "' AND relation.role = 'sender'";
}
$query_ids = "(
SELECT notif.id, 'notification_internal_activity' AS msgtable
FROM {notification_internal_activity} AS notif
WHERE " . $query_old_where . "
)
UNION
(
SELECT notif.id, 'module_multirecipient_notification' AS msgtable
FROM {module_multirecipient_notification} AS notif
INNER JOIN {module_multirecipient_userrelation} AS relation
ON notif.id = relation.notification
WHERE " . $query_new_where . " AND relation.deleted = '0'
)";
$query_old_where = array();
$query_new_where = array();
$records_ids = get_records_sql_array($query_ids, array());
if (!empty($records_ids)) {
foreach ($records_ids as $record) {
if ($record->msgtable === 'notification_internal_activity') {
$query_old_where []= "notif.id = '" . $record->id . "'";
}
else {
$query_new_where []= "notif.id = '" . $record->id . "'";
}
}
}
$query = "";
$variables = array();
if (count($query_old_where) > 0) {
$query .= "
SELECT notif.id, notif.ctime, 'notification_internal_activity' AS msgtable,";
if (is_mysql()) {
$query .= "
IF (LOWER(notif.subject) LIKE ?, 1, 0) AS in_subject,
IF (LOWER(notif.message) LIKE ?, 1, 0) AS in_message,
IF (LOWER(CONCAT(uuser.username, ' ', uuser.firstname, ' ', uuser.lastname)) LIKE ?, 1, 0) AS in_sender,
IF (LOWER(CONCAT(fuser.username, ' ', fuser.firstname, ' ', fuser.lastname)) LIKE ?, 1, 0) AS in_recipient";
}
else {
$query .= "
CASE WHEN LOWER(notif.subject) LIKE ? THEN 1 ELSE 0 END As in_subject,
CASE WHEN LOWER(notif.message) LIKE ? THEN 1 ELSE 0 END AS in_message,
CASE WHEN LOWER(uuser.username || ' ' || uuser.firstname || ' ' || uuser.lastname) LIKE ? THEN 1 ELSE 0 END AS in_sender,
CASE WHEN LOWER(fuser.username || ' ' || fuser.firstname || ' ' || fuser.lastname) LIKE ? THEN 1 ELSE 0 END AS in_recipient
";
}
// Add variables for the ?-placeholders, it's 4, both times
for ($i = 0; $i < 4; $i++) {
$variables []= $searchstring;
}
$query .= "
FROM {notification_internal_activity} AS notif
INNER JOIN {activity_type} AS atype
ON notif.type = atype.id";
if ('outbox.php' === $location) {
$query .= " AND atype.name != 'newpost'";
}
$query .= "
LEFT JOIN {usr} AS uuser
ON uuser.id = notif.from
INNER JOIN {usr} AS fuser
ON fuser.id = notif.usr
" . $typesql . "
WHERE (" . (count($query_old_where) > 0 ? join(' OR ', $query_old_where) : "TRUE") . ")";
if (is_mysql()) {
$query .= "
HAVING (LOWER(in_subject) + LOWER(in_message) + LOWER(in_sender) + LOWER(in_recipient) > 0)";
}
else {
$query .= "
AND (
LOWER(notif.subject) LIKE ?
OR LOWER(notif.message) LIKE ?
OR LOWER(uuser.username || ' ' || uuser.firstname || ' ' || uuser.lastname) LIKE ?
OR LOWER(fuser.username || ' ' || fuser.firstname || ' ' || fuser.lastname) LIKE ?
)";
// for the postgres-condition we have another 4 placeholders
for ($i = 0; $i < 4; $i++) {
$variables []= $searchstring;
}
}
if (count($query_new_where) > 0) {
$query .= "
)
UNION
(
";
}
}
if (count($query_new_where) > 0) {
$query .= "
SELECT notif.id, notif.ctime, 'module_multirecipient_notification' AS msgtable,";
if (is_mysql()) {
$query .= "
IF (LOWER(notif.subject) LIKE ?, 1, 0) AS in_subject,
IF (LOWER(notif.message) LIKE ?, 1, 0) AS in_message,
IF (relation.role = 'sender' AND LOWER(CONCAT(usr.username, ' ', usr.firstname, ' ', usr.lastname)) LIKE ?, 1, 0) AS in_sender,
IF (relation.role = 'recipient' AND LOWER(CONCAT(usr.username, ' ', usr.firstname, ' ', usr.lastname)) LIKE ?, 1, 0) AS in_recipient";
}