Commit 8c08b88b authored by Robert Lyon's avatar Robert Lyon

Bug 1697248: Update report navigation and reports

Introduce a new navigation bar to allow going through the different
types of reports:

- Change the page title according to the selected report section and
  report
- Decide which columns to display in a report
- Configure reports via the "Configure reports" button

Add existing reports into the new interface.

Create new and expand existing reports:

- User activity
- Page activity
- Collaboration

Sponsored by the AAIM project with funding from University of
Sussex and Dublin City University.

Change-Id: I1eb6920890af27c34c902fe22ff5ce3591b73cb0
Signed-off-by: Robert Lyon's avatarRobert Lyon <robertl@catalyst.net.nz>
parent ebd928b1
......@@ -20,6 +20,7 @@ define('SECTION_PAGE', 'usersearch');
define('IGNORE_FETCH_REMOTE_AVATAR', 1);
require_once('searchlib.php');
$SESSION->set('usersforstats', null);
$search = (object) array(
'query' => trim(param_variable('query', '')),
'f' => param_alpha('f', null), // first initial
......
......@@ -29,18 +29,31 @@ if (empty($institution)) {
$institution = 'mahara';
}
}
$start = param_variable('start', null);
$end = param_variable('end', null);
$start = $start ? format_date(strtotime($start), 'strftimew3cdate') : null;
$end = $end ? format_date(strtotime($end), 'strftimew3cdate') : null;
if (empty($extradata->start) && !empty($start)) {
$extradata->start = $start;
}
if (empty($extradata->end) && !empty($end)) {
$extradata->end = $end;
}
$type = param_alpha('type', 'users');
$subtype = param_alpha('subtype', $type);
$extraparams = new stdClass();
$extraparams->type = $type;
$extraparams->subtype = $subtype;
$extraparams->offset = param_integer('offset', 0);
$extraparams->limit = param_integer('limit', 10);
$extraparams->sort = isset($extradata->sort) ? $extradata->sort : 'displayname';
$extraparams->sortdesc = isset($extradata->sortdesc) ? true : false;
$extraparams->start = param_alphanumext('start', null);
$extraparams->end = param_alphanumext('end', null);
$extraparams->start = $start;
$extraparams->end = $end;
$extraparams->field = isset($extradata->field) ? $extradata->field : (($institution == 'all') ? 'count_usr' : 'count_members');
$extraparams->extra = (array)$extradata;
list($subpages, $institutiondata, $subpagedata) = display_statistics($institution, $type, $extraparams);
list($subpages, $subpagedata) = display_statistics($institution, $type, $extraparams);
json_reply(false, (object) array('message' => false, 'data' => $subpagedata['table']));
json_reply(false, (object) array('message' => false, 'data' => $subpagedata['table'], 'tableheadings' => $subpagedata['tableheadings'], 'extraparams' => $extraparams));
......@@ -12,6 +12,7 @@
define('INTERNAL', 1);
define('INSTITUTIONALSTAFF', 1);
define('MENUITEM', 'manageinstitutions/statistics');
define('STATISTICSMENU', 1);
require(dirname(dirname(dirname(__FILE__))).'/init.php');
require(get_config('libroot') . 'statistics.php');
......@@ -56,50 +57,229 @@ $institutionselector = pieform(array(
)
));
if ($usersparam = param_variable('users', null)) {
$newuserids = is_array($usersparam) ? array_map('intval', $usersparam) : null;
$SESSION->set('usersforstats', $newuserids);
}
define('PAGEHEADINGARROW', get_string('reports', 'statistics'));
$type = param_alpha('type', 'users');
$subtype = param_alpha('subtype', '');
// Work out the title for the report
$reporttype = get_string('peoplereports', 'statistics');
if ($subtype && $subtype !== $type) {
if (string_exists($type . $subtype . 'reports', 'statistics')) {
$reporttype = get_string($type . $subtype . 'reports', 'statistics');
}
}
else {
if (string_exists($type . 'reports', 'statistics')) {
$reporttype = get_string($type . 'reports', 'statistics');
}
}
define('SUBSECTIONHEADING', $reporttype);
$subtype = !empty($subtype) ? $subtype : $type;
$showall = ($institution == 'all') ? true : false;
if ($showall) {
define('TITLE', get_string('statisticsforallinstitutions', 'admin'));
$icon = 'icon-area-chart';
define('TITLE', get_string('Allinstitutions', 'mahara'));
}
else {
define('TITLE', get_string('institutionstatisticsfor', 'admin', get_field('institution', 'displayname', 'name', $institution)));
$icon = 'icon-university';
define('TITLE', get_field('institution', 'displayname', 'name', $institution));
}
$type = param_alpha('type', 'users');
$start = param_variable('start', null);
$end = param_variable('end', null);
$start = $start ? format_date(strtotime($start), 'strftimew3cdate') : null;
$end = $end ? format_date(strtotime($end), 'strftimew3cdate') : null;
$extraparams = new stdClass();
$extraparams->type = $type;
$extraparams->subtype = $subtype;
$extraparams->institution = $institution;
$extraparams->offset = param_integer('offset', 0);
$extraparams->limit = param_integer('limit', 10);
$extraparams->sort = param_alphanumext('sort', 'displayname');
$extraparams->sortdesc = param_boolean('sortdesc');
$extraparams->start = param_alphanumext('start', null);
$extraparams->end = param_alphanumext('end', null);
list($subpages, $institutiondata, $subpagedata) = display_statistics($institution, $type, $extraparams);
$extraparams->extra = array('sort' => param_alphanumext('sort', ''),
'sortdesc' => param_boolean('sortdesc'),
'start' => $start,
'end' => $end,
'columns' => array(), // will be filled by the $type statistics function
);
$jsondatestart = !empty($start) ? "'" . $start ."'" : 'null';
$jsondateend = !empty($end) ? "'" . $end . "'" : 'null';
$extrajson = json_encode($extraparams->extra);
$wwwroot = get_config('wwwroot');
$js = <<< EOF
jQuery(function ($) {
{$subpagedata['table']['pagination_js']}
function reloadStats() {
window.location.href = '{$wwwroot}admin/users/statistics.php?institution='+$('#usertypeselect_institution').val() +'&type={$type}';
// Need to handle the pieform submission for the 'configure report' here
// This also populates the needed 'calendar' element headdata
// TODO - look to see if we need the ajax fetching of the config form or can we prepopulate the page with it?
$pieform = pieform_instance(report_config_form($extraparams));
$js = <<<JS
var opts = {'id':'statistics_table_container',
'type':'{$type}',
'subtype':'{$subtype}',
'extradata':'{$extrajson}',
'institution':'{$institution}',
'offset':{$extraparams->offset},
'limit':{$extraparams->limit},
'start':{$jsondatestart},
'end':{$jsondateend},
};
function show_stats_config() {
sendjsonrequest(config['wwwroot'] + 'admin/users/statsconfig.json.php', opts, 'POST', function(data) {
$('#modal-configs .modal-body').empty();
$('#modal-configs .modal-body').append(data.data.html);
$("#cancel_reportconfigform_submit").on('click', function(e) {
e.preventDefault();
$("#modal-configs").modal("hide");
});
});
}
function update_table_headers(data) {
var headers = (data) ? data.tableheadings : null;
var activeheaders = (data) ? data.data.activeheadings : null;
var limit = (data) ? data.extraparams.limit : null;
if (headers) {
var newhtml = '';
$.each(headers, function(i, heading) {
if (heading.selected) {
newhtml += heading.html;
}
});
$('#statistics_table thead tr').html(newhtml);
}
$('#statistics_table thead tr').find('a').each(function (i, a) {
$(a).off('click');
$(a).on('click', function(e) {
e.preventDefault();
var loc = a.href.indexOf('?');
var queryData = [];
var extraData = {};
if (loc != -1) {
queryData = parseQueryString(a.href.substring(loc + 1, a.href.length));
queryData.limit = limit;
// move the ones we need in extradata to there
extraData.sort = queryData.sort;
extraData.sortdesc = queryData.sortdesc || false;
extraData.columns = [];
if (activeheaders) {
for (x in activeheaders) {
extraData.columns.push(x);
}
}
queryData.extradata = JSON.stringify(extraData);
}
p.sendQuery(queryData, true);
});
});
}
$(document).on('pageupdated', function(e, data) {
// Update the table header links
$('#statistics_table thead tr').find('a').off('click');
update_table_headers(data);
});
jQuery(function ($) {
// JS Code to deal with the report configuration modal
// This fetches the form for choosing the results with filters, eg time frame
// We need to show/hide modal explicitly so the on 'show.bs.modal' fires allowing
// us to do ajax call for form as modal opens
$('#configbtn').click(function() {
$("#modal-configs").modal("show");
});
$("#modal-configs").on('show.bs.modal', function () {
show_stats_config();
});
$("#modal-configs .close").on('click', function () {
$("#modal-configs").modal("hide");
});
$('#usertypeselect_institution').on('change', reloadStats);
$('.btn.filter').on('click', function() {
var filteropt = $(this);
var filteroptid = filteropt.prop('id');
sendjsonrequest(config['wwwroot'] + 'json/stats_setting.php', {'setting':filteroptid}, 'POST', function(data) {
filteropt.parent().hide();
$('#statistics_table th a:first').trigger('click');
});
});
$('#messages .alert-success').delay(1000).hide("slow");
update_table_headers(null);
});
EOF;
$smarty = smarty(array('paginator','js/chartjs/Chart.min.js'));
setpageicon($smarty, $icon);
function reloadStats() {
window.location.href = '{$wwwroot}admin/users/statistics.php?institution=' + $('#usertypeselect_institution').val() + '&type={$type}&subtype={$subtype}';
}
JS;
if ($type == 'information' && (empty($subtype) || $subtype == 'information')) {
if ($institution == 'all') {
$institutiondata = site_statistics(true);
}
else {
$institutiondata = institution_statistics($institution, true);
}
$subpagedata = false;
$subpages = false;
$subpagination = '';
}
else {
list($subpages, $subpagedata) = display_statistics($institution, $type, $extraparams);
$subpagination = !empty($subpagedata['table']) ? $subpagedata['table']['pagination_js'] : false;
$institutiondata = false;
if ($subpagination) {
$js .= <<<JS
jQuery(function ($) {
// JS Code to deal with the columns selector
// This fetches the results and displays only the selected columns
$('#reportconfig input').on('click', function() {
var selected = [];
// Get all checked boxes
$('#reportconfig input:checked').each(function() {
selected.push($(this).attr('name'));
});
var obj = JSON.parse(opts.extradata);
obj['columns'] = selected;
opts.extradata = JSON.stringify(obj);
opts.offset = $('form.form-pagination input.currentoffset').val();
opts.limit = $('#setlimitselect').val();
sendjsonrequest(config.wwwroot + 'admin/users/statistics.json.php', opts, 'POST', function (data) {
p.updateResults(data);
});
});
p = {$subpagination}
p.extraData = $extrajson;
});
JS;
}
}
$smarty = smarty(array('paginator','js/chartjs/Chart.min.js'));
$smarty->assign('INLINEJAVASCRIPT', $js);
$smarty->assign('institutiondata', $institutiondata);
$smarty->assign('type', $type);
$smarty->assign('subpages', $subpages);
$smarty->assign('showall', ($showall ? '_all' : ''));
$smarty->assign('subpagedata', $subpagedata);
if (isset($subpagedata['table']) && isset($subpagedata['table']['settings'])) {
$smarty->assign('reportsettings', get_report_settings($subpagedata['table']['settings']));
}
$smarty->assign('institutionselector', $institutionselector);
$smarty->display('admin/users/statistics.tpl');
<?php
/**
*
* @package mahara
* @subpackage core
* @author Catalyst IT Ltd
* @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('INSTITUTIONALSTAFF', 1);
define('JSON', 1);
require(dirname(dirname(dirname(__FILE__))) . '/init.php');
require(get_config('libroot') . 'statistics.php');
$extradata = json_decode(param_variable('extradata'));
$institution = param_alphanum('institution', null);
if (empty($institution)) {
if (isset($extradata->institution)) {
$institution = $extradata->institution;
}
else if ($USER->get('admin') || $USER->get('staff')) {
$institution = 'all';
}
else {
$institution = 'mahara';
}
}
$type = param_alpha('type', 'users');
$subtype = param_alpha('subtype', $type);
$extraparams = new stdClass();
$extraparams->type = $type;
$extraparams->subtype = $subtype;
$extraparams->institution = $institution;
$extraparams->offset = param_integer('offset', 0);
$extraparams->limit = param_integer('limit', 10);
$extraparams->sort = isset($extradata->sort) ? $extradata->sort : 'displayname';
$extraparams->sortdesc = isset($extradata->sortdesc) ? true : false;
$extraparams->start = param_alphanumext('start', null);
$extraparams->end = param_alphanumext('end', null);
$extraparams->field = isset($extradata->field) ? $extradata->field : (($institution == 'all') ? 'count_usr' : 'count_members');
$extraparams->extra = (array)$extradata;
$formarray = report_config_form($extraparams);
$form = $formarray ? pieform($formarray) : '';
$reportinfo = get_string('reportdesc' . $subtype, 'statistics');
$smarty = smarty_core();
$smarty->assign('form', $form);
$smarty->assign('reportinformation', $reportinfo);
$html = $smarty->fetch('admin/users/statsconfig.tpl');
$data['html'] = $html;
json_reply(false, (object) array('message' => false, 'data' => $data));
<?php
/**
*
* @package mahara
* @subpackage core
* @author Catalyst IT Ltd
* @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');
json_headers();
$setting = param_alphanum('setting');
// Unset various statistic report page filters
// Don't pass in the session option directly for safety
if (isset($_SESSION['usersforstats']) && $setting == 'removeuserfilter') {
$SESSION->set('usersforstats', null);
}
json_reply(false, array('data' => 'success'));
......@@ -24,6 +24,7 @@ $string['coredata'] = 'core data';
$string['coredatasuccess'] = 'Successfully installed core data';
$string['fromversion'] = 'From version';
$string['information'] = 'Information';
$string['Information'] = 'Information';
$string['installingplugin'] = 'Installing %s';
$string['installsuccess'] = 'Successfully installed version ';
$string['toversion'] = 'To version';
......@@ -263,7 +264,7 @@ $string['Open'] = 'Open';
$string['reopensite'] = 'Reopen site';
$string['reopensitedetail'] = 'Your site is closed. Site administrators may stay logged in until an upgrade is detected.';
// Statistics
// Statistics / Reports
$string['siteinformation'] = 'Site information';
$string['viewfullsitestatistics'] = 'View full site statistics';
$string['institutioncreated_all'] = 'Site installed';
......@@ -303,9 +304,6 @@ $string['blockcountsbytype'] = 'Most frequently used blocks in portfolio pages';
$string['uptodate'] = 'up to date';
$string['latestversionis'] = 'latest version is <a href="%s">%s</a>';
$string['viewsbytype'] = 'Pages by type';
$string['userstatstabletitle'] = 'Daily user statistics';
$string['groupstatstabletitle'] = 'Biggest groups';
$string['viewstatstabletitle'] = 'Most popular pages';
$string['institutionloginstabletitle'] = 'Active institutions';
$string['institutionloginstablesubtitle'] = 'For %s - %s';
$string['visitedtimesrank'] = 'visited %s times, ranked number %s';
......@@ -319,16 +317,17 @@ $string['exportgroupscsv'] = 'Export groups in CSV format';
$string['exportgroupmembershipscsv'] = 'Export group membership in CSV format';
$string['exportgroupmembershipscsvspecific'] = 'Export group membership in CSV format for "%s"';
// Institution statistics
$string['statistics'] = 'Statistics';
$string['institutionstatistics'] = 'Institution statistics';
// Institution statistics / reports
$string['nostatistics'] = 'There are currently no statistiscs to display for this institution';
// $string['institutionstatistics'] = 'Institution statistics';
$string['institutionreports'] = 'Institution reports';
$string['institutionstatisticsfor'] = 'Institution statistics for \'%s\'';
$string['institutioncreated'] = 'Institution created';
// Registration statistics
$string['contentstatstabletitle'] = 'Content statistics for the current week';
$string['historicalstatstabletitle'] = 'Historical statistics for field \'%s\'';
$string['institutionstatstabletitle'] = 'Comparison of institution statistics';
$string['People'] = 'People';
$string['Groups'] = 'Groups';
$string['Content'] = 'Content';
$string['configurereport'] = 'Configure report';
$string['Columns'] = 'Columns';
// Site options
$string['adminsonly'] = 'Administrators only';
......@@ -1149,6 +1148,10 @@ $string['bulkprobationpointssuccess'] = array(
1 => 'Set probation points to %2$d for %1$d users'
);
$string['selectedusers'] = 'Selected users';
$string['selectednusers'] = array(
0 => '1 user selected',
1 => '%s users selected',
);
$string['remoteuser'] = 'Remote username';
$string['userreports'] = 'User reports';
$string['userreportsdescription'] = 'View or download information about the users you selected on the search page.';
......@@ -1310,5 +1313,4 @@ $string['cli_lang_branch'] = 'Mahara series version to fetch langpacks for serie
$string['withselectedcontentexport'] = 'Re-queue items into the export queue';
$string['withselectedcontentdelete'] = 'Delete selected items from the export queue';
$string['statisticsforallinstitutions'] = 'Statistics for all institutions';
\ No newline at end of file
$string['allothers'] = 'All others';
......@@ -200,3 +200,173 @@ $string['admins'] = 'Administrators';
$string['activeusers'] = "Active users";
$string['logins'] = "Logins";
$string['reports'] = 'Reports';
$string['reportsfor'] = 'Reports for %s';
$string['reporttype'] = 'Report type';
$string['reportconfig'] = 'Report configuration';
$string['reportdesctitle'] = 'This report includes:';
// People reports
$string['reportaccesslist'] = 'Portfolio access';
$string['reportdescaccesslist'] = '<ul>
<li>Portfolio owner</li>
<li>Title of the portfolio</li>
<li>Access list, i.e. who has permission to view the portfolio</li>
</ul>';
$string['reportdescusers'] = '<ul>
<li>Date</li>
<li>Number of people who logged in</li>
<li>Number of accounts created</li>
<li>Total number of people in the selected institution</li>
<li>Information about the average user in the selected institution</li>
</ul>';
$string['reportuserdetails'] = 'User details';
$string['reportdescuserdetails'] = '<ul>
<li>Username</li>
<li>Email address</li>
<li>First name</li>
<li>Last name</li>
<li>ID number</li>
<li>Display name</li>
<li>Remote username</li>
<li>Last login</li>
<li>Number of probation points</li>
</ul>';
$string['reportuseractivity'] = 'User activity';
$string['reportdescuseractivity'] = '<ul>
<li>User information</li>
<li>Number of artefacts</li>
<li>Number of pages</li>
<li>Number of collections</li>
<li>Number of groups</li>
<li>Number of logins</li>
<li>Number of actions (create and modify an artefact, forum post, personal pages and collection, group pages and collections, comments, page views)</li>
<li>Last login</li>
<li>Last activity</li>
</ul>';
$string['reportcollaboration'] = 'Collaboration';
$string['reportdesccollaboration'] = '<ul>
<li>Number of comments</li>
<li>Number of annotation feedback</li>
<li>Number of portfolios (pages or collections) shared with individual users</li>
<li>Number of portfolios shared with groups</li>
<li>Number of portfolios shared with an institution</li>
<li>Number of portfolios shared with all registered users</li>
<li>Number of portfolios shared publicly</li>
<li>Number of portfolios shared via secret URLs</li>
<li>Number of portfolios shared with friends</li>
</ul>';
$string['reportmasquerading'] = 'Masquerading sessions';
$string['reportdescmasquerading'] = '<ul>
<li>Name and username</li>
<li>Reason for the masquerading session</li>
<li>Administrator who masqueraded</li>
<li>Start time of the masquerading session</li>
</ul>';
$string['reportpageactivity'] = 'Page activity';
$string['reportdescpageactivity'] = '<ul>
<li>Page title</li>
<li>Page owner</li>
<li>Creation date</li>
<li>Last modification date</li>
<li>Date, when the page was last viewed</li>
<li>Number of blocks included in the page</li>
<li>Title of the collection to which the page belongs (if any)</li>
</ul>';
$string['allothers'] = 'All others';
// Group reports
$string['reportdescgroups'] = '<ul>
<li>ID</li>
<li>Name</li>
<li>Number of members</li>
<li>Number of pages</li>
<li>Number of comments on group pages</li>
<li>Number of comments on pages shared with the group</li>
<li>Number of forums</li>
<li>Number of forum posts</li>
</ul>';
// Content reports
$string['reportdesccontent'] = '<ul>
<li>Title</li>
<li>Number of modifications</li>
<li>Total</li>
<li>Number of unique users who made the modifications</li>
<li>Number of unique users over the total</li>
</ul>';
// Institution reports
$string['informationreports'] = 'Institution information';
$string['reportdescinformation'] = '<ul>
<li>Creation date</li>
<li>Number of users</li>
<li>Number of pages</li>
<li>Disk space used</li>
<li>For "All institutions" only:
<ul>
<li>Number of groups</li>
<li>Database size</li>
<li>Mahara version</li>
<li>Information on the running of cron</li>
</ul></li>
</ul>';
$string['reportinstitutioncomparison'] = 'Institution comparison';
$string['reportdesccomparisons'] = '<ul>
<li>Institution</li>
<li>Number of members</li>
<li>Number of pages</li>
<li>Number of blocks</li>
<li>Number of artefacts</li>
<li>Number of forum posts by institution members</li>
</ul>';
$string['reportdesclogins'] = '<ul>
<li>Institution</li>
<li>Number of logins no matter the user</li>
<li>Number of active users</li>
</ul>';
$string['userscollaborationreports'] = 'Collaboration';
$string['userspageactivityreports'] = 'Page activity';
$string['usersmasqueradingreports'] = 'Masquerading sessions';
$string['usersaccesslistreports'] = 'Portfolio access';
$string['usersuseractivityreports'] = 'User activity';
$string['usersuserdetailsreports'] = 'User details';
$string['groupsreports'] = 'Groups overview';
$string['contentreports'] = 'Content overview';
$string['peoplereports'] = 'People overview';
$string['informationloginsreports'] = 'Logins';
$string['informationcomparisonsreports'] = 'Institution comparison';
$string['applyingfilters'] = 'Applying filters';
$string['nogroupdataperinstitution'] = 'Group reports can only be generated for the entire site. Please select "All institutions" from the institution selector if you have permission to view sitewide reports.';
$string['nocomparisondataperinstitution'] = 'Comparison reports can only be generated for the entire site. Please select "All institutions" from the institution selector if you have permission to view sitewide reports.';
$string['nologinsdataperinstitution'] = 'Login reports can only be generated for the entire site. Please select "All institutions" from the institution selector if you have permission to view sitewide reports.';
$string['timeframe'] = 'Time frame: ';