Merge branch 'wip-mdl-43289' of git://github.com/rajeshtaneja/moodle

This commit is contained in:
Sam Hemelryk 2014-02-12 09:21:54 +13:00
commit ae7befec1e
15 changed files with 997 additions and 111 deletions

View File

@ -0,0 +1,87 @@
<?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/>.
/**
* mod_assign submission_created abstract event.
*
* @package mod_assign
* @copyright 2014 Adrian Greeve <adrian@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_assign\event;
defined('MOODLE_INTERNAL') || die();
/**
* mod_assign submission_created abstract event class.
*
* @property-read array $other Extra information about the event.
* -int submissionid: ID number of this submission.
* -int submissionattempt: Number of attempts made on this submission.
* -string submissionstatus: Status of the submission.
* -int groupid: (optional) The group ID if this is a teamsubmission (optional).
* }
*
* @package mod_assign
* @copyright 2014 Adrian Greeve <adrian@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
abstract class submission_created extends \core\event\base {
/**
* Init method.
*/
protected function init() {
$this->data['crud'] = 'c';
$this->data['edulevel'] = self::LEVEL_PARTICIPATING;
}
/**
* Returns localised general event name.
*
* @return string
*/
public static function get_name() {
return get_string('eventsubmissioncreated', 'mod_assign');
}
/**
* Returns relevant URL.
* @return \moodle_url
*/
public function get_url() {
return new \moodle_url('/mod/assign/view.php', array('id' => $this->contextinstanceid));
}
/**
* Custom validation.
*
* @throws \coding_exception
* @return void
*/
protected function validate_data() {
if (!isset($this->other['submissionid'])) {
throw new \coding_exception('Other must contain the key submissionid.');
}
if (!isset($this->other['submissionattempt'])) {
throw new \coding_exception('Other must contain the key submissionattempt.');
}
if (!isset($this->other['submissionstatus'])) {
throw new \coding_exception('Other must contain the key submissionstatus.');
}
}
}

View File

