Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
mahara
mahara
Commits
82519cc6
Commit
82519cc6
authored
May 03, 2010
by
Richard Mansfield
Browse files
Use paginator for inbox instead of tablerender; use notification icons
Signed-off-by:
Richard Mansfield
<
richardm@catalyst.net.nz
>
parent
bd3c9f41
Changes
6
Hide whitespace changes
Inline
Side-by-side
htdocs/account/activity/index.json.php
View file @
82519cc6
...
...
@@ -30,115 +30,80 @@ define('JSON', 1);
require
(
dirname
(
dirname
(
dirname
(
__FILE__
)))
.
'/init.php'
);
json_headers
();
$readone
=
param_integer
(
'readone'
,
0
);
$markasread
=
param_integer
(
'markasread'
,
0
);
$delete
=
param_integer
(
'delete'
,
0
);
$quiet
=
param_integer
(
'quiet'
,
0
);
if
(
$markasread
)
{
$count
=
0
;
db_begin
();
try
{
foreach
(
$_GET
as
$k
=>
$v
)
{
if
(
preg_match
(
'/^unread\-(\d+)$/'
,
$k
,
$m
))
{
set_field
(
'notification_internal_activity'
,
'read'
,
1
,
'id'
,
$m
[
1
],
'usr'
,
$USER
->
get
(
'id'
));
$count
++
;
}
}
}
catch
(
Exception
$e
)
{
db_rollback
();
json_reply
(
'local'
,
get_string
(
'failedtomarkasread'
,
'activity'
)
.
': '
.
$e
->
getMessage
());
}
db_commit
();
if
(
$quiet
)
{
json_reply
(
false
,
null
);
}
json_reply
(
false
,
array
(
'message'
=>
get_string
(
'markedasread'
,
'activity'
),
'count'
=>
$count
));
}
else
if
(
$delete
)
{
$count
=
0
;
db_begin
();
try
{
foreach
(
$_GET
as
$k
=>
$v
)
{
if
(
preg_match
(
'/^delete\-(\d+)$/'
,
$k
,
$m
))
{
delete_records
(
'notification_internal_activity'
,
'id'
,
$m
[
1
],
'usr'
,
$USER
->
get
(
'id'
));
$count
++
;
}
}
}
catch
(
Exception
$e
)
{
db_rollback
();
json_reply
(
'local'
,
get_string
(
'failedtodeletenotifications'
,
'activity'
)
.
': '
.
$e
->
getMessage
());
}
db_commit
();
safe_require
(
'notification'
,
'internal'
);
json_reply
(
false
,
array
(
'message'
=>
get_string
(
'deletednotifications'
,
'activity'
,
$count
),
'count'
=>
$count
,
'newunreadcount'
=>
call_static_method
(
generate_class_name
(
'notification'
,
'internal'
),
'unread_count'
,
$USER
->
get
(
'id'
))
));
if
(
$readone
)
{
set_field
(
'notification_internal_activity'
,
'read'
,
1
,
'id'
,
$readone
,
'usr'
,
$USER
->
get
(
'id'
));
json_reply
(
false
,
null
);
}
// normal processing
require_once
(
get_config
(
'libroot'
)
.
'activity.php'
);
$type
=
param_variable
(
'type'
,
'all'
);
$limit
=
param_integer
(
'limit'
,
10
);
$offset
=
param_integer
(
'offset'
,
0
);
$
userid
=
$USER
->
get
(
'id'
)
;
$
message
=
false
;
$typesql
=
''
;
if
(
$type
!=
'all'
)
{
$types
=
split
(
','
,
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)'
;
if
(
$markasread
)
{
$ids
=
array
();
foreach
(
$_GET
as
$k
=>
$v
)
{
if
(
preg_match
(
'/^unread\-(\d+)$/'
,
$k
,
$m
))
{
$ids
[]
=
$m
[
1
];
}
$typesql
=
' AND '
.
$typesql
;
}
if
(
$ids
)
{
set_field_select
(
'notification_internal_activity'
,
'read'
,
1
,
'id IN ('
.
join
(
','
,
$ids
)
.
') AND usr = ?'
,
array
(
$USER
->
get
(
'id'
))
);
}
$message
=
get_string
(
'markedasread'
,
'activity'
);
}
$from
=
"
FROM
{
notification_internal_activity
}
a
JOIN
{
activity_type
}
at ON a.type = at.id
WHERE a.usr = ?
$typesql
"
;
$values
=
array
(
$userid
);
$count
=
count_records_sql
(
'SELECT COUNT(*)'
.
$from
,
$values
);
$records
=
get_records_sql_array
(
'
SELECT a.*, at.name AS type,at.plugintype, at.pluginname'
.
$from
.
'
ORDER BY a.ctime DESC'
,
$values
,
$offset
,
$limit
);
if
(
empty
(
$records
))
{
$records
=
array
();
else
if
(
$delete
)
{
$ids
=
array
();
foreach
(
$_GET
as
$k
=>
$v
)
{
if
(
preg_match
(
'/^delete\-(\d+)$/'
,
$k
,
$m
))
{
$ids
[]
=
$m
[
1
];
}
}
if
(
$ids
)
{
$strids
=
join
(
','
,
$ids
);
$userid
=
$USER
->
get
(
'id'
);
db_begin
();
execute_sql
(
"
UPDATE
{
notification_internal_activity
}
SET parent = NULL
WHERE parent IN (
SELECT id
FROM
{
notification_internal_activity
}
WHERE id IN (
$strids
) AND usr = ?
)"
,
array
(
$userid
)
);
delete_records_select
(
'notification_internal_activity'
,
"id IN (
$strids
) AND usr = ?"
,
array
(
$userid
)
);
db_commit
();
}
$message
=
get_string
(
'deletednotifications'
,
'activity'
,
count
(
$ids
));
}
$data
=
array
();
$star
=
$THEME
->
get_url
(
'images/star.png'
);
$unread
=
get_string
(
'unread'
,
'activity'
);
foreach
(
$records
as
&
$r
)
{
$r
->
date
=
format_date
(
strtotime
(
$r
->
ctime
));
$section
=
'activity'
;
if
(
!
empty
(
$r
->
plugintype
))
{
$section
=
$r
->
plugintype
.
'.'
.
$r
->
pluginname
;
}
$r
->
type
=
get_string
(
'type'
.
$r
->
type
,
$section
);
$r
->
message
=
clean_html
(
format_whitespace
(
$r
->
message
));
$newhtml
=
activitylist_html
(
$type
,
$limit
,
$offset
);
if
(
$message
)
{
safe_require
(
'notification'
,
'internal'
);
$newhtml
[
'newunreadcount'
]
=
call_static_method
(
generate_class_name
(
'notification'
,
'internal'
),
'unread_count'
,
$USER
->
get
(
'id'
)
);
}
$activity
=
array
(
'count'
=>
$count
,
'offset'
=>
$offset
,
'limit'
=>
$limit
,
'data'
=>
$records
,
'star'
=>
$star
,
'unread'
=>
$unread
,
);
json_reply
(
false
,
(
object
)
array
(
'message'
=>
$message
,
'data'
=>
$newhtml
));
echo
json_encode
(
$activity
);
?>
htdocs/account/activity/index.php
View file @
82519cc6
...
...
@@ -59,60 +59,19 @@ if ($USER->get('admin')) {
$type
=
param_variable
(
'type'
,
'all'
);
if
(
!
isset
(
$options
[
$type
]))
{
// Comma-separated list; filter out anything that's not an installed type
$type
s
=
join
(
','
,
array_unique
(
array_filter
(
$type
=
join
(
','
,
array_unique
(
array_filter
(
split
(
','
,
$type
),
create_function
(
'$a'
,
'global $installedtypes; return isset($installedtypes[$a]);'
)
)));
}
$strtype
=
json_encode
(
$type
);
$morestr
=
get_string
(
'more...'
);
require_once
(
'activity.php'
);
$activitylist
=
activitylist_html
(
$type
);
$star
=
json_encode
(
$THEME
->
get_url
(
'images/star.png'
));
$
un
read
=
json_encode
(
get_string
(
'
un
read'
,
'activity'
));
$
str
read
=
json_encode
(
get_string
(
'read'
,
'activity'
));
$javascript
=
<<<JAVASCRIPT
var activitylist = new TableRenderer(
'activitylist',
'index.json.php',
[
function(r) {
if (r.message) {
var messagemore = DIV({'id' : 'message-' + r.id, 'style': 'display:none'});
messagemore.innerHTML = r.message;
if (r.url) {
appendChildNodes(messagemore, BR(null), A({'href' : r.url, 'class': 's'}, '{$morestr}'));
}
return TD(null, A({'href': '', 'onclick': 'showHideMessage(' + r.id + '); return false;'}, r.subject),
messagemore);
}
else if (r.url) {
return TD(null, A({'href': r.url}, r.subject));
}
else {
return TD(null, r.subject);
}
},
'type',
'date',
function (r, d) {
if (r.read == 1) {
return TD({'class': 'center'},IMG({'src' : d.star, 'alt' : d.unread}));
}
else {
return TD({'class': 'center'}, INPUT({'type' : 'checkbox', 'class' : 'tocheckread', 'name' : 'unread-' + r.id}));
}
},
function (r, d) {
return TD({'class': 'center'}, INPUT({'type' : 'checkbox', 'class' : 'tocheckdel', 'name' : 'delete-' + r.id}));
}
]
);
activitylist.type = {$strtype};
activitylist.statevars.push('type');
activitylist.updateOnLoad();
function markread(form, action) {
...
...
@@ -130,20 +89,18 @@ function markread(form, action) {
} else if (action == 'del') {
pd['delete'] = 1;
}
if (paginatorData) {
for (p in paginatorData.params) {
pd[p] = paginatorData.params[p];
}
}
sendjsonrequest('index.json.php', pd, 'GET', function (data) {
if (!data.error) {
if (data.count > 0) {
activitylist.doupdate();
if (data.newunreadcount && typeof(data.newunreadcount) != 'undefined') {
updateUnreadCount(data.newunreadcount, 'reset');
} else {
updateUnreadCount(data.count, 'decrement');
}
}
paginator.updateResults(data);
if (data.newunreadcount && typeof(data.newunreadcount) != 'undefined') {
updateUnreadCount(data.newunreadcount, 'reset');
}
}, function () {
activitylist.doupdate();
});
}
...
...
@@ -175,25 +132,61 @@ function updateUnreadCount(n, decrement) {
}
function showHideMessage(id) {
if (getStyle('message-' + id, 'display') == 'none') {
var unread = getFirstElementByTagAndClassName('input', 'tocheckread',
$('message-' + id).parentNode.parentNode);
var message = $('message-' + id);
if (!message) {
return;
}
if (hasElementClass(message, 'hidden')) {
var unread = getFirstElementByTagAndClassName(
'input', 'tocheckread', message.parentNode.parentNode
);
if (unread) {
var pd = {'markasread':1, 'quiet':1};
pd['unread-'+id] = 1;
var pd = {'readone':id};
sendjsonrequest('index.json.php', pd, 'GET', function(data) {
return !!data.error;
swapDOM(unread, IMG({'src' : {$star}, 'alt' : {$strread}}));
updateUnreadCount(1, 'decrement');
});
swapDOM(unread, IMG({'src' : {$star}, 'alt' : {$unread}}));
updateUnreadCount(1, 'decrement');
}
show
Element(
'
message
-' + id
);
remove
Element
Class
(message
, 'hidden'
);
}
else {
hideElement('message-' + id);
addElementClass(message, 'hidden');
}
}
function changeactivitytype() {
var params = {'type': this.options[this.selectedIndex].value};
sendjsonrequest('index.json.php', params, 'GET', function(data) {
paginator.updateResults(data);
});
}
// We want the paginator to tell us when a page gets changed.
// @todo: remember checked/unchecked state when changing pages
function PaginatorData() {
var self = this;
var params = {};
this.pageChanged = function(data) {
self.params = {
'offset': data.offset,
'limit': data.limit,
'type': data.type
}
}
paginatorProxy.addObserver(self);
connect(self, 'pagechanged', self.pageChanged);
}
var paginator;
var paginatorData = new PaginatorData();
addLoadEvent(function () {
paginator = {$activitylist['pagination_js']}
connect('notifications_type', 'onchange', changeactivitytype);
});
JAVASCRIPT;
$deleteall
=
pieform
(
array
(
...
...
@@ -219,16 +212,16 @@ function delete_all_notifications_submit() {
redirect
(
get_config
(
'wwwroot'
)
.
'account/activity/index.php'
);
}
$smarty
=
smarty
(
array
(
'
tablerendere
r'
));
$smarty
=
smarty
(
array
(
'
paginato
r'
));
$smarty
->
assign
(
'selectallread'
,
'toggleChecked(\'tocheckread\'); return false;'
);
$smarty
->
assign
(
'selectalldel'
,
'toggleChecked(\'tocheckdel\'); return false;'
);
$smarty
->
assign
(
'markread'
,
'markread(this, \'read\'); return false;'
);
$smarty
->
assign
(
'markdel'
,
'markread(document.notificationlist, \'del\'); return false;'
);
$smarty
->
assign
(
'typechange'
,
'activitylist.type = this.options[this.selectedIndex].value; activitylist.doupdate();'
);
$smarty
->
assign
(
'options'
,
$options
);
$smarty
->
assign
(
'type'
,
$type
);
$smarty
->
assign
(
'INLINEJAVASCRIPT'
,
$javascript
);
$smarty
->
assign
(
'PAGEHEADING'
,
hsc
(
get_string
(
'inbox'
)));
$smarty
->
assign
(
'deleteall'
,
$deleteall
);
$smarty
->
assign
(
'activitylist'
,
$activitylist
);
$smarty
->
display
(
'account/activity/index.tpl'
);
?>
htdocs/lib/activity.php
View file @
82519cc6
...
...
@@ -883,4 +883,79 @@ abstract class ActivityTypePlugin extends ActivityType {
}
}
?>
/**
* Get one page of notifications and return html
*/
function
activitylist_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
=
split
(
','
,
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
;
}
}
$from
=
"
FROM
{
notification_internal_activity
}
a
JOIN
{
activity_type
}
at ON a.type = at.id
WHERE a.usr = ?
$typesql
"
;
$values
=
array
(
$userid
);
$count
=
count_records_sql
(
'SELECT COUNT(*)'
.
$from
,
$values
);
$pagination
=
build_pagination
(
array
(
'id'
=>
'activitylist_pagination'
,
'url'
=>
get_config
(
'wwwroot'
)
.
'account/activity/index.php?type='
.
hsc
(
$type
),
'jsonscript'
=>
'account/activity/index.json.php'
,
'datatable'
=>
'activitylist'
,
'count'
=>
$count
,
'limit'
=>
$limit
,
'offset'
=>
$offset
,
));
$result
=
array
(
'count'
=>
$count
,
'limit'
=>
$limit
,
'offset'
=>
$offset
,
'type'
=>
$type
,
'tablerows'
=>
''
,
'pagination'
=>
$pagination
[
'html'
],
'pagination_js'
=>
$pagination
[
'javascript'
],
);
if
(
$count
<
1
)
{
return
$result
;
}
$records
=
get_records_sql_array
(
'
SELECT
a.*, at.name AS type, at.plugintype, at.pluginname'
.
$from
.
'
ORDER BY a.ctime DESC'
,
$values
,
$offset
,
$limit
);
if
(
$records
)
{
foreach
(
$records
as
&
$r
)
{
$r
->
date
=
format_date
(
strtotime
(
$r
->
ctime
),
'strfdaymonthyearshort'
);
$section
=
empty
(
$r
->
plugintype
)
?
'activity'
:
"
{
$r
->
plugintype
}
.
{
$r
->
pluginname
}
"
;
$r
->
strtype
=
get_string
(
'type'
.
$r
->
type
,
$section
);
$r
->
message
=
clean_html
(
format_whitespace
(
$r
->
message
));
}
}
$smarty
=
smarty_core
();
$smarty
->
assign
(
'data'
,
$records
);
$result
[
'tablerows'
]
=
$smarty
->
fetch
(
'account/activity/activitylist.tpl'
);
return
$result
;
}
htdocs/theme/raw/static/style/style.css
View file @
82519cc6
...
...
@@ -1564,7 +1564,7 @@ form#search input.text {
position
:
relative
;
top
:
-30px
;
left
:
-15px
;
width
:
5
0%
;
width
:
1
0%
;
}
/* Settings > Institution membership */
...
...
htdocs/theme/raw/templates/account/activity/activitylist.tpl
0 → 100644
View file @
82519cc6
{
foreach
from
=
$data
item
=
item
}
<tr
class=
"
{
cycle
values
=
'r0,r1'
}
"
>
<td>
<img
src=
"
{
theme_url
filename
=
cat
(
'images/'
$item
->
type
'.gif'
)
}
"
alt=
"
{
$item
->
strtype
|
escape
}
"
/>
</td>
<td>
{
if
$item
->
message
}
<a
href=
""
onclick=
"showHideMessage(
{
$item
->
id
}
); return false;"
>
{
$item
->
subject
|
escape
}
</a>
<div
id=
"message-
{
$item
->
id
}
"
class=
"hidden"
>
{
$item
->
message
|
clean_html
}
{
if
$item
->
url
}
<br><a
href=
"
{
$item
->
url
|
escape
}
"
class=
"s"
>
{
str
tag
=
"more..."
}
</a>
{/
if
}
</div>
{
elseif
$item
->
url
}
<a
href=
"
{
$item
->
url
|
escape
}
"
>
{
$item
->
subject
|
escape
}
</a>
{
else
}
{
$item
->
subject
|
escape
}
{/
if
}
</td>
<td>
{
$item
->
date
|
escape
}
</td>
<td
class=
"center"
>
{
if
$item
->
read
}
<img
src=
"
{
theme_url
filename
=
'images/star.png'
}
"
alt=
"
{
str
tag
=
read
section
=
activity
}
"
>
{
else
}
<input
type=
"checkbox"
class=
"tocheckread"
name=
"unread-
{
$item
->
id
|
escape
}
"
>
{/
if
}
</td>
<td
class=
"center"
><input
type=
"checkbox"
class=
"tocheckdel"
name=
"delete-
{
$item
->
id
|
escape
}
"
></td>
</tr>
{/
foreach
}
htdocs/theme/raw/templates/account/activity/index.tpl
View file @
82519cc6
...
...
@@ -3,7 +3,7 @@
<div
id=
"notifications"
>
<form
method=
"post"
>
<label>
{
str
section
=
'activity'
tag
=
'type'
}
:
</label>
<select
name=
"type"
onChang
e=
"
{
$
type
change
}
"
>
<select
id=
"notifications_type"
nam
e=
"type"
>
<option
value=
"all"
>
--
</option>
{
foreach
from
=
$options
item
=
name
key
=
t
}
<option
value=
"
{
$t
}
"
{
if
$type
==
$t
}
selected
{/
if
}
>
{
$name
}
</option>
...
...
@@ -14,8 +14,8 @@
<table
id=
"activitylist"
class=
"fullwidth"
>
<thead>
<tr>
<th></th>
<th>
{
str
section
=
'activity'
tag
=
'subject'
}
</th>
<th>
{
str
section
=
'activity'
tag
=
'type'
}
</th>
<th>
{
str
section
=
'activity'
tag
=
'date'
}
</th>
<th
width=
"50"
class=
"center"
>
{
str
section
=
'activity'
tag
=
'read'
}
<br><a
href=
""
onclick=
"
{
$selectallread
}
"
>
{
str
section
=
'activity'
tag
=
'selectall'
}
</a></th>
<th
width=
"50"
class=
"center"
>
{
str
tag
=
'delete'
}
<br><a
href=
""
onclick=
"
{
$selectalldel
}
"
>
{
str
section
=
'activity'
tag
=
'selectall'
}
</a></th>
...
...
@@ -29,10 +29,13 @@
</td>
</tr>
</tfoot>
<tbody></tbody>
<tbody>
{
$activitylist.tablerows
}
</tbody>
</table>
{
$activitylist.pagination
}
</form>
</div>
{
$deleteall
}
<div
class=
"left"
>
{
$deleteall
}
</div>
{
include
file
=
"footer.tpl"
}
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment