Merge branch 'MDL-42190-master-workshopdelsub' of git://github.com/mudrd8mz/moodle
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* The mod_workshop submission deleted event.
|
||||
*
|
||||
* @package mod_workshop
|
||||
* @copyright 2015 Paul Nicholls
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace mod_workshop\event;
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* The mod_workshop submission deleted event class.
|
||||
*
|
||||
* @property-read array $other {
|
||||
* Extra information about the event.
|
||||
*
|
||||
* - string submissiontitle: (optional) Submission title.
|
||||
* }
|
||||
*
|
||||
* @package mod_workshop
|
||||
* @since Moodle 3.1
|
||||
* @copyright 2015 Paul Nicholls
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class submission_deleted extends \core\event\base {
|
||||
|
||||
/**
|
||||
* Init method.
|
||||
*/
|
||||
protected function init() {
|
||||
$this->data['crud'] = 'd';
|
||||
$this->data['edulevel'] = self::LEVEL_PARTICIPATING;
|
||||
$this->data['objecttable'] = 'workshop_submissions';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns non-localised description of what happened.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_description() {
|
||||
return "The user with id '$this->userid' deleted the submission with id '$this->objectid' for the workshop " .
|
||||
"with course module id '$this->contextinstanceid'.";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns localised general event name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_name() {
|
||||
return get_string('eventsubmissiondeleted', 'workshop');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns relevant URL.
|
||||
*
|
||||
* @return \moodle_url
|
||||
*/
|
||||
public function get_url() {
|
||||
return new \moodle_url('/mod/workshop/submission.php',
|
||||
array('cmid' => $this->contextinstanceid, 'id' => $this->objectid));
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace add_to_log() statement.
|
||||
*
|
||||
* @return array of parameters to be passed to legacy add_to_log() function.
|
||||
*/
|
||||
protected function get_legacy_logdata() {
|
||||
return array($this->courseid, 'workshop', 'delete submission',
|
||||
'submission.php?cmid=' . $this->contextinstanceid . '&id=' . $this->objectid,
|
||||
$this->objectid, $this->contextinstanceid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines mapping of the 'objectid' property when restoring course logs.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_objectid_mapping() {
|
||||
return array('db' => 'workshop_submissions', 'restore' => 'workshop_submission');
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines mapping of the 'other' property when restoring course logs.
|
||||
*
|
||||
* @return array|bool
|
||||
*/
|
||||
public static function get_other_mapping() {
|
||||
// Nothing to map.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -233,4 +233,15 @@ $capabilities = array(
|
||||
'manager' => CAP_ALLOW
|
||||
)
|
||||
),
|
||||
|
||||
// Ability to delete other users' submissions.
|
||||
'mod/workshop:deletesubmissions' => array(
|
||||
'captype' => 'write',
|
||||
'contextlevel' => CONTEXT_MODULE,
|
||||
'archetypes' => array(
|
||||
'teacher' => CAP_ALLOW,
|
||||
'editingteacher' => CAP_ALLOW,
|
||||
'manager' => CAP_ALLOW
|
||||
)
|
||||
),
|
||||
);
|
||||
|
||||
@@ -92,6 +92,7 @@ $string['daystoday'] = 'today';
|
||||
$string['daystomorrow'] = 'tomorrow';
|
||||
$string['daysyesterday'] = 'yesterday';
|
||||
$string['deadlinesignored'] = 'Time restrictions do not apply to you';
|
||||
$string['deletesubmission'] = 'Delete submission';
|
||||
$string['editassessmentform'] = 'Edit assessment form';
|
||||
$string['editassessmentformstrategy'] = 'Edit assessment form ({$a})';
|
||||
$string['editingassessmentform'] = 'Editing assessment form';
|
||||
@@ -113,6 +114,7 @@ $string['eventsubmissionassessmentsreset'] = 'Submission assessments cleared';
|
||||
$string['eventsubmissioncreated'] = 'Submission created';
|
||||
$string['eventsubmissionreassessed'] = 'Submission re-assessed';
|
||||
$string['eventsubmissionupdated'] = 'Submission updated';
|
||||
$string['eventsubmissiondeleted'] = 'Submission deleted';
|
||||
$string['eventsubmissionviewed'] = 'Submission viewed';
|
||||
$string['eventphaseswitched'] = 'Phase switched';
|
||||
$string['example'] = 'Example submission';
|
||||
@@ -255,6 +257,8 @@ $string['submission'] = 'Submission';
|
||||
$string['submissionattachment'] = 'Attachment';
|
||||
$string['submissionby'] = 'Submission by {$a}';
|
||||
$string['submissioncontent'] = 'Submission content';
|
||||
$string['submissiondeleteconfirm'] = 'Are you sure you want to delete the following submission?';
|
||||
$string['submissiondeleteconfirmassess'] = 'Are you sure you want to delete the following submission? Note this will also delete {$a->count} assessments associated with this submission, which may affect the reviewers\' grades.';
|
||||
$string['submissionend'] = 'Submissions deadline';
|
||||
$string['submissionendbeforestart'] = 'Submissions deadline can not be specified before the open for submissions date';
|
||||
$string['submissionendevent'] = '{$a} (submissions deadline)';
|
||||
@@ -316,6 +320,7 @@ $string['withoutsubmission'] = 'Reviewer without own submission';
|
||||
$string['workshop:addinstance'] = 'Add a new workshop';
|
||||
$string['workshop:allocate'] = 'Allocate submissions for review';
|
||||
$string['workshop:editdimensions'] = 'Edit assessment forms';
|
||||
$string['workshop:deletesubmissions'] = 'Delete submissions';
|
||||
$string['workshop:ignoredeadlines'] = 'Ignore time restrictions';
|
||||
$string['workshop:manageexamples'] = 'Manage example submissions';
|
||||
$string['workshopname'] = 'Workshop name';
|
||||
|
||||
+71
-17
@@ -27,12 +27,14 @@ require_once(dirname(dirname(dirname(__FILE__))).'/config.php');
|
||||
require_once(dirname(__FILE__).'/locallib.php');
|
||||
require_once($CFG->dirroot . '/repository/lib.php');
|
||||
|
||||
$cmid = required_param('cmid', PARAM_INT); // course module id
|
||||
$id = optional_param('id', 0, PARAM_INT); // submission id
|
||||
$edit = optional_param('edit', false, PARAM_BOOL); // open for editing?
|
||||
$assess = optional_param('assess', false, PARAM_BOOL); // instant assessment required
|
||||
$cmid = required_param('cmid', PARAM_INT); // Course module id.
|
||||
$id = optional_param('id', 0, PARAM_INT); // Submission id.
|
||||
$edit = optional_param('edit', false, PARAM_BOOL); // Open the page for editing?
|
||||
$assess = optional_param('assess', false, PARAM_BOOL); // Instant assessment required.
|
||||
$delete = optional_param('delete', false, PARAM_BOOL); // Submission removal requested.
|
||||
$confirm = optional_param('confirm', false, PARAM_BOOL); // Submission removal request confirmed.
|
||||
|
||||
$cm = get_coursemodule_from_id('workshop', $cmid, 0, false, MUST_EXIST);
|
||||
$cm = get_coursemodule_from_id('workshop', $cmid, 0, false, MUST_EXIST);
|
||||
$course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST);
|
||||
|
||||
require_login($course, false, $cm);
|
||||
@@ -85,9 +87,11 @@ $cansubmit = has_capability('mod/workshop:submit', $workshop->context);
|
||||
$canallocate = has_capability('mod/workshop:allocate', $workshop->context);
|
||||
$canpublish = has_capability('mod/workshop:publishsubmissions', $workshop->context);
|
||||
$canoverride = (($workshop->phase == workshop::PHASE_EVALUATION) and has_capability('mod/workshop:overridegrades', $workshop->context));
|
||||
$candeleteall = has_capability('mod/workshop:deletesubmissions', $workshop->context);
|
||||
$userassessment = $workshop->get_assessment_of_submission_by_user($submission->id, $USER->id);
|
||||
$isreviewer = !empty($userassessment);
|
||||
$editable = ($cansubmit and $ownsubmission);
|
||||
$deletable = $candeleteall;
|
||||
$ispublished = ($workshop->phase == workshop::PHASE_CLOSED
|
||||
and $submission->published == 1
|
||||
and has_capability('mod/workshop:viewpublishedsubmissions', $workshop->context));
|
||||
@@ -127,6 +131,36 @@ if ($editable and $workshop->useexamples and $workshop->examplesmode == workshop
|
||||
}
|
||||
$edit = ($editable and $edit);
|
||||
|
||||
if (!$candeleteall and $ownsubmission and $editable) {
|
||||
// Only allow the student to delete their own submission if it's still editable and hasn't been assessed.
|
||||
if (count($workshop->get_assessments_of_submission($submission->id)) > 0) {
|
||||
$deletable = false;
|
||||
} else {
|
||||
$deletable = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($submission->id and $delete and $confirm and $deletable) {
|
||||
require_sesskey();
|
||||
$workshop->delete_submission($submission);
|
||||
|
||||
// Event information.
|
||||
$params = array(
|
||||
'context' => $workshop->context,
|
||||
'courseid' => $workshop->course->id,
|
||||
'relateduserid' => $submission->authorid,
|
||||
'other' => array(
|
||||
'submissiontitle' => $submission->title
|
||||
)
|
||||
);
|
||||
$params['objectid'] = $submission->id;
|
||||
$event = \mod_workshop\event\submission_deleted::create($params);
|
||||
$event->add_record_snapshot('workshop', $workshoprecord);
|
||||
$event->trigger();
|
||||
|
||||
redirect($workshop->view_url());
|
||||
}
|
||||
|
||||
$seenaspublished = false; // is the submission seen as a published submission?
|
||||
|
||||
if ($submission->id and ($ownsubmission or $canviewall or $isreviewer)) {
|
||||
@@ -313,6 +347,18 @@ if ($edit) {
|
||||
die();
|
||||
}
|
||||
|
||||
// Confirm deletion (if requested).
|
||||
if ($deletable and $delete) {
|
||||
$prompt = get_string('submissiondeleteconfirm', 'workshop');
|
||||
if ($candeleteall) {
|
||||
$count = count($workshop->get_assessments_of_submission($submission->id));
|
||||
if ($count > 0) {
|
||||
$prompt = get_string('submissiondeleteconfirmassess', 'workshop', ['count' => $count]);
|
||||
}
|
||||
}
|
||||
echo $output->confirm($prompt, new moodle_url($PAGE->url, ['delete' => 1, 'confirm' => 1]), $workshop->view_url());
|
||||
}
|
||||
|
||||
// else display the submission
|
||||
|
||||
if ($submission->id) {
|
||||
@@ -326,20 +372,28 @@ if ($submission->id) {
|
||||
echo $output->box(get_string('noyoursubmission', 'workshop'));
|
||||
}
|
||||
|
||||
if ($editable) {
|
||||
if ($submission->id) {
|
||||
$btnurl = new moodle_url($PAGE->url, array('edit' => 'on', 'id' => $submission->id));
|
||||
$btntxt = get_string('editsubmission', 'workshop');
|
||||
} else {
|
||||
$btnurl = new moodle_url($PAGE->url, array('edit' => 'on'));
|
||||
$btntxt = get_string('createsubmission', 'workshop');
|
||||
// If not at removal confirmation screen, some action buttons can be displayed.
|
||||
if (!$delete) {
|
||||
if ($editable) {
|
||||
if ($submission->id) {
|
||||
$btnurl = new moodle_url($PAGE->url, array('edit' => 'on', 'id' => $submission->id));
|
||||
$btntxt = get_string('editsubmission', 'workshop');
|
||||
} else {
|
||||
$btnurl = new moodle_url($PAGE->url, array('edit' => 'on'));
|
||||
$btntxt = get_string('createsubmission', 'workshop');
|
||||
}
|
||||
echo $output->single_button($btnurl, $btntxt, 'get');
|
||||
}
|
||||
echo $output->single_button($btnurl, $btntxt, 'get');
|
||||
}
|
||||
|
||||
if ($submission->id and !$edit and !$isreviewer and $canallocate and $workshop->assessing_allowed($USER->id)) {
|
||||
$url = new moodle_url($PAGE->url, array('assess' => 1));
|
||||
echo $output->single_button($url, get_string('assess', 'workshop'), 'post');
|
||||
if ($submission->id and $deletable) {
|
||||
$url = new moodle_url($PAGE->url, array('delete' => 1));
|
||||
echo $output->single_button($url, get_string('deletesubmission', 'workshop'), 'get');
|
||||
}
|
||||
|
||||
if ($submission->id and !$edit and !$isreviewer and $canallocate and $workshop->assessing_allowed($USER->id)) {
|
||||
$url = new moodle_url($PAGE->url, array('assess' => 1));
|
||||
echo $output->single_button($url, get_string('assess', 'workshop'), 'post');
|
||||
}
|
||||
}
|
||||
|
||||
if (($workshop->phase == workshop::PHASE_CLOSED) and ($ownsubmission or $canviewall)) {
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
@mod @mod_workshop
|
||||
Feature: Workshop submission removal
|
||||
In order to get rid of accidentally submitted or otherwise inappropriate contents
|
||||
As a student and as a teacher
|
||||
I need to be able to delete my submission, or any submission respectively
|
||||
|
||||
Background:
|
||||
Given the following "users" exist:
|
||||
| username | firstname | lastname | email |
|
||||
| student1 | Sam1 | Student1 | student1@example.com |
|
||||
| student2 | Sam2 | Student2 | student2@example.com |
|
||||
| student3 | Sam3 | Student3 | student3@example.com |
|
||||
| teacher1 | Terry1 | Teacher1 | teacher1@example.com |
|
||||
And the following "courses" exist:
|
||||
| fullname | shortname |
|
||||
| Course1 | c1 |
|
||||
And the following "course enrolments" exist:
|
||||
| user | course | role |
|
||||
| student1 | c1 | student |
|
||||
| student2 | c1 | student |
|
||||
| student3 | c1 | student |
|
||||
| teacher1 | c1 | editingteacher |
|
||||
And the following "activities" exist:
|
||||
| activity | name | intro | course | idnumber |
|
||||
| workshop | TestWorkshop | Test workshop description | c1 | workshop1 |
|
||||
# Teacher sets up assessment form and changes the phase to submission.
|
||||
And I log in as "teacher1"
|
||||
And I follow "Course1"
|
||||
And I edit assessment form in workshop "TestWorkshop" as:"
|
||||
| id_description__idx_0_editor | Aspect1 |
|
||||
| id_description__idx_1_editor | Aspect2 |
|
||||
| id_description__idx_2_editor | |
|
||||
And I change phase in workshop "TestWorkshop" to "Submission phase"
|
||||
And I log out
|
||||
# Student1 submits.
|
||||
And I log in as "student1"
|
||||
And I follow "Course1"
|
||||
And I follow "TestWorkshop"
|
||||
And I add a submission in workshop "TestWorkshop" as:"
|
||||
| Title | Submission1 |
|
||||
| Submission content | Some content |
|
||||
And I log out
|
||||
# Student2 submits.
|
||||
And I log in as "student2"
|
||||
And I follow "Course1"
|
||||
And I add a submission in workshop "TestWorkshop" as:"
|
||||
| Title | Submission2 |
|
||||
| Submission content | Some content |
|
||||
And I log out
|
||||
# Teacher allocates student3 to be reviewer of student2's submission.
|
||||
And I log in as "teacher1"
|
||||
And I follow "Course1"
|
||||
And I follow "TestWorkshop"
|
||||
And I allocate submissions in workshop "TestWorkshop" as:"
|
||||
| Participant | Reviewer |
|
||||
| Sam2 Student2 | Sam3 Student3 |
|
||||
And I log out
|
||||
|
||||
Scenario: Students can delete their submissions as long as the submissions are editable and not allocated for assessments
|
||||
Given I log in as "student1"
|
||||
And I follow "Course1"
|
||||
And I follow "TestWorkshop"
|
||||
When I follow "My submission"
|
||||
Then I should see "Submission1"
|
||||
And "Delete submission" "button" should exist
|
||||
And I click on "Delete submission" "button"
|
||||
And I should see "Are you sure you want to delete the following submission?"
|
||||
And I should see "Submission1"
|
||||
And I click on "Continue" "button"
|
||||
And I should see "You have not submitted your work yet"
|
||||
|
||||
Scenario: Students cannot delete their submissions if the submissions are not editable
|
||||
Given I log in as "teacher1"
|
||||
And I follow "Course1"
|
||||
And I follow "TestWorkshop"
|
||||
And I change phase in workshop "TestWorkshop" to "Closed"
|
||||
And I log out
|
||||
And I log in as "student1"
|
||||
And I follow "Course1"
|
||||
And I follow "TestWorkshop"
|
||||
When I follow "My submission"
|
||||
Then I should see "Submission1"
|
||||
And "Delete submission" "button" should not exist
|
||||
|
||||
Scenario: Students cannot delete their submissions if the submissions are allocated for assessments
|
||||
Given I log in as "student2"
|
||||
And I follow "Course1"
|
||||
And I follow "TestWorkshop"
|
||||
When I follow "My submission"
|
||||
Then I should see "Submission2"
|
||||
And "Delete submission" "button" should not exist
|
||||
|
||||
Scenario: Teachers can delete submissions even if the submissions are allocated for assessments.
|
||||
Given I log in as "teacher1"
|
||||
And I follow "Course1"
|
||||
And I follow "TestWorkshop"
|
||||
And "Submission1" "link" should exist
|
||||
And "Submission2" "link" should exist
|
||||
When I follow "Submission2"
|
||||
Then "Delete submission" "button" should exist
|
||||
And I click on "Delete submission" "button"
|
||||
And I should see "Are you sure you want to delete the following submission?"
|
||||
And I should see "Note this will also delete 1 assessments associated with this submission, which may affect the reviewers' grades."
|
||||
And I click on "Continue" "button"
|
||||
And "Submission1" "link" should exist
|
||||
And "Submission2" "link" should not exist
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2015111600; // The current module version (YYYYMMDDXX)
|
||||
$plugin->version = 2016012101; // The current module version (YYYYMMDDXX)
|
||||
$plugin->requires = 2015111000; // Requires this Moodle version.
|
||||
$plugin->component = 'mod_workshop';
|
||||
$plugin->cron = 60; // Give as a chance every minute.
|
||||
|
||||
Reference in New Issue
Block a user