Commit 16892d04 authored by Son Nguyen's avatar Son Nguyen Committed by Robert Lyon
Browse files

Fix paginators in participation report (Bug 1367077)

Refactor the query
Add json update for pagination

Change-Id: I8f9ffb67c928f95187e3429492d8e7893d24d61d
parent a4bca185
<?php
/**
*
* @package mahara
* @subpackage core
* @author Son Nguyen <son.nguyen@catalyst.net.nz>, Catalyst IT, NZ
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL version 3 or later
* @copyright For copyright information on Mahara, please see the README file distributed with this software.
*/
define('INTERNAL', 1);
define('JSON', 1);
require(dirname(dirname(__FILE__)) . '/init.php');
require_once(get_config('libroot') . 'view.php');
require_once(get_config('libroot') . 'group.php');
require_once(get_config('libroot') . 'pieforms/pieform.php');
define('GROUP', param_integer('group'));
$wwwroot = get_config('wwwroot');
$limit = param_integer('limit', 0);
$userlimit = get_account_preference($USER->get('id'), 'viewsperpage');
if ($limit > 0 && $limit != $userlimit) {
$USER->set_account_preference('viewsperpage', $limit);
}
else {
$limit = $userlimit;
}
$offset = param_integer('offset', 0);
$sort = param_variable('sort', 'title');
$direction = param_variable('direction', 'asc');
$group = group_current_group();
$role = group_user_access($group->id);
if (!group_role_can_access_report($group, $role)) {
json_reply(true, get_string('accessdenied', 'error'));
}
$limit = ($limit > 0) ? $limit : 10;
$groupviews = View::get_participation_groupviews_data($group->id, $sort, $direction, $limit, $offset);
$pagination = array(
'baseurl' => $wwwroot . 'group/report.php?group=' . $group->id . '&sort=' . $sort . '&direction=' . $direction,
'id' => 'groupviews_pagination',
'datatable' => 'groupviewsreport',
'jsonscript' => 'group/participationgroupviews.json.php',
'setlimit' => true,
'resultcounttextsingular' => get_string('view', 'view'),
'resultcounttextplural' => get_string('views', 'view'),
);
View::render_participation_views($groupviews, 'group/participationgroupviews.tpl', $pagination);
json_reply(false, array('data' => $groupviews));
<?php
/**
*
* @package mahara
* @subpackage core
* @author Son Nguyen <son.nguyen@catalyst.net.nz>, Catalyst IT, NZ
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL version 3 or later
* @copyright For copyright information on Mahara, please see the README file distributed with this software.
*/
define('INTERNAL', 1);
define('JSON', 1);
require(dirname(dirname(__FILE__)) . '/init.php');
require_once(get_config('libroot') . 'view.php');
require_once(get_config('libroot') . 'group.php');
require_once(get_config('libroot') . 'pieforms/pieform.php');
define('GROUP', param_integer('group'));
$wwwroot = get_config('wwwroot');
$limit = param_integer('limit', 0);
$userlimit = get_account_preference($USER->get('id'), 'viewsperpage');
if ($limit > 0 && $limit != $userlimit) {
$USER->set_account_preference('viewsperpage', $limit);
}
else {
$limit = $userlimit;
}
$offset = param_integer('offset', 0);
$sort = param_variable('sort', 'title');
$direction = param_variable('direction', 'asc');
$group = group_current_group();
$role = group_user_access($group->id);
if (!group_role_can_access_report($group, $role)) {
json_reply(true, get_string('accessdenied', 'error'));
}
$limit = ($limit > 0) ? $limit : 10;
$sharedviews = View::get_participation_sharedviews_data($group->id, $sort, $direction, $limit, $offset);
$pagination = array(
'baseurl' => $wwwroot . 'group/report.php?group=' . $group->id . '&sort=' . $sort . '&direction=' . $direction,
'id' => 'sharedviews_pagination',
'datatable' => 'sharedviewsreport',
'jsonscript' => 'group/participationsharedviews.json.php',
'setlimit' => true,
'resultcounttextsingular' => get_string('view', 'view'),
'resultcounttextplural' => get_string('views', 'view'),
);
View::render_participation_views($sharedviews, 'group/participationsharedviews.tpl', $pagination);
json_reply(false, array('data' => $sharedviews));
......@@ -20,8 +20,14 @@ define('GROUP', param_integer('group'));
$wwwroot = get_config('wwwroot');
$needsubdomain = get_config('cleanurlusersubdomains');
$setlimit = true;
$limit = param_integer('limit', 10);
$limit = param_integer('limit', 0);
$userlimit = get_account_preference($USER->get('id'), 'viewsperpage');
if ($limit > 0 && $limit != $userlimit) {
$USER->set_account_preference('viewsperpage', $limit);
}
else {
$limit = $userlimit;
}
$offset = param_integer('offset', 0);
$sort = param_variable('sort', 'title');
$direction = param_variable('direction', 'asc');
......@@ -31,162 +37,39 @@ if (!group_role_can_access_report($group, $role)) {
throw new AccessDeniedException();
}
$commentoptions = ArtefactTypeComment::get_comment_options();
$commentoptions->limit = 0;
$sharedviews = View::get_sharedviews_data(0, null, $group->id);
$sharedviewscount = $sharedviews->count;
$sharedviews = $sharedviews->data;
foreach ($sharedviews as &$data) {
if (isset($data['group'])) {
$data['groupname'] = get_field('group', 'name', 'id', $data['group']);
}
$view = new View($data['id']);
$commentoptions->view = $view;
$comments = ArtefactTypeComment::get_comments($commentoptions);
$extcommenters = 0;
$membercommenters = 0;
$extcomments = 0;
$membercomments = 0;
$commenters = array();
foreach ($comments->data as $c) {
if (empty($c->author)) {
if (!isset($commenters[$c->authorname])) {
$commenters[$c->authorname] = array();
}
$commenters[$c->authorname]['commenter'] = $c->authorname;
$commenters[$c->authorname]['count'] = (isset($commenters[$c->authorname]['count']) ? $commenters[$c->authorname]['count'] + 1 : 1);
if ($commenters[$c->authorname]['count'] == 1) {
$extcommenters++;
}
$extcomments++;
}
else {
if (!isset($commenters[$c->author->id])) {
$commenters[$c->author->id] = array();
}
$commenters[$c->author->id]['commenter'] = (int) $c->author->id;
$commenters[$c->author->id]['member'] = group_user_access($group->id, $c->author->id);
$commenters[$c->author->id]['count'] = (isset($commenters[$c->author->id]['count']) ? $commenters[$c->author->id]['count'] + 1 : 1);
if (empty($commenters[$c->author->id]['member'])) {
if ($commenters[$c->author->id]['count'] == 1) {
$extcommenters++;
}
$extcomments++;
}
else {
if ($commenters[$c->author->id]['count'] == 1) {
$membercommenters++;
}
$membercomments++;
}
}
}
sorttablebycolumn($commenters, 'count', 'desc');
$data['mcommenters'] = $membercommenters;
$data['ecommenters'] = $extcommenters;
$data['mcomments'] = $membercomments;
$data['ecomments'] = $extcomments;
$data['comments'] = $commenters;
$data['baseurl'] = $needsubdomain ? $view->get_url(true) : ($wwwroot . $view->get_url(false));
}
if (in_array($sort, array('title', 'sharedby', 'mcomments', 'ecomments'))) {
sorttablebycolumn($sharedviews, $sort, $direction);
}
$sharedviews = array_slice($sharedviews, $offset, $limit);
list($searchform, $groupviews, $unusedpagination) = View::views_by_owner($group->id);
$groupviews = $groupviews->data;
$groupviewscount = count($groupviews);
$sharedviews = View::get_participation_sharedviews_data($group->id, $sort, $direction, $limit, $offset);
foreach ($groupviews as &$data) {
$view = new View($data['id']);
$commentoptions->view = $view;
$comments = ArtefactTypeComment::get_comments($commentoptions);
$pagination = array(
'baseurl' => $wwwroot . 'group/report.php?group=' . $group->id . '&sort=' . $sort . '&direction=' . $direction,
'id' => 'sharedviews_pagination',
'datatable' => 'sharedviewsreport',
'jsonscript' => 'group/participationsharedviews.json.php',
'setlimit' => true,
'resultcounttextsingular' => get_string('view', 'view'),
'resultcounttextplural' => get_string('views', 'view'),
);
$extcommenters = 0;
$membercommenters = 0;
$extcomments = 0;
$membercomments = 0;
$commenters = array();
foreach ($comments->data as $c) {
if (empty($c->author)) {
if (!isset($commenters[$c->authorname])) {
$commenters[$c->authorname] = array();
}
$commenters[$c->authorname]['commenter'] = $c->authorname;
$commenters[$c->authorname]['count'] = (isset($commenters[$c->authorname]['count']) ? $commenters[$c->authorname]['count'] + 1 : 1);
if ($commenters[$c->authorname]['count'] == 1) {
$extcommenters++;
}
$extcomments++;
}
else {
if (!isset($commenters[$c->author->id])) {
$commenters[$c->author->id] = array();
}
$commenters[$c->author->id]['commenter'] = (int) $c->author->id;
$commenters[$c->author->id]['member'] = group_user_access($group->id, $c->author->id);
$commenters[$c->author->id]['count'] = (isset($commenters[$c->author->id]['count']) ? $commenters[$c->author->id]['count'] + 1 : 1);
if (empty($commenters[$c->author->id]['member'])) {
if ($commenters[$c->author->id]['count'] == 1) {
$extcommenters++;
}
$extcomments++;
}
else {
if ($commenters[$c->author->id]['count'] == 1) {
$membercommenters++;
}
$membercomments++;
}
}
}
View::render_participation_views($sharedviews, 'group/participationsharedviews.tpl', $pagination);
$data['id'] = (int) $data['id'];
$data['mcommenters'] = $membercommenters;
$data['ecommenters'] = $extcommenters;
$data['mcomments'] = $membercomments;
$data['ecomments'] = $extcomments;
$data['comments'] = $commenters;
$data['title'] = $data['displaytitle'];
}
if (in_array($sort, array('title', 'mcomments', 'ecomments'))) {
sorttablebycolumn($groupviews, $sort, $direction);
}
$groupviews = array_slice($groupviews, $offset, $limit);
$groupviews = View::get_participation_groupviews_data($group->id, $sort, $direction, $limit, $offset);
$pagination = build_pagination(array(
'url' => get_config('wwwroot') . 'group/report.php?group=' . $group->id,
'count' => max($sharedviewscount, $groupviewscount),
'limit' => $limit,
'setlimit' => $setlimit,
'offset' => $offset,
'jumplinks' => 6,
'numbersincludeprevnext' => 2,
));
$pagination = array(
'baseurl' => $wwwroot . 'group/report.php?group=' . $group->id . '&sort=' . $sort . '&direction=' . $direction,
'id' => 'groupviews_pagination',
'datatable' => 'groupviewsreport',
'jsonscript' => 'group/participationgroupviews.json.php',
'setlimit' => true,
'resultcounttextsingular' => get_string('view', 'view'),
'resultcounttextplural' => get_string('views', 'view'),
);
$js = <<< EOF
addLoadEvent(function () {
p = {$pagination['javascript']}
});
EOF;
View::render_participation_views($groupviews, 'group/participationgroupviews.tpl', $pagination);
$smarty = smarty(array('paginator'));
$smarty->assign('baseurl', get_config('wwwroot') . 'group/report.php?group=' . $group->id);
$smarty->assign('heading', $group->name);
$smarty->assign('sharedviews', $sharedviews);
$smarty->assign('groupviews', $groupviews);
$smarty->assign('pagination', $pagination['html']);
$smarty->assign('INLINEJAVASCRIPT', $js);
$smarty->assign('gvcount', $groupviewscount);
$smarty->assign('svcount', $sharedviewscount);
$smarty->assign('sort', $sort);
$smarty->assign('direction', $direction);
$smarty->display('group/report.tpl');
......@@ -110,6 +110,9 @@ var Paginator = function(id, datatable, heading, script, extradata) {
if (loc != -1) {
queryData = parseQueryString(url.substring(loc + 1, url.length));
queryData.offset = currentoffset.value;
if ((queryData.offset % setlimitselect.value) !== 0) {
queryData.offset = Math.floor(queryData.offset / setlimitselect.value) * setlimitselect.value;
}
queryData.setlimit = "1";
queryData.limit = setlimitselect.value;
queryData.extradata = serializeJSON(self.extraData);
......
......@@ -4391,6 +4391,312 @@ class View {
);
}
/**
* Get all group views and its participation info excluding the view in collections
*
* @param int $groupid ID of the group
* @param string $sort in ('title', 'owner', 'membercommentcount', 'nonmembercommentcount')
* @param string $direction = 'asc' or 'desc'
* @param int $limit
* @param int $offset
* @throws AccessDeniedException if the logged-in user is not the group admin or member
* @return array(
'data' => array(),
'count' => $count,
'limit' => $limit,
'offset' => $offset,
);
*/
public static function get_participation_groupviews_data($groupid, $sort, $direction, $limit=10, $offset=0) {
global $USER;
$userid = $USER->get('id');
require_once(get_config('libroot') . 'group.php');
if (!group_user_access($groupid)) {
throw new AccessDeniedException(get_string('accessdenied', 'error'));
}
// Query group views with number of member comments
$sql1 = "
SELECT DISTINCT v.id, count(DISTINCT ac.artefact) AS membercommentcount
FROM {view} v
LEFT JOIN (
SELECT c.*
FROM {artefact_comment_comment} c
INNER JOIN {artefact} a ON (a.id = c.artefact)
WHERE EXISTS (SELECT 1 FROM {group_member} m2 WHERE m2.group = ? AND m2.member = a.author)
) ac ON (ac.onview = v.id)
WHERE v.group = ?
AND NOT EXISTS (SELECT 1 FROM {collection_view} cv WHERE cv.view = v.id)
GROUP BY v.id ";
$ph = array($groupid, $groupid);
// Query shared views with number of non-member comments
$sql2 = "
SELECT DISTINCT v.id, count(DISTINCT ac.artefact) AS nonmembercommentcount
FROM {view} v
LEFT JOIN (
SELECT c.*
FROM {artefact_comment_comment} c
INNER JOIN {artefact} a ON (a.id = c.artefact)
WHERE NOT EXISTS (SELECT 1 FROM {group_member} m2 WHERE m2.group = ? AND m2.member = a.author)
) ac ON (ac.onview = v.id)
WHERE v.group = ?
AND NOT EXISTS (SELECT 1 FROM {collection_view} cv WHERE cv.view = v.id)
GROUP BY v.id ";
$ph = array_merge($ph, array($groupid, $groupid));
$from = '
FROM {view} v
INNER JOIN (' . $sql1 . ') pv1 ON (pv1.id = v.id)
INNER JOIN (' . $sql2 . ') pv2 ON (pv2.id = v.id) ';
$count = count_records_sql('SELECT COUNT(DISTINCT(v.id)) ' . $from, $ph);
if (in_array($sort, array('title', 'owner', 'membercommentcount', 'nonmembercommentcount'))
&& in_array($direction, array('asc', 'desc'))) {
$ordersql = "$sort $direction";
}
else {
$ordersql = "v.title, v.id";
}
$viewdata = get_records_sql_assoc('
SELECT DISTINCT v.id,v.title,v.startdate,v.stopdate,v.description,v.group,v.owner,v.ownerformat,v.institution,v.urlid, membercommentcount, nonmembercommentcount'
. $from . '
ORDER BY '. $ordersql,
$ph, $offset, $limit
);
if ($viewdata) {
// Get more info about view comments
foreach ($viewdata as &$view) {
if (isset($view->group)) {
$view->groupname = get_field('group', 'name', 'id', $view->group);
}
$viewobj = new View($view->id);
$view->url = $viewobj->get_url();
self::get_view_comment_info($view, $groupid);
}
}
else {
$viewdata = array();
}
return array(
'data' => array_values($viewdata),
'count' => $count,
'limit' => $limit,
'offset' => $offset,
);
}
/**
* Get (views + their participation info) which have been explicitly shared to a group and are
* not owned by the group excluding the view in collections
*
* @param int $groupid ID of the group
* @param string $sort in ('title', 'owner', 'membercommentcount', 'nonmembercommentcount')
* @param string $direction = 'asc' or 'desc'
* @param int $limit
* @param int $offset
* @throws AccessDeniedException if the logged-in user is not the group admin or member
* @return array(
'data' => array(),
'count' => $count,
'limit' => $limit,
'offset' => $offset,
);
*/
public static function get_participation_sharedviews_data($groupid, $sort, $direction, $limit=10, $offset=0) {
global $USER;
$userid = $USER->get('id');
require_once(get_config('libroot') . 'group.php');
if (!group_user_access($groupid)) {
throw new AccessDeniedException(get_string('accessdenied', 'error'));
}
// Query shared views with number of member comments
$sql1 = "
SELECT DISTINCT v.id, count(DISTINCT ac.artefact) AS membercommentcount
FROM {view} v
INNER JOIN {view_access} va ON (va.view = v.id)
LEFT JOIN (
SELECT c.*
FROM {artefact_comment_comment} c
INNER JOIN {artefact} a ON (a.id = c.artefact)
WHERE EXISTS (SELECT 1 FROM {group_member} m2 WHERE m2.group = ? AND m2.member = a.author)
) ac ON (ac.onview = v.id)
WHERE va.group = ? AND (v.group IS NULL OR v.group != ?)
AND NOT EXISTS (SELECT 1 FROM {collection_view} cv WHERE cv.view = v.id)
GROUP BY v.id ";
$ph = array($groupid, $groupid, $groupid);
// Query shared views with number of non-member comments
$sql2 = "
SELECT DISTINCT v.id, count(DISTINCT ac.artefact) AS nonmembercommentcount
FROM {view} v
INNER JOIN {view_access} va ON (va.view = v.id)
LEFT JOIN (
SELECT c.*
FROM {artefact_comment_comment} c
INNER JOIN {artefact} a ON (a.id = c.artefact)
WHERE NOT EXISTS (SELECT 1 FROM {group_member} m2 WHERE m2.group = ? AND m2.member = a.author)
) ac ON (ac.onview = v.id)
WHERE va.group = ? AND (v.group IS NULL OR v.group != ?)
AND NOT EXISTS (SELECT 1 FROM {collection_view} cv WHERE cv.view = v.id)
GROUP BY v.id ";
$ph = array_merge($ph, array($groupid, $groupid, $groupid));
$from = '
FROM {view} v
INNER JOIN (' . $sql1 . ') pv1 ON (pv1.id = v.id)
INNER JOIN (' . $sql2 . ') pv2 ON (pv2.id = v.id) ';
$count = count_records_sql('SELECT COUNT(DISTINCT(v.id)) ' . $from, $ph);
if (in_array($sort, array('title', 'owner', 'membercommentcount', 'nonmembercommentcount'))
&& in_array($direction, array('asc', 'desc'))) {
$ordersql = "$sort $direction";
}
else {
$ordersql = "v.title, v.id";
}
$viewdata = get_records_sql_assoc('
SELECT DISTINCT v.id,v.title,v.startdate,v.stopdate,v.description,v.group,v.owner,v.ownerformat,v.institution,v.urlid, membercommentcount, nonmembercommentcount'
. $from . '
ORDER BY '. $ordersql,
$ph, $offset, $limit
);
if ($viewdata) {
// Get more info about view comments
foreach ($viewdata as &$view) {
if (isset($view->group)) {
$view->groupname = get_field('group', 'name', 'id', $view->group);
}
$viewobj = new View($view->id);
$view->url = $viewobj->get_url();
self::get_view_comment_info($view, $groupid);
}
}
else {
$viewdata = array();
}
return array(
'data' => array_values($viewdata),
'count' => $count,
'limit' => $limit,
'offset' => $offset,
);
}
/**
* Add comment info to a group view
* - mcommenters: number of group member comments
* - ecommenters: number of nonmember comments
* - mcomments: list of group member comments
* - ecomments: list of group nonmember comments
* - comments: list of all comments
*
* @param $view a view object with $view->id
* @param $groupid a ID of the group that the view is shared with
*/
public static function get_view_comment_info(&$view, $groupid) {
$viewcomments = get_records_sql_array('
SELECT
a.id, a.author, a.authorname, a.ctime, a.mtime, a.description, a.group,
c.private, c.deletedby, c.requestpublic, c.rating, c.lastcontentupdate,
u.username, u.firstname, u.lastname, u.preferredname, u.email, u.staff, u.admin,
u.deleted, u.profileicon, u.urlid
FROM {artefact} a
INNER JOIN {artefact_comment_comment} c ON a.id = c.artefact
LEFT JOIN {usr} u ON a.author = u.id
WHERE c.onview = ?'
, array($view->id));
$extcommenters = 0;
$membercommenters = 0;
$extcomments = 0;
$membercomments = 0;
$commenters = array();
if ($viewcomments && is_array($viewcomments)) {
foreach ($viewcomments as $c) {
if (empty($c->author)) {
if (!isset($commenters[$c->authorname])) {
$commenters[$c->authorname] = array();
}
$commenters[$c->authorname]['commenter'] = $c->authorname;
$commenters[$c->authorname]['count'] = (isset($commenters[$c->authorname]['count']) ? $commenters[$c->authorname]['count'] + 1 : 1);
if ($commenters[$c->authorname]['count'] == 1) {
$extcommenters++;
}
$extcomments++;
}
else {
if (!isset($commenters[$c->author])) {
$commenters[$c->author] = array();
}
$commenters[$c->author]['commenter'] = (int) $c->author;
$commenters[$c->author]['member'] = group_user_access($groupid, $c->author);
$commenters[$c->author]['count'] = (isset($commenters[$c->author]['count']) ? $commenters[$c->author]['count'] + 1 : 1);
if (empty($commenters[$c->author]['member'])) {
if ($commenters[$c->author]['count'] == 1) {
$extcommenters++;
}
$extcomments++;
}
else {
if ($commenters[$c->author]['count'] == 1) {
$membercommenters++;
}
$membercomments++;
}
}
}
}
$view->mcommenters = $membercommenters;
$view->ecommenters = $extcommenters;
$view->mcomments = $membercomments;