mirror of
https://github.com/moodle/moodle.git
synced 2025-04-22 00:42:54 +02:00
MDL-68394 h5pactivity: Implement methods to display recent
activity info.
This commit is contained in:
parent
efb3d4e7a7
commit
045c3ec3ee
@ -77,6 +77,7 @@ $string['grade_highest_attempt'] = 'Highest grade';
|
||||
$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';
|
||||
@ -94,6 +95,7 @@ Any question attempts are marked automatically, and the grade is recorded in the
|
||||
$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';
|
||||
|
@ -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)) {
|
||||
@ -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
mod/h5pactivity/templates/reviewattempts.mustache
Normal file
58
mod/h5pactivity/templates/reviewattempts.mustache
Normal file
@ -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>
|
79
mod/h5pactivity/tests/behat/recent_activity.feature
Normal file
79
mod/h5pactivity/tests/behat/recent_activity.feature
Normal file
@ -0,0 +1,79 @@
|
||||
@mod @mod_h5pactivity @core_h5p @_file_upload @_switch_iframe
|
||||
Feature: Users can see the H5P recent activity from the recent activity block
|
||||
In order to quickly see the updates from H5P activity in my course
|
||||
As a user
|
||||
I need to be able to see the recent activity in the recent activity block
|
||||
|
||||
Background:
|
||||
Given the following "users" exist:
|
||||
| username | firstname | lastname | email |
|
||||
| teacher1 | Teacher | 1 | teacher1@example.com |
|
||||
| student1 | Student | 1 | student1@example.com |
|
||||
| student2 | Student | 2 | student2@example.com |
|
||||
And the following "courses" exist:
|
||||
| fullname | shortname | category |
|
||||
| Course 1 | C1 | 0 |
|
||||
And the following "course enrolments" exist:
|
||||
| user | course | role |
|
||||
| teacher1 | C1 | editingteacher |
|
||||
| student1 | C1 | student |
|
||||
| student2 | C1 | student |
|
||||
And the following "permission overrides" exist:
|
||||
| capability | permission | role | contextlevel | reference |
|
||||
| moodle/h5p:updatelibraries | Allow | editingteacher | System | |
|
||||
And I log in as "teacher1"
|
||||
And I am on "Course 1" course homepage with editing mode on
|
||||
And I add a "H5P" to section "1"
|
||||
And I set the following fields to these values:
|
||||
| Name | Awesome H5P package |
|
||||
| Description | Description |
|
||||
And I upload "h5p/tests/fixtures/multiple-choice-2-6.h5p" file to "Package file" filemanager
|
||||
And I click on "Save and return to course" "button"
|
||||
And I add the "Recent activity" block
|
||||
And I log out
|
||||
And I log in as "student1"
|
||||
And I am on "Course 1" course homepage
|
||||
And I follow "Awesome H5P package"
|
||||
And I switch to "h5p-player" class iframe
|
||||
And I switch to "h5p-iframe" class iframe
|
||||
And I click on "Wrong one" "text" in the ".h5p-question-content" "css_element"
|
||||
And I click on "Check" "button" in the ".h5p-question-buttons" "css_element"
|
||||
And I switch to the main frame
|
||||
And I log out
|
||||
And I log in as "student2"
|
||||
And I am on "Course 1" course homepage
|
||||
And I follow "Awesome H5P package"
|
||||
And I switch to "h5p-player" class iframe
|
||||
And I switch to "h5p-iframe" class iframe
|
||||
And I click on "Correct one" "text" in the ".h5p-question-content" "css_element"
|
||||
And I click on "Check" "button" in the ".h5p-question-buttons" "css_element"
|
||||
And I switch to the main frame
|
||||
And I log out
|
||||
|
||||
@javascript
|
||||
Scenario: Student see only his own activity
|
||||
Given I log in as "student1"
|
||||
And I am on "Course 1" course homepage
|
||||
And I should see "H5P submitted:" in the "Recent activity" "block"
|
||||
And I should see "Student 1" in the "Recent activity" "block"
|
||||
And I should not see "Grade:" in the "Recent activity" "block"
|
||||
And I should not see "Student 2" in the "Recent activity" "block"
|
||||
When I click on "Full report of recent activity" "link"
|
||||
Then I should see "H5P Awesome H5P package"
|
||||
And I should see "Student 1 - "
|
||||
And I should not see "Grade:"
|
||||
And I should not see "Student 2 - "
|
||||
|
||||
@javascript
|
||||
Scenario: Teacher see each student activity
|
||||
Given I log in as "teacher1"
|
||||
And I am on "Course 1" course homepage
|
||||
And I should see "H5P submitted:" in the "Recent activity" "block"
|
||||
And I should see "Student 1" in the "Recent activity" "block"
|
||||
And I should not see "Grade:" in the "Recent activity" "block"
|
||||
And I should see "Student 2" in the "Recent activity" "block"
|
||||
When I click on "Full report of recent activity" "link"
|
||||
Then I should see "H5P Awesome H5P package"
|
||||
And I should see "Student 1 - "
|
||||
And I should see "Grade:"
|
||||
And I should see "Student 2 - "
|
242
mod/h5pactivity/tests/lib_test.php
Normal file
242
mod/h5pactivity/tests/lib_test.php
Normal file
@ -0,0 +1,242 @@
|
||||
<?php
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* Unit tests for (some of) mod/h5pactivity/lib.php.
|
||||
*
|
||||
* @package mod_h5pactivity
|
||||
* @copyright 2021 Ilya Tregubov <ilya@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
use mod_h5pactivity\local\manager;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
global $CFG;
|
||||
require_once($CFG->dirroot . '/mod/h5pactivity/lib.php');
|
||||
|
||||
/**
|
||||
* Unit tests for (some of) mod/h5pactivity/lib.php.
|
||||
*
|
||||
* @copyright 2021 Ilya Tregubov <ilya@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class lib_test extends advanced_testcase {
|
||||
|
||||
/**
|
||||
* Test that assign_print_recent_activity shows ungraded submitted assignments.
|
||||
*/
|
||||
public function test_print_recent_activity() {
|
||||
$this->resetAfterTest();
|
||||
$this->setAdminUser();
|
||||
|
||||
$course = $this->getDataGenerator()->create_course();
|
||||
$student = $this->getDataGenerator()->create_and_enrol($course, 'student');
|
||||
$activity = $this->getDataGenerator()->create_module('h5pactivity',
|
||||
['course' => $course, 'enabletracking' => 1, 'grademethod' => manager::GRADEHIGHESTATTEMPT]);
|
||||
|
||||
$generator = $this->getDataGenerator()->get_plugin_generator('mod_h5pactivity');
|
||||
|
||||
$manager = manager::create_from_instance($activity);
|
||||
$cm = $manager->get_coursemodule();
|
||||
|
||||
$user = $student;
|
||||
$params = ['cmid' => $cm->id, 'userid' => $user->id];
|
||||
$generator->create_content($activity, $params);
|
||||
$this->setUser($student);
|
||||
$this->expectOutputRegex('/submitted:/');
|
||||
h5pactivity_print_recent_activity($course, true, time() - 3600);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that h5pactivity_print_recent_activity does not display any warnings when a custom fullname has been configured.
|
||||
*/
|
||||
public function test_print_recent_activity_fullname() {
|
||||
$this->resetAfterTest();
|
||||
$this->setAdminUser();
|
||||
|
||||
$course = $this->getDataGenerator()->create_course();
|
||||
$teacher = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
|
||||
$student = $this->getDataGenerator()->create_and_enrol($course, 'student');
|
||||
$activity = $this->getDataGenerator()->create_module('h5pactivity',
|
||||
['course' => $course, 'enabletracking' => 1, 'grademethod' => manager::GRADEHIGHESTATTEMPT]);
|
||||
|
||||
$generator = $this->getDataGenerator()->get_plugin_generator('mod_h5pactivity');
|
||||
|
||||
$manager = manager::create_from_instance($activity);
|
||||
$cm = $manager->get_coursemodule();
|
||||
|
||||
$user = $student;
|
||||
$params = ['cmid' => $cm->id, 'userid' => $user->id];
|
||||
$generator->create_content($activity, $params);
|
||||
|
||||
$this->setUser($teacher);
|
||||
|
||||
$this->expectOutputRegex('/submitted:/');
|
||||
set_config('fullnamedisplay', 'firstname, lastnamephonetic');
|
||||
h5pactivity_print_recent_activity($course, false, time() - 3600);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that h5pactivity_get_recent_mod_activity fetches the h5pactivity correctly.
|
||||
*/
|
||||
public function test_h5pactivity_get_recent_mod_activity() {
|
||||
$this->resetAfterTest();
|
||||
$this->setAdminUser();
|
||||
|
||||
$course = $this->getDataGenerator()->create_course();
|
||||
$teacher = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
|
||||
$student = $this->getDataGenerator()->create_and_enrol($course, 'student');
|
||||
$activity = $this->getDataGenerator()->create_module('h5pactivity',
|
||||
['course' => $course, 'enabletracking' => 1, 'grademethod' => manager::GRADEHIGHESTATTEMPT]);
|
||||
|
||||
$generator = $this->getDataGenerator()->get_plugin_generator('mod_h5pactivity');
|
||||
|
||||
$manager = manager::create_from_instance($activity);
|
||||
$cm = $manager->get_coursemodule();
|
||||
|
||||
$user = $student;
|
||||
$params = ['cmid' => $cm->id, 'userid' => $user->id];
|
||||
$generator->create_content($activity, $params);
|
||||
|
||||
$index = 1;
|
||||
$activities = [
|
||||
$index => (object) [
|
||||
'type' => 'h5pactivity',
|
||||
'cmid' => $cm->id,
|
||||
],
|
||||
];
|
||||
|
||||
$this->setUser($teacher);
|
||||
h5pactivity_get_recent_mod_activity($activities, $index, time() - HOURSECS, $course->id, $cm->id);
|
||||
|
||||
$activity = $activities[1];
|
||||
$this->assertEquals("h5pactivity", $activity->type);
|
||||
$this->assertEquals($student->id, $activity->user->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that h5pactivity_get_recent_mod_activity fetches activity correctly.
|
||||
*/
|
||||
public function test_h5pactivity_fetch_recent_activity() {
|
||||
global $DB;
|
||||
|
||||
$this->resetAfterTest();
|
||||
$this->setAdminUser();
|
||||
|
||||
$course = $this->getDataGenerator()->create_course();
|
||||
|
||||
// Create users and groups.
|
||||
$students = array();
|
||||
$groups = array();
|
||||
$teacher = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
|
||||
|
||||
for ($i = 1; $i < 4; $i++) {
|
||||
$students[$i] = $this->getDataGenerator()->create_and_enrol($course, 'student');
|
||||
$groups[$i] = $this->getDataGenerator()->create_group(array('courseid' => $course->id));
|
||||
}
|
||||
|
||||
// Update the course set the groupmode SEPARATEGROUPS and forced.
|
||||
update_course((object)array('id' => $course->id, 'groupmode' => SEPARATEGROUPS, 'groupmodeforce' => true));
|
||||
|
||||
// Student 1 is in groups 1 and 3.
|
||||
groups_add_member($groups[1], $students[1]);
|
||||
groups_add_member($groups[3], $students[1]);
|
||||
|
||||
// Student 2 is in groups 1 and 2.
|
||||
groups_add_member($groups[1], $students[2]);
|
||||
groups_add_member($groups[2], $students[2]);
|
||||
|
||||
// Student 3 is only in group 3.
|
||||
groups_add_member($groups[3], $students[3]);
|
||||
|
||||
// Grader is only in group 3.
|
||||
groups_add_member($groups[3], $teacher);
|
||||
|
||||
$timestart = time() - 1;
|
||||
// Create h5pactivity.
|
||||
$activity = $this->getDataGenerator()->create_module('h5pactivity',
|
||||
['course' => $course->id, 'enabletracking' => 1, 'grademethod' => manager::GRADEHIGHESTATTEMPT,
|
||||
'groupmode' => SEPARATEGROUPS]);
|
||||
|
||||
$teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher'));
|
||||
$cmcontext = \context_module::instance($activity->cmid);
|
||||
assign_capability('moodle/site:accessallgroups', CAP_PROHIBIT, $teacherrole->id, $cmcontext, true);
|
||||
|
||||
$manager = manager::create_from_instance($activity);
|
||||
$cm = $manager->get_coursemodule();
|
||||
|
||||
// Create attempts.
|
||||
$generator = $this->getDataGenerator()->get_plugin_generator('mod_h5pactivity');
|
||||
foreach ($students as $student) {
|
||||
$params = ['cmid' => $cm->id, 'userid' => $student->id];
|
||||
$generator->create_content($activity, $params);
|
||||
}
|
||||
|
||||
// Get all attempts.
|
||||
$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";
|
||||
|
||||
$submissions = $DB->get_records_sql($sql, $dbparams);
|
||||
$this->assertCount(count($students), $submissions);
|
||||
|
||||
// Fetch activity for student (only his own).
|
||||
$this->setUser($students[1]);
|
||||
$recentactivity = h5pactivity_fetch_recent_activity($submissions, $course->id);
|
||||
$this->assertCount(1, $recentactivity);
|
||||
$this->assertEquals($students[1]->id, $recentactivity[$students[1]->id]->userid);
|
||||
|
||||
// Fetch users group info for grader.
|
||||
$this->setUser($teacher);
|
||||
$recentactivity = h5pactivity_fetch_recent_activity($submissions, $course->id);
|
||||
$this->assertCount(2, $recentactivity);
|
||||
// Grader, Student 1 and 3 are in Group 3.
|
||||
$this->assertEquals($students[1]->id, $recentactivity[$students[1]->id]->userid);
|
||||
$this->assertEquals($students[3]->id, $recentactivity[$students[3]->id]->userid);
|
||||
|
||||
// Grader is in Group 2.
|
||||
groups_remove_member($groups[3], $teacher);
|
||||
groups_add_member($groups[2], $teacher);
|
||||
get_fast_modinfo($course->id, 0, true);
|
||||
$recentactivity = h5pactivity_fetch_recent_activity($submissions, $course->id);
|
||||
$this->assertCount(1, $recentactivity);
|
||||
// Grader, Student 2 are in Group 2.
|
||||
$this->assertEquals($students[2]->id, $recentactivity[$students[2]->id]->userid);
|
||||
|
||||
// Grader is in Group 1.
|
||||
groups_remove_member($groups[2], $teacher);
|
||||
groups_add_member($groups[1], $teacher);
|
||||
get_fast_modinfo($course->id, 0, true);
|
||||
$recentactivity = h5pactivity_fetch_recent_activity($submissions, $course->id);
|
||||
$this->assertCount(2, $recentactivity);
|
||||
// Grader, Student 1 and 2 are in Group 1.
|
||||
$this->assertEquals($students[1]->id, $recentactivity[$students[1]->id]->userid);
|
||||
$this->assertEquals($students[2]->id, $recentactivity[$students[2]->id]->userid);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user