@ -29,49 +29,38 @@ defined('MOODLE_INTERNAL') || die();
/**
* mod_assign submission updated event class.
*
* @property-read array $other Extra information about the event.
* -int submissionid: ID number of this submission.
* -int submissionattempt: Number of attempts made on this submission.
* -string submissionstatus: Status of the submission.
* -int groupid: (optional) The group ID if this is a teamsubmission (optional).
* }
*
* @package mod_assign
* @copyright 2013 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class submission_updated extends \core\event\base {
abstract class submission_updated extends \core\event\base {
/**
* Legacy log data.
*
* @var array
* Init method.
*/
protected $legacylogdata;
/**
* Returns description of what happened.
*
* @return string
*/
public function get_description() {
return "The user {$this->userid} has updated the submission {$this->objectid}.";
protected function init() {
$this->data['crud'] = 'u';
$this->data['edulevel'] = self::LEVEL_PARTICIPATING;
}
/**
* Return legacy data for add_to_log().
*
* @return array
*/
protected function get_legacy_logdata() {
return $this->legacylogdata;
}
/**
* Return localised event name.
* Returns localised general event name.
*
* @return string
*/
public static function get_name() {
return get_string('event_submission_updated', 'mod_assign');
return get_string('eventsubmissionupdated', 'mod_assign');
}
/**
* Get URL related to the action.
*
* Returns relevant URL.
* @return \moodle_url
*/
public function get_url() {
@ -79,24 +68,20 @@ class submission_updated extends \core\event\base {
}
/**
* Init method.
* Custom validation.
*
* @throws \coding_exception
* @return void
*/
protected function init() {
$this->data['crud'] = 'u';
$this->data['edulevel'] = self::LEVEL_PARTICIPATING;
$this->data['objecttable'] = 'assign_submission';
protected function validate_data() {
if (!isset($this->other['submissionid'])) {
throw new \coding_exception('Other must contain the key submissionid.');
}
if (!isset($this->other['submissionattempt'])) {
throw new \coding_exception('Other must contain the key submissionattempt.');
}
if (!isset($this->other['submissionstatus'])) {
throw new \coding_exception('Other must contain the key submissionstatus.');
}
}
/**
* Sets the legacy event log data.
*
* @param stdClass $legacylogdata legacy log data.
* @return void
*/
public function set_legacy_logdata($legacylogdata) {
$this->legacylogdata = $legacylogdata;
}
}

View File

@ -151,8 +151,9 @@ $string['event_submission_graded'] = 'The submission has been graded.';
$string['event_submission_locked'] = 'The submissions have been locked for a user.';
$string['event_submission_status_updated'] = 'The status of the submission has been updated.';
$string['event_submission_unlocked'] = 'The submissions have been unlocked for a user.';
$string['event_submission_updated'] = 'The user has saved a submission.';
$string['event_workflow_state_updated'] = 'The state of the workflow has been updated.';
$string['eventsubmissioncreated'] = 'Submission created.';
$string['eventsubmissionupdated'] = 'Submission updated.';
$string['extensionduedate'] = 'Extension due date';
$string['extensionnotafterduedate'] = 'Extension date must be after the due date';
$string['extensionnotafterfromdate'] = 'Extension date must be after the allow submissions from date';

View File

@ -5544,14 +5544,6 @@ class assign {
$event->set_legacy_logdata($addtolog);
$event->trigger();
}
$addtolog = $this->add_to_log('submit', $this->format_submission_for_log($submission), '', true);
$params = array(
'context' => $this->context,
'objectid' => $submission->id
);
$event = \mod_assign\event\submission_updated::create($params);
$event->set_legacy_logdata($addtolog);
$event->trigger();
$complete = COMPLETION_INCOMPLETE;
if ($submission->status == ASSIGN_SUBMISSION_STATUS_SUBMITTED) {

View File

@ -0,0 +1,93 @@
<?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/>.
/**
* assignsubmission_file submission_created event.
*
* @package assignsubmission_file
* @copyright 2014 Adrian Greeve <adrian@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace assignsubmission_file\event;
defined('MOODLE_INTERNAL') || die();
/**
* assignsubmission_file submission_created event class.
*
* @property-read array $other Extra information about the event.
* -int submissionid: ID number of this submission.
* -int submissionattempt: Number of attempts made on this submission.
* -string submissionstatus: Status of the submission.
* -int groupid: (optional) The group ID if this is a teamsubmission (optional).
* -int filesubmissioncount: The number of files uploaded.
* }
*
* @package assignsubmission_file
* @copyright 2014 Adrian Greeve <adrian@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class submission_created extends \mod_assign\event\submission_created {
/**
* Init method.
*/
protected function init() {
parent::init();
$this->data['objecttable'] = 'assignsubmission_file';
}
/**
* Returns non-localised description of what happened.
*
* @return string
*/
public function get_description() {
if (!empty($this->other['groupid'])) {
$context = $this->get_context();
if (isset($context)) {
$descriptionstring = 'A user with an id of ' . $this->userid . ' updated a file submission and uploaded ' .
$this->other['filesubmissioncount'] . ' file/s in the assign module with an id of ' .
$this->other['submissionid'] . ' for the group ' .
\format_string($this->other['groupname'], true, array('context' => $context)) . '.';
} else {
$descriptionstring = 'A user with an id of ' . $this->userid . ' updated a file submission and uploaded ' .
$this->other['filesubmissioncount'] . ' file/s in the assign module with an id of ' .
$this->other['submissionid'] . ' for the group ' . $this->other['groupid'] . '.';
}
} else {
$descriptionstring = 'A user with an id of ' . $this->userid . ' updated a file submission and uploaded '.
$this->other['filesubmissioncount'] . ' file/s in the assign module with an id of ' .
$this->other['submissionid'];
}
return $descriptionstring;
}
/**
* Custom validation.
*
* @throws \coding_exception
* @return void
*/
protected function validate_data() {
parent::validate_data();
if (!isset($this->other['filesubmissioncount'])) {
throw new \coding_exception('Other must contain the key filesubmissioncount.');
}
}
}

View File

@ -0,0 +1,93 @@
<?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/>.
/**
* assignsubmission_file submission_updated event.
*
* @package assignsubmission_file
* @copyright 2014 Adrian Greeve <adrian@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace assignsubmission_file\event;
defined('MOODLE_INTERNAL') || die();
/**
* assignsubmission_file submission_updated event class.
*
* @property-read array $other Extra information about the event.
* -int submissionid: ID number of this submission.
* -int submissionattempt: Number of attempts made on this submission.
* -string submissionstatus: Status of the submission.
* -int groupid: (optional) The group ID if this is a teamsubmission (optional).
* -int filesubmissioncount: The number of files uploaded.
* }
*
* @package assignsubmission_file
* @copyright 2014 Adrian Greeve <adrian@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class submission_updated extends \mod_assign\event\submission_updated {
/**
* Init method.
*/
protected function init() {
parent::init();
$this->data['objecttable'] = 'assignsubmission_file';
}
/**
* Returns non-localised description of what happened.
*
* @return string
*/
public function get_description() {
if (!empty($this->other['groupid'])) {
$context = $this->get_context();
if (isset($context)) {
$descriptionstring = 'A user with an id of ' . $this->userid . ' updated a file submission and uploaded ' .
$this->other['filesubmissioncount'] . ' file/s in the assign module with an id of ' .
$this->other['submissionid'] . ' for the group ' .
\format_string($this->other['groupname'], true, array('context' => $context)) . '.';
} else {
$descriptionstring = 'A user with an id of ' . $this->userid . ' updated a file submission and uploaded ' .
$this->other['filesubmissioncount'] . ' file/s in the assign module with an id of ' .
$this->other['submissionid'] . ' for the group ' . $this->other['groupid'] . '.';
}
} else {
$descriptionstring = 'A user with an id of ' . $this->userid . ' updated a file submission and uploaded '.
$this->other['filesubmissioncount'] . ' file/s in the assign module with an id of ' .
$this->other['submissionid'];
}
return $descriptionstring;
}
/**
* Custom validation.
*
* @throws \coding_exception
* @return void
*/
protected function validate_data() {
parent::validate_data();
if (!isset($this->other['filesubmissioncount'])) {
throw new \coding_exception('Other must contain the key filesubmissioncount.');
}
}
}

View File

@ -220,6 +220,7 @@ class assign_submission_file extends assign_submission_plugin {
$params = array(
'context' => context_module::instance($this->assignment->get_course_module()->id),
'courseid' => $this->assignment->get_course()->id,
'objectid' => $submission->id,
'other' => array(
'content' => '',
@ -230,17 +231,49 @@ class assign_submission_file extends assign_submission_plugin {
$event->set_legacy_files($files);
$event->trigger();
$groupname = null;
$groupid = 0;
// Get the group name as other fields are not transcribed in the logs and this information is important.
if (empty($submission->userid) && !empty($submission->groupid)) {
$groupname = $DB->get_field('groups', 'name', array('id' => $submission->groupid), '*', MUST_EXIST);
$groupid = $submission->groupid;
} else {
$params['relateduserid'] = $submission->userid;
}
// Unset the objectid and other field from params for use in submission events.
unset($params['objectid']);
unset($params['other']);
$params['other'] = array(
'submissionid' => $submission->id,
'submissionattempt' => $submission->attemptnumber,
'submissionstatus' => $submission->status,
'filesubmissioncount' => $count,
'groupid' => $groupid,
'groupname' => $groupname
);
if ($filesubmission) {
$filesubmission->numfiles = $this->count_files($submission->id,
ASSIGNSUBMISSION_FILE_FILEAREA);
return $DB->update_record('assignsubmission_file', $filesubmission);
$updatestatus = $DB->update_record('assignsubmission_file', $filesubmission);
$params['objectid'] = $filesubmission->id;
$event = \assignsubmission_file\event\submission_updated::create($params);
$event->trigger();
return $updatestatus;
} else {
$filesubmission = new stdClass();
$filesubmission->numfiles = $this->count_files($submission->id,
ASSIGNSUBMISSION_FILE_FILEAREA);
$filesubmission->submission = $submission->id;
$filesubmission->assignment = $this->assignment->get_instance()->id;
return $DB->insert_record('assignsubmission_file', $filesubmission) > 0;
$filesubmission->id = $DB->insert_record('assignsubmission_file', $filesubmission);
$params['objectid'] = $filesubmission->id;
$event = \assignsubmission_file\event\submission_created::create($params);
$event->trigger();
return $filesubmission->id > 0;
}
}

View File

@ -29,68 +29,155 @@ require_once($CFG->dirroot . '/mod/assign/tests/base_test.php');
class assignsubmission_file_events_testcase extends advanced_testcase {
public function test_assessable_uploaded() {
$this->resetAfterTest();
/** @var stdClass $user A user to submit an assignment. */
protected $user;
$user = $this->getDataGenerator()->create_user();
$course = $this->getDataGenerator()->create_course();
/** @var stdClass $course New course created to hold the assignment activity. */
protected $course;
/** @var stdClass $cm A context module object. */
protected $cm;
/** @var stdClass $context Context of the assignment activity. */
protected $context;
/** @var stdClass $assign The assignment object. */
protected $assign;
/** @var stdClass $files Files that are being submitted for the assignment. */
protected $files;
/** @var stdClass $submission Submission information. */
protected $submission;
/** @var stdClass $fi File information - First file*/
protected $fi;
/** @var stdClass $fi2 File information - Second file*/
protected $fi2;
/**
* Setup all the various parts of an assignment activity including creating a file submission.
*/
protected function setUp() {
$this->user = $this->getDataGenerator()->create_user();
$this->course = $this->getDataGenerator()->create_course();
$generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
$params['course'] = $course->id;
$params['course'] = $this->course->id;
$instance = $generator->create_instance($params);
$cm = get_coursemodule_from_instance('assign', $instance->id);
$context = context_module::instance($cm->id);
$assign = new testable_assign($context, $cm, $course);
$this->cm = get_coursemodule_from_instance('assign', $instance->id);
$this->context = context_module::instance($this->cm->id);
$this->assign = new testable_assign($this->context, $this->cm, $this->course);
$this->setUser($user->id);
$submission = $assign->get_user_submission($user->id, true);
$this->setUser($this->user->id);
$this->submission = $this->assign->get_user_submission($this->user->id, true);
$fs = get_file_storage();
$dummy = (object) array(
'contextid' => $context->id,
'contextid' => $this->context->id,
'component' => 'assignsubmission_file',
'filearea' => ASSIGNSUBMISSION_FILE_FILEAREA,
'itemid' => $submission->id,
'itemid' => $this->submission->id,
'filepath' => '/',
'filename' => 'myassignmnent.pdf'
);
$fi = $fs->create_file_from_string($dummy, 'Content of ' . $dummy->filename);
$this->fi = $fs->create_file_from_string($dummy, 'Content of ' . $dummy->filename);
$dummy = (object) array(
'contextid' => $context->id,
'contextid' => $this->context->id,
'component' => 'assignsubmission_file',
'filearea' => ASSIGNSUBMISSION_FILE_FILEAREA,
'itemid' => $submission->id,
'itemid' => $this->submission->id,
'filepath' => '/',
'filename' => 'myassignmnent.png'
);
$fi2 = $fs->create_file_from_string($dummy, 'Content of ' . $dummy->filename);
$files = $fs->get_area_files($context->id, 'assignsubmission_file', ASSIGNSUBMISSION_FILE_FILEAREA,
$submission->id, 'id', false);
$this->fi2 = $fs->create_file_from_string($dummy, 'Content of ' . $dummy->filename);
$this->files = $fs->get_area_files($this->context->id, 'assignsubmission_file', ASSIGNSUBMISSION_FILE_FILEAREA,
$this->submission->id, 'id', false);
}
/**
* Test that the assessable_uploaded event is fired when a file submission has been made.
*/
public function test_assessable_uploaded() {
$this->resetAfterTest();
$data = new stdClass();
$plugin = $assign->get_submission_plugin_by_type('file');
$plugin = $this->assign->get_submission_plugin_by_type('file');
$sink = $this->redirectEvents();
$plugin->save($submission, $data);
$plugin->save($this->submission, $data);
$events = $sink->get_events();
$this->assertCount(1, $events);
$this->assertCount(2, $events);
$event = reset($events);
$this->assertInstanceOf('\assignsubmission_file\event\assessable_uploaded', $event);
$this->assertEquals($context->id, $event->contextid);
$this->assertEquals($submission->id, $event->objectid);
$this->assertEquals($this->context->id, $event->contextid);
$this->assertEquals($this->submission->id, $event->objectid);
$this->assertCount(2, $event->other['pathnamehashes']);
$this->assertEquals($fi->get_pathnamehash(), $event->other['pathnamehashes'][0]);
$this->assertEquals($fi2->get_pathnamehash(), $event->other['pathnamehashes'][1]);
$this->assertEquals($this->fi->get_pathnamehash(), $event->other['pathnamehashes'][0]);
$this->assertEquals($this->fi2->get_pathnamehash(), $event->other['pathnamehashes'][1]);
$expected = new stdClass();
$expected->modulename = 'assign';
$expected->cmid = $cm->id;
$expected->itemid = $submission->id;
$expected->courseid = $course->id;
$expected->userid = $user->id;
$expected->file = $files;
$expected->files = $files;
$expected->pathnamehashes = array($fi->get_pathnamehash(), $fi2->get_pathnamehash());
$expected->cmid = $this->cm->id;
$expected->itemid = $this->submission->id;
$expected->courseid = $this->course->id;
$expected->userid = $this->user->id;
$expected->file = $this->files;
$expected->files = $this->files;
$expected->pathnamehashes = array($this->fi->get_pathnamehash(), $this->fi2->get_pathnamehash());
$this->assertEventLegacyData($expected, $event);
$this->assertEventContextNotUsed($event);
}
/**
* Test that the submission_created event is fired when a file submission is saved.
*/
public function test_submission_created() {
$this->resetAfterTest();
$data = new stdClass();
$plugin = $this->assign->get_submission_plugin_by_type('file');
$sink = $this->redirectEvents();
$plugin->save($this->submission, $data);
$events = $sink->get_events();
$this->assertCount(2, $events);
// We want to test the last event fired.
$event = $events[1];
$this->assertInstanceOf('\assignsubmission_file\event\submission_created', $event);
$this->assertEquals($this->context->id, $event->contextid);
$this->assertEquals($this->course->id, $event->courseid);
$this->assertEquals($this->submission->id, $event->other['submissionid']);
$this->assertEquals($this->submission->attemptnumber, $event->other['submissionattempt']);
$this->assertEquals($this->submission->status, $event->other['submissionstatus']);
$this->assertEquals($this->submission->userid, $event->relateduserid);
}
/**
* Test that the submission_updated event is fired when a file submission is saved when an existing submission already exists.
*/
public function test_submission_updated() {
$this->resetAfterTest();
$data = new stdClass();
$plugin = $this->assign->get_submission_plugin_by_type('file');
$sink = $this->redirectEvents();
// Create a submission.
$plugin->save($this->submission, $data);
// Update a submission.
$plugin->save($this->submission, $data);
$events = $sink->get_events();
$this->assertCount(4, $events);
// We want to test the last event fired.
$event = $events[3];
$this->assertInstanceOf('\assignsubmission_file\event\submission_updated', $event);
$this->assertEquals($this->context->id, $event->contextid);
$this->assertEquals($this->course->id, $event->courseid);
$this->assertEquals($this->submission->id, $event->other['submissionid']);
$this->assertEquals($this->submission->attemptnumber, $event->other['submissionattempt']);
$this->assertEquals($this->submission->status, $event->other['submissionstatus']);
$this->assertEquals($this->submission->userid, $event->relateduserid);
}
}

View File

@ -0,0 +1,93 @@
<?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/>.
/**
* assignsubmission_onlinetext submission_created event.
*
* @package assignsubmission_onlinetext
* @copyright 2014 Adrian Greeve <adrian@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace assignsubmission_onlinetext\event;
defined('MOODLE_INTERNAL') || die();
/**
* assignsubmission_onlinetext submission_created event class.
*
* @property-read array $other Extra information about the event.
* -int submissionid: ID number of this submission.
* -int submissionattempt: Number of attempts made on this submission.
* -string submissionstatus: Status of the submission.
* -int groupid: (optional) The group ID if this is a teamsubmission (optional).
* -int onlinetextwordcount: Word count of the online text submission.
* }
*
* @package assignsubmission_onlinetext
* @copyright 2014 Adrian Greeve <adrian@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class submission_created extends \mod_assign\event\submission_created {
/**
* Init method.
*/
protected function init() {
parent::init();
$this->data['objecttable'] = 'assignsubmission_file';
}
/**
* Returns non-localised description of what happened.
*
* @return string
*/
public function get_description() {
if (!empty($this->other['groupid'])) {
$context = $this->get_context();
if (isset($context)) {
$descriptionstring = 'A user with an id of ' . $this->userid . ' updated a file submission and uploaded ' .
$this->other['onlinetextwordcount'] . ' file/s in the assign module with an id of ' .
$this->other['submissionid'] . ' for the group ' .
\format_string($this->other['groupname'], true, array('context' => $context)) . '.';
} else {
$descriptionstring = 'A user with an id of ' . $this->userid . ' updated a file submission and uploaded ' .
$this->other['onlinetextwordcount'] . ' file/s in the assign module with an id of ' .
$this->other['submissionid'] . ' for the group ' . $this->other['groupid'] . '.';
}
} else {
$descriptionstring = 'A user with an id of ' . $this->userid . ' updated a file submission and uploaded '.
$this->other['onlinetextwordcount'] . ' file/s in the assign module with an id of ' .
$this->other['submissionid'];
}
return $descriptionstring;
}
/**
* Custom validation.
*
* @throws \coding_exception
* @return void
*/
protected function validate_data() {
parent::validate_data();
if (!isset($this->other['onlinetextwordcount'])) {
throw new \coding_exception('Other must contain the key onlinetextwordcount.');
}
}
}

View File

@ -0,0 +1,93 @@
<?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/>.
/**
* assignsubmission_onlinetext submission_updated event.
*
* @package assignsubmission_onlinetext
* @copyright 2014 Adrian Greeve <adrian@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace assignsubmission_onlinetext\event;
defined('MOODLE_INTERNAL') || die();
/**
* assignsubmission_onlinetext submission_updated event class.
*
* @property-read array $other Extra information about the event.
* -int submissionid: ID number of this submission.
* -int submissionattempt: Number of attempts made on this submission.
* -string submissionstatus: Status of the submission.
* -int groupid: (optional) The group ID if this is a teamsubmission (optional).
* -int onlinetextwordcount: Word count of the online text submission.
* }
*
* @package assignsubmission_onlinetext
* @copyright 2014 Adrian Greeve <adrian@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class submission_updated extends \mod_assign\event\submission_updated {
/**
* Init method.
*/
protected function init() {
parent::init();
$this->data['objecttable'] = 'assignsubmission_file';
}
/**
* Returns non-localised description of what happened.
*
* @return string
*/
public function get_description() {
if (!empty($this->other['groupid'])) {
$context = $this->get_context();
if (isset($context)) {
$descriptionstring = 'A user with an id of ' . $this->userid . ' updated a file submission and uploaded ' .
$this->other['onlinetextwordcount'] . ' file/s in the assign module with an id of ' .
$this->other['submissionid'] . ' for the group ' .
\format_string($this->other['groupname'], true, array('context' => $context)) . '.';
} else {
$descriptionstring = 'A user with an id of ' . $this->userid . ' updated a file submission and uploaded ' .
$this->other['onlinetextwordcount'] . ' file/s in the assign module with an id of ' .
$this->other['submissionid'] . ' for the group ' . $this->other['groupid'] . '.';
}
} else {
$descriptionstring = 'A user with an id of ' . $this->userid . ' updated a file submission and uploaded '.
$this->other['onlinetextwordcount'] . ' file/s in the assign module with an id of ' .
$this->other['submissionid'];
}
return $descriptionstring;
}
/**
* Custom validation.
*
* @throws \coding_exception
* @return void
*/
protected function validate_data() {
parent::validate_data();
if (!isset($this->other['onlinetextwordcount'])) {
throw new \coding_exception('Other must contain the key onlinetextwordcount.');
}
}
}

View File

@ -150,6 +150,7 @@ class assign_submission_onlinetext extends assign_submission_plugin {
$params = array(
'context' => context_module::instance($this->assignment->get_course_module()->id),
'courseid' => $this->assignment->get_course()->id,
'objectid' => $submission->id,
'other' => array(
'pathnamehashes' => array_keys($files),
@ -160,12 +161,39 @@ class assign_submission_onlinetext extends assign_submission_plugin {
$event = \assignsubmission_onlinetext\event\assessable_uploaded::create($params);
$event->trigger();
$groupname = null;
$groupid = 0;
// Get the group name as other fields are not transcribed in the logs and this information is important.
if (empty($submission->userid) && !empty($submission->groupid)) {
$groupname = $DB->get_field('groups', 'name', array('id' => $submission->groupid), '*', MUST_EXIST);
$groupid = $submission->groupid;
} else {
$params['relateduserid'] = $submission->userid;
}
$count = count_words($data->onlinetext);
// Unset the objectid and other field from params for use in submission events.
unset($params['objectid']);
unset($params['other']);
$params['other'] = array(
'submissionid' => $submission->id,
'submissionattempt' => $submission->attemptnumber,
'submissionstatus' => $submission->status,
'onlinetextwordcount' => $count,
'groupid' => $groupid,
'groupname' => $groupname
);
if ($onlinetextsubmission) {
$onlinetextsubmission->onlinetext = $data->onlinetext;
$onlinetextsubmission->onlineformat = $data->onlinetext_editor['format'];
return $DB->update_record('assignsubmission_onlinetext', $onlinetextsubmission);
$params['objectid'] = $onlinetextsubmission->id;
$updatestatus = $DB->update_record('assignsubmission_onlinetext', $onlinetextsubmission);
$event = \assignsubmission_onlinetext\event\submission_updated::create($params);
$event->trigger();
return $updatestatus;
} else {
$onlinetextsubmission = new stdClass();
@ -174,7 +202,11 @@ class assign_submission_onlinetext extends assign_submission_plugin {
$onlinetextsubmission->submission = $submission->id;
$onlinetextsubmission->assignment = $this->assignment->get_instance()->id;
return $DB->insert_record('assignsubmission_onlinetext', $onlinetextsubmission) > 0;
$onlinetextsubmission->id = $DB->insert_record('assignsubmission_onlinetext', $onlinetextsubmission);
$params['objectid'] = $onlinetextsubmission->id;
$event = \assignsubmission_onlinetext\event\submission_created::create($params);
$event->trigger();
return $onlinetextsubmission->id > 0;
}
}

View File

@ -29,48 +29,125 @@ require_once($CFG->dirroot . '/mod/assign/tests/base_test.php');
class assignsubmission_onlinetext_events_testcase extends advanced_testcase {
public function test_assessable_uploaded() {
$this->resetAfterTest();
/** @var stdClass $user A user to submit an assignment. */
protected $user;
$user = $this->getDataGenerator()->create_user();
$course = $this->getDataGenerator()->create_course();
/** @var stdClass $course New course created to hold the assignment activity. */
protected $course;
/** @var stdClass $cm A context module object. */
protected $cm;
/** @var stdClass $context Context of the assignment activity. */
protected $context;
/** @var stdClass $assign The assignment object. */
protected $assign;
/** @var stdClass $submission Submission information. */
protected $submission;
/** @var stdClass $data General data for the assignment submission. */
protected $data;
/**
* Setup all the various parts of an assignment activity including creating an onlinetext submission.
*/
protected function setUp() {
$this->user = $this->getDataGenerator()->create_user();
$this->course = $this->getDataGenerator()->create_course();
$generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
$params['course'] = $course->id;
$params['course'] = $this->course->id;
$instance = $generator->create_instance($params);
$cm = get_coursemodule_from_instance('assign', $instance->id);
$context = context_module::instance($cm->id);
$assign = new testable_assign($context, $cm, $course);
$this->cm = get_coursemodule_from_instance('assign', $instance->id);
$this->context = context_module::instance($this->cm->id);
$this->assign = new testable_assign($this->context, $this->cm, $this->course);
$this->setUser($user->id);
$submission = $assign->get_user_submission($user->id, true);
$data = new stdClass();
$data->onlinetext_editor = array(
$this->setUser($this->user->id);
$this->submission = $this->assign->get_user_submission($this->user->id, true);
$this->data = new stdClass();
$this->data->onlinetext_editor = array(
'itemid' => file_get_unused_draft_itemid(),
'text' => 'Submission text',
'format' => FORMAT_PLAIN
);
$plugin = $assign->get_submission_plugin_by_type('onlinetext');
}
/**
* Test that the assessable_uploaded event is fired when an online text submission is saved.
*/
public function test_assessable_uploaded() {
$this->resetAfterTest();
$plugin = $this->assign->get_submission_plugin_by_type('onlinetext');
$sink = $this->redirectEvents();
$plugin->save($submission, $data);
$plugin->save($this->submission, $this->data);
$events = $sink->get_events();
$this->assertCount(1, $events);
$this->assertCount(2, $events);
$event = reset($events);
$this->assertInstanceOf('\assignsubmission_onlinetext\event\assessable_uploaded', $event);
$this->assertEquals($context->id, $event->contextid);
$this->assertEquals($submission->id, $event->objectid);
$this->assertEquals($this->context->id, $event->contextid);
$this->assertEquals($this->submission->id, $event->objectid);
$this->assertEquals(array(), $event->other['pathnamehashes']);
$this->assertEquals(FORMAT_PLAIN, $event->other['format']);
$this->assertEquals('Submission text', $event->other['content']);
$expected = new stdClass();
$expected->modulename = 'assign';
$expected->cmid = $cm->id;
$expected->itemid = $submission->id;
$expected->courseid = $course->id;
$expected->userid = $user->id;
$expected->cmid = $this->cm->id;
$expected->itemid = $this->submission->id;
$expected->courseid = $this->course->id;
$expected->userid = $this->user->id;
$expected->content = 'Submission text';
$this->assertEventLegacyData($expected, $event);
$this->assertEventContextNotUsed($event);
}
/**
* Test that the submission_created event is fired when an onlinetext submission is saved.
*/
public function test_submission_created() {
$this->resetAfterTest();
$plugin = $this->assign->get_submission_plugin_by_type('onlinetext');
$sink = $this->redirectEvents();
$plugin->save($this->submission, $this->data);
$events = $sink->get_events();
$this->assertCount(2, $events);
$event = $events[1];
$this->assertInstanceOf('\assignsubmission_onlinetext\event\submission_created', $event);
$this->assertEquals($this->context->id, $event->contextid);
$this->assertEquals($this->course->id, $event->courseid);
$this->assertEquals($this->submission->id, $event->other['submissionid']);
$this->assertEquals($this->submission->attemptnumber, $event->other['submissionattempt']);
$this->assertEquals($this->submission->status, $event->other['submissionstatus']);
$this->assertEquals($this->submission->userid, $event->relateduserid);
}
/**
* Test that the submission_updated event is fired when an onlinetext
* submission is saved and an existing submission already exists.
*/
public function test_submission_updated() {
$this->resetAfterTest();
$plugin = $this->assign->get_submission_plugin_by_type('onlinetext');
$sink = $this->redirectEvents();
// Create a submission.
$plugin->save($this->submission, $this->data);
// Update a submission.
$plugin->save($this->submission, $this->data);
$events = $sink->get_events();
$this->assertCount(4, $events);
$event = $events[3];
$this->assertInstanceOf('\assignsubmission_onlinetext\event\submission_updated', $event);
$this->assertEquals($this->context->id, $event->contextid);
$this->assertEquals($this->course->id, $event->courseid);
$this->assertEquals($this->submission->id, $event->other['submissionid']);
$this->assertEquals($this->submission->attemptnumber, $event->other['submissionattempt']);
$this->assertEquals($this->submission->status, $event->other['submissionstatus']);
$this->assertEquals($this->submission->userid, $event->relateduserid);
}
}

View File

@ -0,0 +1,171 @@
<?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/>.
/**
* Contains the event tests for the module assign.
*
* @package mod_assign
* @copyright 2014 Adrian Greeve <adrian@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
global $CFG;
require_once($CFG->dirroot . '/mod/assign/tests/base_test.php');
require_once($CFG->dirroot . '/mod/assign/tests/fixtures/event_mod_assign_fixtures.php');
/**
* Contains the event tests for the module assign.
*
* @package mod_assign
* @copyright 2014 Adrian Greeve <adrian@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class assign_events_testcase extends advanced_testcase {
/** @var stdClass $user A user to submit an assignment. */
protected $user;
/** @var stdClass $course New course created to hold the assignment activity. */
protected $course;
/** @var stdClass $cm A context module object. */
protected $cm;
/** @var stdClass $context Context of the assignment activity. */
protected $context;
/** @var array $params Standard event parameters. */
protected $params;
/**
* Setup all the various parts of an assignment activity.
*/
protected function setUp() {
$this->user = $this->getDataGenerator()->create_user();
$this->course = $this->getDataGenerator()->create_course();
$generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
$instance = $generator->create_instance(array('course' => $this->course->id));
$this->cm = get_coursemodule_from_instance('assign', $instance->id);
$this->context = context_module::instance($this->cm->id);
// Standard Event parameters.
$this->params = array(
'context' => $this->context,
'courseid' => $this->course->id
);
}
/**
* Basic tests for the submission_created() abstract class.
*/
public function test_submission_created() {
$this->resetAfterTest();
$eventinfo = $this->params;
$eventinfo['other'] = array(
'submissionid' => '17',
'submissionattempt' => 0,
'submissionstatus' => 'submitted'
);
$sink = $this->redirectEvents();
$event = \mod_assign_unittests\event\submission_created::create($eventinfo);
$event->trigger();
$result = $sink->get_events();
$event = reset($result);
$sink->close();
$this->assertEquals($this->context->id, $event->contextid);
$this->assertEquals($this->course->id, $event->courseid);
// Check that an error occurs when teamsubmission is not set.
try {
\mod_assign_unittests\event\submission_created::create($this->params);
$this->fail('Other must contain the key submissionid.');
} catch (Exception $e) {
$this->assertInstanceOf('coding_exception', $e);
}
// Check that the submission status debugging is fired.
$subinfo = $this->params;
$subinfo['other'] = array('submissionid' => '23');
try {
\mod_assign_unittests\event\submission_created::create($subinfo);
$this->fail('Other must contain the key submissionattempt.');
} catch (Exception $e) {
$this->assertInstanceOf('coding_exception', $e);
}
$subinfo['other'] = array('submissionattempt' => '0');
try {
\mod_assign_unittests\event\submission_created::create($subinfo);
$this->fail('Other must contain the key submissionstatus.');
} catch (Exception $e) {
$this->assertInstanceOf('coding_exception', $e);
}
}
/**
* Basic tests for the submission_updated() abstract class.
*/
public function test_submission_updated() {
$this->resetAfterTest();
$eventinfo = $this->params;
$eventinfo['other'] = array(
'submissionid' => '17',
'submissionattempt' => 0,
'submissionstatus' => 'submitted'
);
$sink = $this->redirectEvents();
$event = \mod_assign_unittests\event\submission_updated::create($eventinfo);
$event->trigger();
$result = $sink->get_events();
$event = reset($result);
$sink->close();
$this->assertEquals($this->context->id, $event->contextid);
$this->assertEquals($this->course->id, $event->courseid);
// Check that an error occurs when teamsubmission is not set.
try {
\mod_assign_unittests\event\submission_created::create($this->params);
$this->fail('Other must contain the key submissionid.');
} catch (Exception $e) {
$this->assertInstanceOf('coding_exception', $e);
}
// Check that the submission status debugging is fired.
$subinfo = $this->params;
$subinfo['other'] = array('submissionid' => '23');
try {
\mod_assign_unittests\event\submission_created::create($subinfo);
$this->fail('Other must contain the key submissionattempt.');
} catch (Exception $e) {
$this->assertInstanceOf('coding_exception', $e);
}
$subinfo['other'] = array('submissionattempt' => '0');
try {
\mod_assign_unittests\event\submission_created::create($subinfo);
$this->fail('Other must contain the key submissionstatus.');
} catch (Exception $e) {
$this->assertInstanceOf('coding_exception', $e);
}
}
}

View File

@ -0,0 +1,48 @@
<?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/>.
/**
* mod_assign unit test events.
*
* @package mod_assign
* @copyright 2013 Adrian Greeve <adrian@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_assign_unittests\event;
defined('MOODLE_INTERNAL') || die();
/**
* mod_assign submission_created unit test event class.
*
* @package mod_assign
* @copyright 2013 Adrian Greeve <adrian@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class submission_created extends \mod_assign\event\submission_created {
}
/**
* mod_assign submission_updated unit test event class.
*
* @package mod_assign
* @copyright 2013 Adrian Greeve <adrian@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class submission_updated extends \mod_assign\event\submission_updated {
}

View File

@ -1,13 +1,14 @@
This files describes API changes in the assign code.
=== 2.7 ===
* Added setting sendstudentnotifications to assign DB table with admin defaults. This sets the default value for the
"Notify students" option on the grading forms. This setting can be retrieved via webservices.
=== 2.7 ===
* Web service function mod_assign_save_grade has an additional optional parameter $advancedgradingdata which allows
advanced grading data to be used.
* A new web service function mod_assign_save_grades has been added which allows multiple grades to be processed.
* The event submission_updated() [mod/assign/classes/event/submission_updated.php] has been altered to now be an abstract class
for submission events in the submission plug-ins.
=== 2.6.1 ===