Skip to content

Commit

Permalink
MDL-68394 h5pactivity: Implement methods to display recent
Browse files Browse the repository at this point in the history
activity info.
  • Loading branch information
ilyatregubov committed May 26, 2021
1 parent efb3d4e commit 045c3ec
Show file tree
Hide file tree
Showing 5 changed files with 662 additions and 1 deletion.
2 changes: 2 additions & 0 deletions mod/h5pactivity/lang/en/h5pactivity.php
Expand Up @@ -77,6 +77,7 @@
$string['grade_average_attempt'] = 'Average grade';
$string['grade_last_attempt'] = 'Last attempt';
$string['grade_first_attempt'] = 'First attempt';
$string['grade_h5p'] = 'Grade: {$a}';
$string['h5pactivity:addinstance'] = 'Add a new H5P';
$string['h5pactivity:reviewattempts'] = 'Review H5P attempts';
$string['h5pactivity:submit'] = 'Submit H5P attempts';
Expand All @@ -94,6 +95,7 @@
$string['modulename_link'] = 'mod/h5pactivity/view';
$string['modulenameplural'] = 'H5P';
$string['myattempts'] = 'My attempts';
$string['newsubmissions'] = 'H5P submitted';
$string['no_compatible_track'] = 'This interaction ({$a}) does not provide tracking information or the tracking
provided is not compatible with the current activity version.';
$string['noparticipants'] = 'No participants to display';
Expand Down
282 changes: 281 additions & 1 deletion mod/h5pactivity/lib.php
Expand Up @@ -261,7 +261,7 @@ function h5pactivity_reset_course_form_defaults(stdClass $course): array {
* @return array of reseting status
*/
function h5pactivity_reset_userdata(stdClass $data): array {
global $CFG, $DB;
global $DB;
$componentstr = get_string('modulenameplural', 'mod_h5pactivity');
$status = [];
if (!empty($data->reset_h5pactivity)) {
Expand Down Expand Up @@ -541,3 +541,283 @@ function h5pactivity_dndupload_handle($uploadinfo): int {

return h5pactivity_add_instance($h5p, null);
}

/**
* Print recent activity from all h5pactivities in a given course
*
* This is used by the recent activity block
* @param mixed $course the course to print activity for
* @param bool $viewfullnames boolean to determine whether to show full names or not
* @param int $timestart the time the rendering started
* @return bool true if activity was printed, false otherwise.
*/
function h5pactivity_print_recent_activity($course, bool $viewfullnames, int $timestart): bool {
global $CFG, $DB, $OUTPUT, $USER;

$dbparams = [$timestart, $course->id, 'h5pactivity'];

$userfieldsapi = \core_user\fields::for_userpic();
$namefields = $userfieldsapi->get_sql('u', false, '', 'userid', false)->selects;;

$sql = "SELECT h5pa.id, h5pa.timemodified, cm.id as cmid, $namefields
FROM {h5pactivity_attempts} h5pa
JOIN {h5pactivity} h5p ON h5p.id = h5pa.h5pactivityid
JOIN {course_modules} cm ON cm.instance = h5p.id
JOIN {modules} md ON md.id = cm.module
JOIN {user} u ON u.id = h5pa.userid
WHERE h5pa.timemodified > ?
AND h5p.course = ?
AND md.name = ?
ORDER BY h5pa.timemodified ASC";

if (!$submissions = $DB->get_records_sql($sql, $dbparams)) {
return false;
}

$modinfo = get_fast_modinfo($course);

$recentactivity = h5pactivity_fetch_recent_activity($submissions, $course->id);

if (empty($recentactivity)) {
return false;
}

$cms = $modinfo->get_cms();

echo $OUTPUT->heading(get_string('newsubmissions', 'h5pactivity') . ':', 6);

foreach ($recentactivity as $submission) {
$cm = $cms[$submission->cmid];
$link = $CFG->wwwroot.'/mod/h5pactivity/view.php?id='.$cm->id;
print_recent_activity_note($submission->timemodified,
$submission,
$cm->name,
$link,
false,
$viewfullnames);
}

return true;
}

/**
* Returns all h5pactivities since a given time.
*
* @param array $activities The activity information is returned in this array
* @param int $index The current index in the activities array
* @param int $timestart The earliest activity to show
* @param int $courseid Limit the search to this course
* @param int $cmid The course module id
* @param int $userid Optional user id
* @param int $groupid Optional group id
* @return void
*/
function h5pactivity_get_recent_mod_activity(array &$activities, int &$index, int $timestart, int $courseid,
int $cmid, int $userid=0, int $groupid=0) {
global $CFG, $DB, $USER;

$course = get_course($courseid);
$modinfo = get_fast_modinfo($course);

$cm = $modinfo->get_cm($cmid);
$params = [];
if ($userid) {
$userselect = 'AND u.id = :userid';
$params['userid'] = $userid;
} else {
$userselect = '';
}

if ($groupid) {
$groupselect = 'AND gm.groupid = :groupid';
$groupjoin = 'JOIN {groups_members} gm ON gm.userid=u.id';
$params['groupid'] = $groupid;
} else {
$groupselect = '';
$groupjoin = '';
}

$params['cminstance'] = $cm->instance;
$params['timestart'] = $timestart;

$userfieldsapi = \core_user\fields::for_userpic();
$userfields = $userfieldsapi->get_sql('u', false, '', 'userid', false)->selects;

$sql = "SELECT h5pa.id, h5pa.timemodified, cm.id as cmid, $userfields
FROM {h5pactivity_attempts} h5pa
JOIN {h5pactivity} h5p ON h5p.id = h5pa.h5pactivityid
JOIN {course_modules} cm ON cm.instance = h5p.id
JOIN {modules} md ON md.id = cm.module
JOIN {user} u ON u.id = h5pa.userid $groupjoin
WHERE h5pa.timemodified > :timestart
AND h5p.id = :cminstance $userselect $groupselect
ORDER BY h5pa.timemodified ASC";

if (!$submissions = $DB->get_records_sql($sql, $params)) {
return;
}

$cmcontext = context_module::instance($cm->id);
$grader = has_capability('mod/h5pactivity:reviewattempts', $cmcontext);
$viewfullnames = has_capability('moodle/site:viewfullnames', $cmcontext);

$recentactivity = h5pactivity_fetch_recent_activity($submissions, $courseid);

if (empty($recentactivity)) {
return;
}

if ($grader) {
require_once($CFG->libdir.'/gradelib.php');
$userids = [];
foreach ($recentactivity as $id => $submission) {
$userids[] = $submission->userid;
}
$grades = grade_get_grades($courseid, 'mod', 'h5pactivity', $cm->instance, $userids);
}

$aname = format_string($cm->name, true);
foreach ($recentactivity as $submission) {
$activity = new stdClass();

$activity->type = 'h5pactivity';
$activity->cmid = $cm->id;
$activity->name = $aname;
$activity->sectionnum = $cm->sectionnum;
$activity->timestamp = $submission->timemodified;
$activity->user = new stdClass();
if ($grader) {
$activity->grade = $grades->items[0]->grades[$submission->userid]->str_long_grade;
}

$userfields = explode(',', implode(',', \core_user\fields::get_picture_fields()));
foreach ($userfields as $userfield) {
if ($userfield == 'id') {
// Aliased in SQL above.
$activity->user->{$userfield} = $submission->userid;
} else {
$activity->user->{$userfield} = $submission->{$userfield};
}
}
$activity->user->fullname = fullname($submission, $viewfullnames);

$activities[$index++] = $activity;
}

return;
}

/**
* Print recent activity from all h5pactivities in a given course
*
* This is used by course/recent.php
* @param stdClass $activity
* @param int $courseid
* @param bool $detail
* @param array $modnames
*/
function h5pactivity_print_recent_mod_activity(stdClass $activity, int $courseid, bool $detail, array $modnames) {
global $OUTPUT;

$modinfo = [];
if ($detail) {
$modinfo['modname'] = $activity->name;
$modinfo['modurl'] = new moodle_url('/mod/h5pactivity/view.php', ['id' => $activity->cmid]);
$modinfo['modicon'] = $OUTPUT->image_icon('icon', $modnames[$activity->type], 'h5pactivity');
}

$userpicture = $OUTPUT->user_picture($activity->user);

$template = ['userpicture' => $userpicture,
'submissiontimestamp' => $activity->timestamp,
'modinfo' => $modinfo,
'userurl' => new moodle_url('/user/view.php', array('id' => $activity->user->id, 'course' => $courseid)),
'fullname' => $activity->user->fullname];
if (isset($activity->grade)) {
$template['grade'] = get_string('grade_h5p', 'h5pactivity', $activity->grade);
}

echo $OUTPUT->render_from_template('mod_h5pactivity/reviewattempts', $template);
}

/**
* Fetches recent activity for course module.
*
* @param array $submissions The activity submissions
* @param int $courseid Limit the search to this course
* @return array $recentactivity recent activity in a course.
*/
function h5pactivity_fetch_recent_activity(array $submissions, int $courseid) : array {
global $USER;

$course = get_course($courseid);
$modinfo = get_fast_modinfo($course);

$recentactivity = [];
$grader = [];

$cms = $modinfo->get_cms();

foreach ($submissions as $submission) {
if (!array_key_exists($submission->cmid, $cms)) {
continue;
}
$cm = $cms[$submission->cmid];
if (!$cm->uservisible) {
continue;
}

if ($USER->id == $submission->userid) {
$recentactivity[$submission->userid] = $submission;
continue;
}

$cmcontext = context_module::instance($cm->id);
// The act of submitting of attempt may be considered private -
// only graders will see it if specified.
if (!array_key_exists($cm->id, $grader)) {
$grader[$cm->id] = has_capability('mod/h5pactivity:reviewattempts', $cmcontext);
}
if (!$grader[$cm->id]) {
continue;
}

$groups = [];
$usersgroups = [];

$groupmode = groups_get_activity_groupmode($cm, $course);
$accessallgroups = has_capability('moodle/site:accessallgroups', $cmcontext);

if ($groupmode == SEPARATEGROUPS && !$accessallgroups) {

if (isguestuser()) {
// Shortcut - guest user does not belong into any group.
continue;
}

if (!isset($groups[$cm->groupingid])) {
$groups[$cm->groupingid] = $modinfo->get_groups($cm->groupingid);
if (!$groups[$cm->groupingid]) {
continue;
}
}

if (!isset($usersgroups[$cm->groupingid][$submission->userid])) {
$usersgroups[$cm->groupingid][$submission->userid] =
groups_get_all_groups($course->id, $submission->userid, $cm->groupingid);
}

if (is_array($usersgroups[$cm->groupingid][$submission->userid])) {
$usersgroupstmp = array_keys($usersgroups[$cm->groupingid][$submission->userid]);
$intersect = array_intersect($usersgroupstmp, $groups[$cm->groupingid]);
if (empty($intersect)) {
continue;
}
}
}

$recentactivity[$submission->userid] = $submission;
}

return $recentactivity;
}
58 changes: 58 additions & 0 deletions mod/h5pactivity/templates/reviewattempts.mustache
@@ -0,0 +1,58 @@
{{!
This file is part of Moodle - http://moodle.org/
Moodle 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.
Moodle 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 Moodle. If not, see <http://www.gnu.org/licenses/>.
}}
{{!
@template mod_h5pactivity/reviewattempts
This template will render the H5P activity inside a recent activity report.
Variables requirer for this template:
* userpicture - User fullname and picture
* grade - User grade
* userdate - Submission date
Example context (json):
{
"userpicture": "<a href=\"#\"> </a>",
"grade": "30.77 / 100.00",
"userdate": "Wednesday, 27 January 2021, 9:54 AM",
"userurl": "http://localhost/m/stable_master/user/view.php?id=3&course=6",
"fullname": "Lukáš Svoboda"
}

}}
<table class="h5pactivity-recent">
<tbody>
<tr>
<td class="userpicture">{{{userpicture}}}</td>
<td>
<div class="title">
{{#modinfo}}
{{modicon}}<a href="{{modurl}}">{{modname}}</a>
{{/modinfo}}
</div>
{{#grade}}
<div class="grade">
{{grade}}
</div>
{{/grade}}
<div class="user">
<a href="{{userurl}}">{{fullname}}</a> - {{#userdate}} {{submissiontimestamp}}, {{#str}} strftimedatetime {{/str}} {{/userdate}}
</div>
</td>
</tr>
</tbody>
</table>

0 comments on commit 045c3ec

Please sign in to comment.