first commit

This commit is contained in:
CHIEFSOFT\ameye
2024-09-30 18:11:26 -04:00
commit e592ca6823
27270 changed files with 5002257 additions and 0 deletions
@@ -0,0 +1,67 @@
<?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/>.
/**
* This file contains the class for backup of this feedback plugin
*
* @package assignfeedback_comments
* @copyright 2012 NetSpot {@link http://www.netspot.com.au}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* Provides the information to backup comments feedback.
*
* This just records the text and format.
*
* @package assignfeedback_comments
* @copyright 2012 NetSpot {@link http://www.netspot.com.au}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class backup_assignfeedback_comments_subplugin extends backup_subplugin {
/**
* Returns the subplugin information to attach to submission element.
* @return backup_subplugin_element
*/
protected function define_grade_subplugin_structure() {
// Create XML elements.
$subplugin = $this->get_subplugin_element();
$subpluginwrapper = new backup_nested_element($this->get_recommended_name());
$subpluginelement = new backup_nested_element('feedback_comments',
null,
array('commenttext', 'commentformat', 'grade'));
// Connect XML elements into the tree.
$subplugin->add_child($subpluginwrapper);
$subpluginwrapper->add_child($subpluginelement);
// Set source to populate the data.
$subpluginelement->set_source_table('assignfeedback_comments',
array('grade' => backup::VAR_PARENTID));
$subpluginelement->annotate_files(
'assignfeedback_comments',
'feedback',
'grade'
);
return $subplugin;
}
}
@@ -0,0 +1,83 @@
<?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/>.
/**
* Restore subplugin class.
*
* Provides the necessary information needed to restore
* one assign_submission subplugin.
*
* @package assignfeedback_comments
* @copyright 2012 NetSpot {@link http://www.netspot.com.au}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* Restore subplugin class.
*
* Provides the necessary information needed to restore
* one assignfeedback subplugin.
*
* @package assignfeedback_comments
* @copyright 2012 NetSpot {@link http://www.netspot.com.au}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class restore_assignfeedback_comments_subplugin extends restore_subplugin {
/**
* Returns the paths to be handled by the subplugin at workshop level
* @return array
*/
protected function define_grade_subplugin_structure() {
$paths = array();
$elename = $this->get_namefor('grade');
// We used get_recommended_name() so this works.
$elepath = $this->get_pathfor('/feedback_comments');
$paths[] = new restore_path_element($elename, $elepath);
return $paths;
}
/**
* Processes one feedback_comments element.
* @param mixed $data
*/
public function process_assignfeedback_comments_grade($data) {
global $DB;
$data = (object)$data;
$data->assignment = $this->get_new_parentid('assign');
$oldgradeid = $data->grade;
// The mapping is set in the restore for the core assign activity
// when a grade node is processed.
$data->grade = $this->get_mappingid('grade', $data->grade);
$DB->insert_record('assignfeedback_comments', $data);
$this->add_related_files(
'assignfeedback_comments',
'feedback',
'grade',
null,
$oldgradeid
);
}
}
@@ -0,0 +1,193 @@
<?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/>.
/**
* Privacy class for requesting user data.
*
* @package assignfeedback_comments
* @copyright 2018 Adrian Greeve <adrian@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace assignfeedback_comments\privacy;
defined('MOODLE_INTERNAL') || die();
require_once($CFG->dirroot . '/mod/assign/locallib.php');
use \core_privacy\local\metadata\collection;
use \core_privacy\local\request\writer;
use \core_privacy\local\request\contextlist;
use \mod_assign\privacy\assign_plugin_request_data;
use \mod_assign\privacy\useridlist;
/**
* Privacy class for requesting user data.
*
* @package assignfeedback_comments
* @copyright 2018 Adrian Greeve <adrian@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider implements
\core_privacy\local\metadata\provider,
\mod_assign\privacy\assignfeedback_provider,
\mod_assign\privacy\assignfeedback_user_provider {
/**
* Return meta data about this plugin.
*
* @param collection $collection A list of information to add to.
* @return collection Return the collection after adding to it.
*/
public static function get_metadata(collection $collection): collection {
$data = [
'assignment' => 'privacy:metadata:assignmentid',
'grade' => 'privacy:metadata:gradepurpose',
'commenttext' => 'privacy:metadata:commentpurpose'
];
$collection->add_database_table('assignfeedback_comments', $data, 'privacy:metadata:tablesummary');
$collection->link_subsystem('core_files', 'privacy:metadata:filepurpose');
return $collection;
}
/**
* No need to fill in this method as all information can be acquired from the assign_grades table in the mod assign
* provider.
*
* @param int $userid The user ID.
* @param contextlist $contextlist The context list.
*/
public static function get_context_for_userid_within_feedback(int $userid, contextlist $contextlist) {
// This uses the assign_grades table.
}
/**
* This also does not need to be filled in as this is already collected in the mod assign provider.
*
* @param useridlist $useridlist A list of user IDs
*/
public static function get_student_user_ids(useridlist $useridlist) {
// Not required.
}
/**
* If you have tables that contain userids and you can generate entries in your tables without creating an
* entry in the assign_grades table then please fill in this method.
*
* @param \core_privacy\local\request\userlist $userlist The userlist object
*/
public static function get_userids_from_context(\core_privacy\local\request\userlist $userlist) {
// Not required.
}
/**
* Export all user data for this plugin.
*
* @param assign_plugin_request_data $exportdata Data used to determine which context and user to export and other useful
* information to help with exporting.
*/
public static function export_feedback_user_data(assign_plugin_request_data $exportdata) {
// Get that comment information and jam it into that exporter.
$assign = $exportdata->get_assign();
$plugin = $assign->get_plugin_by_type('assignfeedback', 'comments');
$gradeid = $exportdata->get_pluginobject()->id;
$comments = $plugin->get_feedback_comments($gradeid);
if ($comments && !empty($comments->commenttext)) {
$currentpath = array_merge(
$exportdata->get_subcontext(),
[get_string('privacy:commentpath', 'assignfeedback_comments')]
);
$comments->commenttext = writer::with_context($assign->get_context())->rewrite_pluginfile_urls(
$currentpath,
ASSIGNFEEDBACK_COMMENTS_COMPONENT,
ASSIGNFEEDBACK_COMMENTS_FILEAREA,
$gradeid,
$comments->commenttext
);
$data = (object)
[
'commenttext' => format_text($comments->commenttext, $comments->commentformat,
['context' => $exportdata->get_context()])
];
writer::with_context($exportdata->get_context())->export_data($currentpath, $data);
writer::with_context($exportdata->get_context())->export_area_files($currentpath,
ASSIGNFEEDBACK_COMMENTS_COMPONENT, ASSIGNFEEDBACK_COMMENTS_FILEAREA, $gradeid);
}
}
/**
* Any call to this method should delete all user data for the context defined in the deletion_criteria.
*
* @param assign_plugin_request_data $requestdata Data useful for deleting user data from this sub-plugin.
*/
public static function delete_feedback_for_context(assign_plugin_request_data $requestdata) {
$assign = $requestdata->get_assign();
$fs = get_file_storage();
$fs->delete_area_files($requestdata->get_context()->id, ASSIGNFEEDBACK_COMMENTS_COMPONENT,
ASSIGNFEEDBACK_COMMENTS_FILEAREA);
$plugin = $assign->get_plugin_by_type('assignfeedback', 'comments');
$plugin->delete_instance();
}
/**
* Calling this function should delete all user data associated with this grade entry.
*
* @param assign_plugin_request_data $requestdata Data useful for deleting user data.
*/
public static function delete_feedback_for_grade(assign_plugin_request_data $requestdata) {
global $DB;
$fs = new \file_storage();
$fs->delete_area_files($requestdata->get_context()->id, ASSIGNFEEDBACK_COMMENTS_COMPONENT,
ASSIGNFEEDBACK_COMMENTS_FILEAREA, $requestdata->get_pluginobject()->id);
$DB->delete_records('assignfeedback_comments', ['assignment' => $requestdata->get_assignid(),
'grade' => $requestdata->get_pluginobject()->id]);
}
/**
* Deletes all feedback for the grade ids / userids provided in a context.
* assign_plugin_request_data contains:
* - context
* - assign object
* - grade ids (pluginids)
* - user ids
* @param assign_plugin_request_data $deletedata A class that contains the relevant information required for deletion.
*/
public static function delete_feedback_for_grades(assign_plugin_request_data $deletedata) {
global $DB;
if (empty($deletedata->get_gradeids())) {
return;
}
list($sql, $params) = $DB->get_in_or_equal($deletedata->get_gradeids(), SQL_PARAMS_NAMED);
$fs = new \file_storage();
$fs->delete_area_files_select(
$deletedata->get_context()->id,
ASSIGNFEEDBACK_COMMENTS_COMPONENT,
ASSIGNFEEDBACK_COMMENTS_FILEAREA,
$sql,
$params
);
$params['assignment'] = $deletedata->get_assignid();
$DB->delete_records_select('assignfeedback_comments', "assignment = :assignment AND grade $sql", $params);
}
}
@@ -0,0 +1,27 @@
<?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/>.
/**
* Capability definitions for this module.
*
* @package assignfeedback_comments
* @copyright 2012 NetSpot {@link http://www.netspot.com.au}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$capabilities = array(
);
@@ -0,0 +1,41 @@
<?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/>.
/**
* Post-install code for the feedback_comments module.
*
* @package assignfeedback_comments
* @copyright 2012 NetSpot {@link http://www.netspot.com.au}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* Set the initial order for the feedback comments plugin (top)
* @return bool
*/
function xmldb_assignfeedback_comments_install() {
global $CFG;
require_once($CFG->dirroot . '/mod/assign/adminlib.php');
// Set the correct initial order for the plugins.
$pluginmanager = new assign_plugin_manager('assignfeedback');
$pluginmanager->move_plugin('comments', 'up');
return true;
}
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8" ?>
<XMLDB PATH="mod/assign/feedback/comments/db" VERSION="20120423" COMMENT="XMLDB file for Moodle mod/assign/feedback/comments"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../../../../lib/xmldb/xmldb.xsd"
>
<TABLES>
<TABLE NAME="assignfeedback_comments" COMMENT="Text feedback for submitted assignments">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
<FIELD NAME="assignment" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
<FIELD NAME="grade" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
<FIELD NAME="commenttext" TYPE="text" NOTNULL="false" SEQUENCE="false" COMMENT="The feedback text"/>
<FIELD NAME="commentformat" TYPE="int" LENGTH="4" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="The feedback text format"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="The unique id for this feedback"/>
<KEY NAME="assignment" TYPE="foreign" FIELDS="assignment" REFTABLE="assign" REFFIELDS="id" COMMENT="The assignment instance this feedback relates to."/>
<KEY NAME="grade" TYPE="foreign" FIELDS="grade" REFTABLE="assign_grades" REFFIELDS="id" COMMENT="The grade instance this feedback relates to."/>
</KEYS>
</TABLE>
</TABLES>
</XMLDB>
@@ -0,0 +1,44 @@
<?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/>.
/**
* Upgrade code for the feedback_comments module.
*
* @package assignfeedback_comments
* @copyright 2012 NetSpot {@link http://www.netspot.com.au}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* Stub for upgrade code
* @param int $oldversion
* @return bool
*/
function xmldb_assignfeedback_comments_upgrade($oldversion) {
// Automatically generated Moodle v4.1.0 release upgrade line.
// Put any upgrade step following this.
// Automatically generated Moodle v4.2.0 release upgrade line.
// Put any upgrade step following this.
// Automatically generated Moodle v4.3.0 release upgrade line.
// Put any upgrade step following this.
// Automatically generated Moodle v4.4.0 release upgrade line.
// Put any upgrade step following this.
return true;
}
@@ -0,0 +1,39 @@
<?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/>.
/**
* Strings for component 'assignfeedback_comments', language 'en'
*
* @package assignfeedback_comments
* @copyright 2012 NetSpot {@link http://www.netspot.com.au}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$string['default'] = 'Enabled by default';
$string['default_help'] = 'If set, this feedback method will be enabled by default for all new assignments.';
$string['enabled'] = 'Feedback comments';
$string['enabled_help'] = 'If enabled, the marker can leave feedback comments for each submission. ';
$string['pluginname'] = 'Feedback comments';
$string['privacy:commentpath'] = 'Feedback comments';
$string['privacy:metadata:assignmentid'] = 'Assignment ID';
$string['privacy:metadata:commentpurpose'] = 'The comment text.';
$string['privacy:metadata:filepurpose'] = 'Feedback files from the teacher for the student.';
$string['privacy:metadata:gradepurpose'] = 'The grade ID associated with the comment.';
$string['privacy:metadata:tablesummary'] = 'This stores comments made by the graders as feedback for the student on their submission.';
$string['commentinline'] = 'Comment inline';
$string['commentinline_help'] = 'If enabled, the submission text will be copied into the feedback comment field during grading, making it easier to comment inline (using a different colour, perhaps) or to edit the original text.';
$string['commentinlinedefault'] = 'Comment inline by default';
$string['commentinlinedefault_help'] = 'If set, this comment inline functionality will be enabled by default for all new assignments.';
+82
View File
@@ -0,0 +1,82 @@
<?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/>.
/**
* This file contains the moodle hooks for the comments feedback plugin
*
* @package assignfeedback_comments
* @copyright 2018 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* Serves assignment comment feedback files.
*
* @param mixed $course course or id of the course
* @param mixed $cm course module or id of the course module
* @param context $context
* @param string $filearea
* @param array $args
* @param bool $forcedownload
* @param array $options - List of options affecting file serving.
* @return bool false if file not found, does not return if found - just send the file
*/
function assignfeedback_comments_pluginfile(
$course,
$cm,
context $context,
$filearea,
$args,
$forcedownload,
array $options = []) {
global $CFG, $DB;
require_once($CFG->dirroot . '/mod/assign/locallib.php');
if ($context->contextlevel != CONTEXT_MODULE) {
return false;
}
require_login($course, false, $cm);
$itemid = (int)array_shift($args);
$record = $DB->get_record('assign_grades', array('id' => $itemid), 'userid,assignment', MUST_EXIST);
$userid = $record->userid;
$assign = new assign($context, $cm, $course);
$instance = $assign->get_instance();
if ($instance->id != $record->assignment) {
return false;
}
if (!$assign->can_view_submission($userid)) {
return false;
}
$relativepath = implode('/', $args);
$fullpath = "/{$context->id}/assignfeedback_comments/$filearea/$itemid/$relativepath";
$fs = get_file_storage();
if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) {
return false;
}
// Download MUST be forced - security!
send_stored_file($file, 0, 0, true, $options);
}
+673
View File
@@ -0,0 +1,673 @@
<?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/>.
/**
* This file contains the definition for the library class for comment feedback plugin
*
* @package assignfeedback_comments
* @copyright 2012 NetSpot {@link http://www.netspot.com.au}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
use core_external\external_single_structure;
use core_external\external_value;
defined('MOODLE_INTERNAL') || die();
// File component for feedback comments.
define('ASSIGNFEEDBACK_COMMENTS_COMPONENT', 'assignfeedback_comments');
// File area for feedback comments.
define('ASSIGNFEEDBACK_COMMENTS_FILEAREA', 'feedback');
/**
* Library class for comment feedback plugin extending feedback plugin base class.
*
* @package assignfeedback_comments
* @copyright 2012 NetSpot {@link http://www.netspot.com.au}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class assign_feedback_comments extends assign_feedback_plugin {
/**
* Get the name of the online comment feedback plugin.
* @return string
*/
public function get_name() {
return get_string('pluginname', 'assignfeedback_comments');
}
/**
* Get the feedback comment from the database.
*
* @param int $gradeid
* @return stdClass|false The feedback comments for the given grade if it exists.
* False if it doesn't.
*/
public function get_feedback_comments($gradeid) {
global $DB;
return $DB->get_record('assignfeedback_comments', array('grade'=>$gradeid));
}
/**
* Get quickgrading form elements as html.
*
* @param int $userid The user id in the table this quickgrading element relates to
* @param mixed $grade - The grade data - may be null if there are no grades for this user (yet)
* @return mixed - A html string containing the html form elements required for quickgrading
*/
public function get_quickgrading_html($userid, $grade) {
$commenttext = '';
if ($grade) {
$feedbackcomments = $this->get_feedback_comments($grade->id);
if ($feedbackcomments) {
$commenttext = $feedbackcomments->commenttext;
}
}
$pluginname = get_string('pluginname', 'assignfeedback_comments');
$labeloptions = array('for'=>'quickgrade_comments_' . $userid,
'class'=>'accesshide');
$textareaoptions = array('name'=>'quickgrade_comments_' . $userid,
'id'=>'quickgrade_comments_' . $userid,
'class'=>'quickgrade');
return html_writer::tag('label', $pluginname, $labeloptions) .
html_writer::tag('textarea', $commenttext, $textareaoptions);
}
/**
* Has the plugin quickgrading form element been modified in the current form submission?
*
* @param int $userid The user id in the table this quickgrading element relates to
* @param stdClass $grade The grade
* @return boolean - true if the quickgrading form element has been modified
*/
public function is_quickgrading_modified($userid, $grade) {
$commenttext = '';
if ($grade) {
$feedbackcomments = $this->get_feedback_comments($grade->id);
if ($feedbackcomments) {
$commenttext = $feedbackcomments->commenttext;
}
}
// Note that this handles the difference between empty and not in the quickgrading
// form at all (hidden column).
$newvalue = optional_param('quickgrade_comments_' . $userid, false, PARAM_RAW);
return ($newvalue !== false) && ($newvalue != $commenttext);
}
/**
* Has the comment feedback been modified?
*
* @param stdClass $grade The grade object.
* @param stdClass $data Data from the form submission.
* @return boolean True if the comment feedback has been modified, else false.
*/
public function is_feedback_modified(stdClass $grade, stdClass $data) {
$commenttext = '';
if ($grade) {
$feedbackcomments = $this->get_feedback_comments($grade->id);
if ($feedbackcomments) {
$commenttext = $feedbackcomments->commenttext;
}
}
$formtext = $data->assignfeedbackcomments_editor['text'];
// Need to convert the form text to use @@PLUGINFILE@@ and format it so we can compare it with what is stored in the DB.
if (isset($data->assignfeedbackcomments_editor['itemid'])) {
$formtext = file_rewrite_urls_to_pluginfile($formtext, $data->assignfeedbackcomments_editor['itemid']);
$formtext = format_text($formtext, FORMAT_HTML);
}
if ($commenttext == $formtext) {
return false;
} else {
return true;
}
}
/**
* Override to indicate a plugin supports quickgrading.
*
* @return boolean - True if the plugin supports quickgrading
*/
public function supports_quickgrading() {
return true;
}
/**
* Return a list of the text fields that can be imported/exported by this plugin.
*
* @return array An array of field names and descriptions. (name=>description, ...)
*/
public function get_editor_fields() {
return array('comments' => get_string('pluginname', 'assignfeedback_comments'));
}
/**
* Get the saved text content from the editor.
*
* @param string $name
* @param int $gradeid
* @return string
*/
public function get_editor_text($name, $gradeid) {
if ($name == 'comments') {
$feedbackcomments = $this->get_feedback_comments($gradeid);
if ($feedbackcomments) {
return $feedbackcomments->commenttext;
}
}
return '';
}
/**
* Get the saved text content from the editor.
*
* @param string $name
* @param string $value
* @param int $gradeid
* @return string
*/
public function set_editor_text($name, $value, $gradeid) {
global $DB;
if ($name == 'comments') {
$feedbackcomment = $this->get_feedback_comments($gradeid);
if ($feedbackcomment) {
$feedbackcomment->commenttext = $value;
return $DB->update_record('assignfeedback_comments', $feedbackcomment);
} else {
$feedbackcomment = new stdClass();
$feedbackcomment->commenttext = $value;
$feedbackcomment->commentformat = FORMAT_HTML;
$feedbackcomment->grade = $gradeid;
$feedbackcomment->assignment = $this->assignment->get_instance()->id;
return $DB->insert_record('assignfeedback_comments', $feedbackcomment) > 0;
}
}
return false;
}
/**
* Save quickgrading changes.
*
* @param int $userid The user id in the table this quickgrading element relates to
* @param stdClass $grade The grade
* @return boolean - true if the grade changes were saved correctly
*/
public function save_quickgrading_changes($userid, $grade) {
global $DB;
$feedbackcomment = $this->get_feedback_comments($grade->id);
$quickgradecomments = optional_param('quickgrade_comments_' . $userid, null, PARAM_RAW);
if (!$quickgradecomments && $quickgradecomments !== '') {
return true;
}
if ($feedbackcomment) {
$feedbackcomment->commenttext = $quickgradecomments;
return $DB->update_record('assignfeedback_comments', $feedbackcomment);
} else {
$feedbackcomment = new stdClass();
$feedbackcomment->commenttext = $quickgradecomments;
$feedbackcomment->commentformat = FORMAT_HTML;
$feedbackcomment->grade = $grade->id;
$feedbackcomment->assignment = $this->assignment->get_instance()->id;
return $DB->insert_record('assignfeedback_comments', $feedbackcomment) > 0;
}
}
/**
* Save the settings for feedback comments plugin
*
* @param stdClass $data
* @return bool
*/
public function save_settings(stdClass $data) {
$this->set_config('commentinline', !empty($data->assignfeedback_comments_commentinline));
return true;
}
/**
* Get the default setting for feedback comments plugin
*
* @param MoodleQuickForm $mform The form to add elements to
* @return void
*/
public function get_settings(MoodleQuickForm $mform) {
$default = $this->get_config('commentinline');
if ($default === false) {
// Apply the admin default if we don't have a value yet.
$default = get_config('assignfeedback_comments', 'inline');
}
$mform->addElement('selectyesno',
'assignfeedback_comments_commentinline',
get_string('commentinline', 'assignfeedback_comments'));
$mform->addHelpButton('assignfeedback_comments_commentinline', 'commentinline', 'assignfeedback_comments');
$mform->setDefault('assignfeedback_comments_commentinline', $default);
// Disable comment online if comment feedback plugin is disabled.
$mform->hideIf('assignfeedback_comments_commentinline', 'assignfeedback_comments_enabled', 'notchecked');
}
/**
* Convert the text from any submission plugin that has an editor field to
* a format suitable for inserting in the feedback text field.
*
* @param stdClass $submission
* @param stdClass $data - Form data to be filled with the converted submission text and format.
* @param stdClass|null $grade
* @return boolean - True if feedback text was set.
*/
protected function convert_submission_text_to_feedback($submission, $data, $grade) {
global $DB;
$format = false;
$text = '';
foreach ($this->assignment->get_submission_plugins() as $plugin) {
$fields = $plugin->get_editor_fields();
if ($plugin->is_enabled() && $plugin->is_visible() && !$plugin->is_empty($submission) && !empty($fields)) {
$user = $DB->get_record('user', ['id' => $submission->userid]);
// Copy the files to the feedback area.
if ($files = $plugin->get_files($submission, $user)) {
$fs = get_file_storage();
$component = 'assignfeedback_comments';
$filearea = ASSIGNFEEDBACK_COMMENTS_FILEAREA;
$itemid = $grade->id;
$fieldupdates = [
'component' => $component,
'filearea' => $filearea,
'itemid' => $itemid
];
foreach ($files as $file) {
if ($file instanceof stored_file) {
// Before we create it, check that it doesn't already exist.
if (!$fs->file_exists(
$file->get_contextid(),
$component,
$filearea,
$itemid,
$file->get_filepath(),
$file->get_filename())) {
$fs->create_file_from_storedfile($fieldupdates, $file);
}
}
}
}
foreach ($fields as $key => $description) {
$rawtext = clean_text($plugin->get_editor_text($key, $submission->id));
$newformat = $plugin->get_editor_format($key, $submission->id);
if ($format !== false && $newformat != $format) {
// There are 2 or more editor fields using different formats, set to plain as a fallback.
$format = FORMAT_PLAIN;
} else {
$format = $newformat;
}
$text .= $rawtext;
}
}
}
if ($format === false) {
$format = FORMAT_HTML;
}
$data->assignfeedbackcomments = $text;
$data->assignfeedbackcommentsformat = $format;
return true;
}
/**
* Get form elements for the grading page
*
* @param stdClass|null $grade
* @param MoodleQuickForm $mform
* @param stdClass $data
* @return bool true if elements were added to the form
*/
public function get_form_elements_for_user($grade, MoodleQuickForm $mform, stdClass $data, $userid) {
$commentinlinenabled = $this->get_config('commentinline');
$submission = $this->assignment->get_user_submission($userid, false);
$feedbackcomments = false;
if ($grade) {
$feedbackcomments = $this->get_feedback_comments($grade->id);
}
// Check first for data from last form submission in case grading validation failed.
if (!empty($data->assignfeedbackcomments_editor['text'])) {
$data->assignfeedbackcomments = $data->assignfeedbackcomments_editor['text'];
$data->assignfeedbackcommentsformat = $data->assignfeedbackcomments_editor['format'];
} else if ($feedbackcomments && !empty($feedbackcomments->commenttext)) {
$data->assignfeedbackcomments = $feedbackcomments->commenttext;
$data->assignfeedbackcommentsformat = $feedbackcomments->commentformat;
} else {
// No feedback given yet - maybe we need to copy the text from the submission?
if (!empty($commentinlinenabled) && $submission) {
$this->convert_submission_text_to_feedback($submission, $data, $grade);
} else { // Set it to empty.
$data->assignfeedbackcomments = '';
$data->assignfeedbackcommentsformat = FORMAT_HTML;
}
}
file_prepare_standard_editor(
$data,
'assignfeedbackcomments',
$this->get_editor_options(),
$this->assignment->get_context(),
ASSIGNFEEDBACK_COMMENTS_COMPONENT,
ASSIGNFEEDBACK_COMMENTS_FILEAREA,
$grade->id
);
$mform->addElement('editor', 'assignfeedbackcomments_editor', $this->get_name(), null, $this->get_editor_options());
return true;
}
/**
* Saving the comment content into database.
*
* @param stdClass $grade
* @param stdClass $data
* @return bool
*/
public function save(stdClass $grade, stdClass $data) {
global $DB;
// Save the files.
$data = file_postupdate_standard_editor(
$data,
'assignfeedbackcomments',
$this->get_editor_options(),
$this->assignment->get_context(),
ASSIGNFEEDBACK_COMMENTS_COMPONENT,
ASSIGNFEEDBACK_COMMENTS_FILEAREA,
$grade->id
);
$feedbackcomment = $this->get_feedback_comments($grade->id);
if ($feedbackcomment) {
$feedbackcomment->commenttext = $data->assignfeedbackcomments;
$feedbackcomment->commentformat = $data->assignfeedbackcommentsformat;
return $DB->update_record('assignfeedback_comments', $feedbackcomment);
} else {
$feedbackcomment = new stdClass();
$feedbackcomment->commenttext = $data->assignfeedbackcomments;
$feedbackcomment->commentformat = $data->assignfeedbackcommentsformat;
$feedbackcomment->grade = $grade->id;
$feedbackcomment->assignment = $this->assignment->get_instance()->id;
return $DB->insert_record('assignfeedback_comments', $feedbackcomment) > 0;
}
}
/**
* Display the comment in the feedback table.
*
* @param stdClass $grade
* @param bool $showviewlink Set to true to show a link to view the full feedback
* @return string
*/
public function view_summary(stdClass $grade, & $showviewlink) {
$feedbackcomments = $this->get_feedback_comments($grade->id);
if ($feedbackcomments) {
$text = $this->rewrite_feedback_comments_urls($feedbackcomments->commenttext, $grade->id);
$text = format_text(
$text,
$feedbackcomments->commentformat,
[
'context' => $this->assignment->get_context()
]
);
// Show the view all link if the text has been shortened.
$short = shorten_text($text, 140);
$showviewlink = $short != $text;
return $short;
}
return '';
}
/**
* Display the comment in the feedback table.
*
* @param stdClass $grade
* @return string
*/
public function view(stdClass $grade) {
$feedbackcomments = $this->get_feedback_comments($grade->id);
if ($feedbackcomments) {
$text = $this->rewrite_feedback_comments_urls($feedbackcomments->commenttext, $grade->id);
$text = format_text(
$text,
$feedbackcomments->commentformat,
[
'context' => $this->assignment->get_context()
]
);
return $text;
}
return '';
}
/**
* Return true if this plugin can upgrade an old Moodle 2.2 assignment of this type
* and version.
*
* @param string $type old assignment subtype
* @param int $version old assignment version
* @return bool True if upgrade is possible
*/
public function can_upgrade($type, $version) {
if (($type == 'upload' || $type == 'uploadsingle' ||
$type == 'online' || $type == 'offline') && $version >= 2011112900) {
return true;
}
return false;
}
/**
* Upgrade the settings from the old assignment to the new plugin based one
*
* @param context $oldcontext - the context for the old assignment
* @param stdClass $oldassignment - the data for the old assignment
* @param string $log - can be appended to by the upgrade
* @return bool was it a success? (false will trigger a rollback)
*/
public function upgrade_settings(context $oldcontext, stdClass $oldassignment, & $log) {
if ($oldassignment->assignmenttype == 'online') {
$this->set_config('commentinline', $oldassignment->var1);
return true;
}
return true;
}
/**
* Upgrade the feedback from the old assignment to the new one
*
* @param context $oldcontext - the database for the old assignment context
* @param stdClass $oldassignment The data record for the old assignment
* @param stdClass $oldsubmission The data record for the old submission
* @param stdClass $grade The data record for the new grade
* @param string $log Record upgrade messages in the log
* @return bool true or false - false will trigger a rollback
*/
public function upgrade(context $oldcontext,
stdClass $oldassignment,
stdClass $oldsubmission,
stdClass $grade,
& $log) {
global $DB;
$feedbackcomments = new stdClass();
$feedbackcomments->commenttext = $oldsubmission->submissioncomment;
$feedbackcomments->commentformat = FORMAT_HTML;
$feedbackcomments->grade = $grade->id;
$feedbackcomments->assignment = $this->assignment->get_instance()->id;
if (!$DB->insert_record('assignfeedback_comments', $feedbackcomments) > 0) {
$log .= get_string('couldnotconvertgrade', 'mod_assign', $grade->userid);
return false;
}
return true;
}
/**
* If this plugin adds to the gradebook comments field, it must specify the format of the text
* of the comment
*
* Only one feedback plugin can push comments to the gradebook and that is chosen by the assignment
* settings page.
*
* @param stdClass $grade The grade
* @return int
*/
public function format_for_gradebook(stdClass $grade) {
$feedbackcomments = $this->get_feedback_comments($grade->id);
if ($feedbackcomments) {
return $feedbackcomments->commentformat;
}
return FORMAT_MOODLE;
}
/**
* If this plugin adds to the gradebook comments field, it must format the text
* of the comment
*
* Only one feedback plugin can push comments to the gradebook and that is chosen by the assignment
* settings page.
*
* @param stdClass $grade The grade
* @return string
*/
public function text_for_gradebook(stdClass $grade) {
$feedbackcomments = $this->get_feedback_comments($grade->id);
if ($feedbackcomments) {
return $feedbackcomments->commenttext;
}
return '';
}
/**
* Return any files this plugin wishes to save to the gradebook.
*
* @param stdClass $grade The assign_grades object from the db
* @return array
*/
public function files_for_gradebook(stdClass $grade): array {
return [
'contextid' => $this->assignment->get_context()->id,
'component' => ASSIGNFEEDBACK_COMMENTS_COMPONENT,
'filearea' => ASSIGNFEEDBACK_COMMENTS_FILEAREA,
'itemid' => $grade->id
];
}
/**
* The assignment has been deleted - cleanup
*
* @return bool
*/
public function delete_instance() {
global $DB;
// Will throw exception on failure.
$DB->delete_records('assignfeedback_comments',
array('assignment'=>$this->assignment->get_instance()->id));
return true;
}
/**
* Returns true if there are no feedback comments for the given grade.
*
* @param stdClass $grade
* @return bool
*/
public function is_empty(stdClass $grade) {
return $this->view($grade) == '';
}
/**
* Get file areas returns a list of areas this plugin stores files
* @return array - An array of fileareas (keys) and descriptions (values)
*/
public function get_file_areas() {
return array(ASSIGNFEEDBACK_COMMENTS_FILEAREA => $this->get_name());
}
/**
* Return a description of external params suitable for uploading an feedback comment from a webservice.
*
* @return \core_external\external_description|null
*/
public function get_external_parameters() {
$editorparams = array('text' => new external_value(PARAM_RAW, 'The text for this feedback.'),
'format' => new external_value(PARAM_INT, 'The format for this feedback'));
$editorstructure = new external_single_structure($editorparams, 'Editor structure', VALUE_OPTIONAL);
return array('assignfeedbackcomments_editor' => $editorstructure);
}
/**
* Return the plugin configs for external functions.
*
* @return array the list of settings
* @since Moodle 3.2
*/
public function get_config_for_external() {
return (array) $this->get_config();
}
/**
* Convert encoded URLs in $text from the @@PLUGINFILE@@/... form to an actual URL.
*
* @param string $text the Text to check
* @param int $gradeid The grade ID which refers to the id in the gradebook
*/
private function rewrite_feedback_comments_urls(string $text, int $gradeid) {
return file_rewrite_pluginfile_urls(
$text,
'pluginfile.php',
$this->assignment->get_context()->id,
ASSIGNFEEDBACK_COMMENTS_COMPONENT,
ASSIGNFEEDBACK_COMMENTS_FILEAREA,
$gradeid
);
}
/**
* File format options.
*
* @return array
*/
private function get_editor_options() {
global $COURSE;
return [
'subdirs' => 1,
'maxbytes' => $COURSE->maxbytes,
'accepted_types' => '*',
'context' => $this->assignment->get_context(),
'maxfiles' => EDITOR_UNLIMITED_FILES
];
}
}
+36
View File
@@ -0,0 +1,36 @@
<?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/>.
/**
* This file defines the admin settings for this plugin
*
* @package assignfeedback_comments
* @copyright 2012 NetSpot {@link http://www.netspot.com.au}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$settings->add(new admin_setting_configcheckbox('assignfeedback_comments/default',
new lang_string('default', 'assignfeedback_comments'),
new lang_string('default_help', 'assignfeedback_comments'), 1));
$setting = new admin_setting_configcheckbox('assignfeedback_comments/inline',
new lang_string('commentinlinedefault', 'assignfeedback_comments'),
new lang_string('commentinlinedefault_help', 'assignfeedback_comments'), 0);
$setting->set_advanced_flag_options(admin_setting_flag::ENABLED, false);
$setting->set_locked_flag_options(admin_setting_flag::ENABLED, false);
$settings->add($setting);
@@ -0,0 +1,40 @@
@mod @mod_assign @assignfeedback @assignfeedback_comments
Feature: In an assignment, teachers can provide feedback comments on student submissions
In order to provide feedback to students on their assignments
As a teacher,
I need to create feedback comments against their submissions.
Background:
Given the following "courses" exist:
| fullname | shortname | category | groupmode |
| Course 1 | C1 | 0 | 0 |
And the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | 1 | teacher1@example.com |
| student1 | Student | 1 | student1@example.com |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | teacher |
| student1 | C1 | student |
@javascript @skip_chrome_zerosize
Scenario: Teachers should be able to add and remove feedback comments via the quick grading interface
Given the following "activities" exist:
| activity | course | name | assignsubmission_onlinetext_enabled | assignfeedback_comments_enabled |
| assign | C1 | Test assignment name | 1 | 1 |
And the following "mod_assign > submissions" exist:
| assign | user | onlinetext |
| Test assignment name | student1 | I'm the student1 submission |
And I am on the "Test assignment name" Activity page logged in as teacher1
And I follow "View all submissions"
Then I click on "Quick grading" "checkbox"
And I set the field "Feedback comments" to "Feedback from teacher."
And I press "Save all quick grading changes"
And I should see "The grade changes were saved"
And I press "Continue"
And I should see "Feedback from teacher."
And I set the field "Feedback comments" to ""
And I press "Save all quick grading changes"
And I should see "The grade changes were saved"
And I press "Continue"
And I should not see "Feedback from teacher."
@@ -0,0 +1,33 @@
@mod @mod_assign @assignfeedback @assignfeedback_comments
Feature: Check that any changes to assignment feedback comments are not lost
if the grading form validation fails due to an invalid grade.
In order to ensure that the feedback changes are not lost
As a teacher
I need to grade a student and ensure that all feedback changes are preserved
@javascript
Scenario: Update the grade and feedback for an assignment
Given the following "courses" exist:
| fullname | shortname |
| Course 1 | C1 |
And the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | 1 | teacher1@example.com |
| student1 | Student | 1 | student1@example.com |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| student1 | C1 | student |
And the following "activities" exist:
| activity | name | course | assignfeedback_comments_enabled |
| assign | Test assignment name | C1 | 1 |
And I am on the "Test assignment name" Activity page logged in as teacher1
And I follow "View all submissions"
And I click on "Grade" "link" in the "Student 1" "table_row"
When I set the following fields to these values:
| Grade out of 100 | 101 |
| Feedback comments | Feedback from teacher. |
And I press "Save changes"
Then I should see "Grade must be less than or equal to 100."
And the following fields match these values:
| Feedback comments | Feedback from teacher. |
@@ -0,0 +1,83 @@
<?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/>.
namespace assignfeedback_comments;
use mod_assign_test_generator;
defined('MOODLE_INTERNAL') || die();
global $CFG;
require_once($CFG->dirroot . '/mod/assign/tests/generator.php');
/**
* Unit tests for assignfeedback_comments
*
* @package assignfeedback_comments
* @copyright 2016 Adrian Greeve <adrian@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class feedback_test extends \advanced_testcase {
// Use the generator helper.
use mod_assign_test_generator;
/**
* Test the is_feedback_modified() method for the comments feedback.
*/
public function test_is_feedback_modified(): void {
$this->resetAfterTest();
$course = $this->getDataGenerator()->create_course();
$teacher = $this->getDataGenerator()->create_and_enrol($course, 'teacher');
$student = $this->getDataGenerator()->create_and_enrol($course, 'student');
$assign = $this->create_instance($course, [
'assignsubmission_onlinetext_enabled' => 1,
'assignfeedback_comments_enabled' => 1,
]);
// Create an online text submission.
$this->add_submission($student, $assign);
$this->setUser($teacher);
// Create formdata.
$grade = $assign->get_user_grade($student->id, true);
$data = (object) [
'assignfeedbackcomments_editor' => [
'text' => '<p>first comment for this test</p>',
'format' => 1,
]
];
// This is the first time that we are submitting feedback, so it is modified.
$plugin = $assign->get_feedback_plugin_by_type('comments');
$this->assertTrue($plugin->is_feedback_modified($grade, $data));
// Save the feedback.
$plugin->save($grade, $data);
// Try again with the same data.
$this->assertFalse($plugin->is_feedback_modified($grade, $data));
// Change the data.
$data->assignfeedbackcomments_editor = [
'text' => '<p>Altered comment for this test</p>',
'format' => 1,
];
$this->assertTrue($plugin->is_feedback_modified($grade, $data));
}
}
@@ -0,0 +1,350 @@
<?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 assignfeedback_comments.
*
* @package assignfeedback_comments
* @copyright 2018 Adrian Greeve <adrian@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace assignfeedback_comments\privacy;
defined('MOODLE_INTERNAL') || die();
global $CFG;
require_once($CFG->dirroot . '/mod/assign/locallib.php');
require_once($CFG->dirroot . '/mod/assign/tests/privacy/provider_test.php');
/**
* Unit tests for mod/assign/feedback/comments/classes/privacy/
*
* @copyright 2018 Adrian Greeve <adrian@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider_test extends \mod_assign\privacy\provider_test {
/**
* Convenience function for creating feedback data.
*
* @param object $assign assign object
* @param \stdClass $student user object
* @param \stdClass $teacher user object
* @param string $submissiontext Submission text
* @param string $feedbacktext Feedback text
* @return array Feedback plugin object and the grade object.
*/
protected function create_feedback($assign, $student, $teacher, $submissiontext, $feedbacktext) {
global $CFG;
$submission = new \stdClass();
$submission->assignment = $assign->get_instance()->id;
$submission->userid = $student->id;
$submission->timecreated = time();
$submission->onlinetext_editor = ['text' => $submissiontext,
'format' => FORMAT_MOODLE];
$this->setUser($student);
$notices = [];
$assign->save_submission($submission, $notices);
$grade = $assign->get_user_grade($student->id, true);
$this->setUser($teacher);
$context = \context_user::instance($teacher->id);
$draftitemid = file_get_unused_draft_itemid();
file_prepare_draft_area($draftitemid, $context->id, ASSIGNFEEDBACK_COMMENTS_COMPONENT,
ASSIGNFEEDBACK_COMMENTS_FILEAREA, $grade->id);
$dummy = array(
'contextid' => $context->id,
'component' => 'user',
'filearea' => 'draft',
'itemid' => $draftitemid,
'filepath' => '/',
'filename' => 'feedback1.txt'
);
$fs = get_file_storage();
$fs->create_file_from_string($dummy, $feedbacktext);
$feedbacktext = $feedbacktext .
" <img src='{$CFG->wwwroot}/draftfile.php/{$context->id}/user/draft/{$draftitemid}/feedback1.txt.png>";
$plugin = $assign->get_feedback_plugin_by_type('comments');
$feedbackdata = new \stdClass();
$feedbackdata->assignfeedbackcomments_editor = [
'text' => $feedbacktext,
'format' => FORMAT_HTML,
'itemid' => $draftitemid
];
$plugin->save($grade, $feedbackdata);
return [$plugin, $grade];
}
/**
* Quick test to make sure that get_metadata returns something.
*/
public function test_get_metadata(): void {
$collection = new \core_privacy\local\metadata\collection('assignfeedback_comments');
$collection = \assignfeedback_comments\privacy\provider::get_metadata($collection);
$this->assertNotEmpty($collection);
}
/**
* Test that feedback comments are exported for a user.
*/
public function test_export_feedback_user_data(): void {
$this->resetAfterTest();
// Create course, assignment, submission, and then a feedback comment.
$course = $this->getDataGenerator()->create_course();
// Student.
$user1 = $this->getDataGenerator()->create_user();
// Teacher.
$user2 = $this->getDataGenerator()->create_user();
$this->getDataGenerator()->enrol_user($user1->id, $course->id, 'student');
$this->getDataGenerator()->enrol_user($user2->id, $course->id, 'editingteacher');
$assign = $this->create_instance(['course' => $course]);
$context = $assign->get_context();
$feedbacktext = '<p>first comment for this test</p>';
list($plugin, $grade) = $this->create_feedback($assign, $user1, $user2, 'Submission text', $feedbacktext);
$writer = \core_privacy\local\request\writer::with_context($context);
$this->assertFalse($writer->has_any_data());
// The student should be able to see the teachers feedback.
$exportdata = new \mod_assign\privacy\assign_plugin_request_data($context, $assign, $grade, [], $user1);
\assignfeedback_comments\privacy\provider::export_feedback_user_data($exportdata);
$this->assertStringContainsString($feedbacktext, $writer->get_data(['Feedback comments'])->commenttext);
$filespath = [];
$filespath[] = 'Feedback comments';
$feedbackfile = $writer->get_files($filespath)['feedback1.txt'];
$this->assertInstanceOf('stored_file', $feedbackfile);
$this->assertEquals('feedback1.txt', $feedbackfile->get_filename());
// The teacher should also be able to see the feedback that they provided.
$exportdata = new \mod_assign\privacy\assign_plugin_request_data($context, $assign, $grade, [], $user2);
\assignfeedback_comments\privacy\provider::export_feedback_user_data($exportdata);
$this->assertStringContainsString($feedbacktext, $writer->get_data(['Feedback comments'])->commenttext);
$feedbackfile = $writer->get_files($filespath)['feedback1.txt'];
$this->assertInstanceOf('stored_file', $feedbackfile);
$this->assertEquals('feedback1.txt', $feedbackfile->get_filename());
}
/**
* Test that all feedback is deleted for a context.
*/
public function test_delete_feedback_for_context(): void {
$this->resetAfterTest();
// Create course, assignment, submission, and then a feedback comment.
$course = $this->getDataGenerator()->create_course();
// Student.
$user1 = $this->getDataGenerator()->create_user();
$user2 = $this->getDataGenerator()->create_user();
// Teacher.
$user3 = $this->getDataGenerator()->create_user();
$this->getDataGenerator()->enrol_user($user1->id, $course->id, 'student');
$this->getDataGenerator()->enrol_user($user2->id, $course->id, 'student');
$this->getDataGenerator()->enrol_user($user3->id, $course->id, 'editingteacher');
$assign = $this->create_instance(['course' => $course]);
$context = $assign->get_context();
$feedbacktext = '<p>first comment for this test</p>';
list($plugin1, $grade1) = $this->create_feedback($assign, $user1, $user3, 'Submission text', $feedbacktext);
$feedbacktext = '<p>Comment for second student.</p>';
list($plugin2, $grade2) = $this->create_feedback($assign, $user2, $user3, 'Submission text', $feedbacktext);
// Check that we have data.
$feedbackcomments = $plugin1->get_feedback_comments($grade1->id);
$this->assertNotEmpty($feedbackcomments);
$feedbackcomments = $plugin1->get_feedback_comments($grade2->id);
$this->assertNotEmpty($feedbackcomments);
$fs = new \file_storage();
$files = $fs->get_area_files($assign->get_context()->id, ASSIGNFEEDBACK_COMMENTS_COMPONENT,
ASSIGNFEEDBACK_COMMENTS_FILEAREA);
// 4 including directories.
$this->assertEquals(4, count($files));
// Delete all comments for this context.
$requestdata = new \mod_assign\privacy\assign_plugin_request_data($context, $assign);
provider::delete_feedback_for_context($requestdata);
// Check that the data is now gone.
$feedbackcomments = $plugin1->get_feedback_comments($grade1->id);
$this->assertEmpty($feedbackcomments);
$feedbackcomments = $plugin1->get_feedback_comments($grade2->id);
$this->assertEmpty($feedbackcomments);
$fs = new \file_storage();
$files = $fs->get_area_files($assign->get_context()->id, ASSIGNFEEDBACK_COMMENTS_COMPONENT,
ASSIGNFEEDBACK_COMMENTS_FILEAREA);
$this->assertEquals(0, count($files));
}
/**
* Test that a grade item is deleted for a user.
*/
public function test_delete_feedback_for_grade(): void {
$this->resetAfterTest();
// Create course, assignment, submission, and then a feedback comment.
$course = $this->getDataGenerator()->create_course();
// Student.
$user1 = $this->getDataGenerator()->create_user();
$user2 = $this->getDataGenerator()->create_user();
// Teacher.
$user3 = $this->getDataGenerator()->create_user();
$this->getDataGenerator()->enrol_user($user1->id, $course->id, 'student');
$this->getDataGenerator()->enrol_user($user2->id, $course->id, 'student');
$this->getDataGenerator()->enrol_user($user3->id, $course->id, 'editingteacher');
$assign = $this->create_instance(['course' => $course]);
$context = $assign->get_context();
$feedbacktext = '<p>first comment for this test</p>';
list($plugin1, $grade1) = $this->create_feedback($assign, $user1, $user3, 'Submission text', $feedbacktext);
$feedbacktext = '<p>Comment for second student.</p>';
list($plugin2, $grade2) = $this->create_feedback($assign, $user2, $user3, 'Submission text', $feedbacktext);
// Check that we have data.
$feedbackcomments = $plugin1->get_feedback_comments($grade1->id);
$this->assertNotEmpty($feedbackcomments);
$feedbackcomments = $plugin1->get_feedback_comments($grade2->id);
$this->assertNotEmpty($feedbackcomments);
$fs = new \file_storage();
$files = $fs->get_area_files($assign->get_context()->id, ASSIGNFEEDBACK_COMMENTS_COMPONENT,
ASSIGNFEEDBACK_COMMENTS_FILEAREA);
// 4 including directories.
$this->assertEquals(4, count($files));
// Delete all comments for this grade object.
$requestdata = new \mod_assign\privacy\assign_plugin_request_data($context, $assign, $grade1, [], $user1);
provider::delete_feedback_for_grade($requestdata);
// These comments should be empty.
$feedbackcomments = $plugin1->get_feedback_comments($grade1->id);
$this->assertEmpty($feedbackcomments);
// These comments should not.
$feedbackcomments = $plugin1->get_feedback_comments($grade2->id);
$this->assertNotEmpty($feedbackcomments);
$fs = new \file_storage();
$files = $fs->get_area_files($assign->get_context()->id, ASSIGNFEEDBACK_COMMENTS_COMPONENT,
ASSIGNFEEDBACK_COMMENTS_FILEAREA);
// 2 files that were not deleted.
$this->assertEquals(2, count($files));
array_shift($files);
$file = array_shift($files);
$this->assertInstanceOf('stored_file', $file);
$this->assertEquals('feedback1.txt', $file->get_filename());
$this->assertEquals($grade2->id, $file->get_itemid());
}
/**
* Test that a grade item is deleted for a user.
*/
public function test_delete_feedback_for_grades(): void {
$this->resetAfterTest();
// Create course, assignment, submission, and then a feedback comment.
$course = $this->getDataGenerator()->create_course();
// Student.
$user1 = $this->getDataGenerator()->create_user();
$user2 = $this->getDataGenerator()->create_user();
$user3 = $this->getDataGenerator()->create_user();
$user4 = $this->getDataGenerator()->create_user();
// Teacher.
$user5 = $this->getDataGenerator()->create_user();
$this->getDataGenerator()->enrol_user($user1->id, $course->id, 'student');
$this->getDataGenerator()->enrol_user($user2->id, $course->id, 'student');
$this->getDataGenerator()->enrol_user($user3->id, $course->id, 'student');
$this->getDataGenerator()->enrol_user($user4->id, $course->id, 'student');
$this->getDataGenerator()->enrol_user($user5->id, $course->id, 'editingteacher');
$assign1 = $this->create_instance(['course' => $course]);
$assign2 = $this->create_instance(['course' => $course]);
$feedbacktext = '<p>first comment for this test</p>';
list($plugin1, $grade1) = $this->create_feedback($assign1, $user1, $user5, 'Submission text', $feedbacktext);
$feedbacktext = '<p>Comment for second student.</p>';
list($plugin2, $grade2) = $this->create_feedback($assign1, $user2, $user5, 'Submission text', $feedbacktext);
$feedbacktext = '<p>Comment for third student.</p>';
list($plugin3, $grade3) = $this->create_feedback($assign1, $user3, $user5, 'Submission text', $feedbacktext);
$feedbacktext = '<p>Comment for third student in the second assignment.</p>';
list($plugin4, $grade4) = $this->create_feedback($assign2, $user3, $user5, 'Submission text', $feedbacktext);
$feedbacktext = '<p>Comment for fourth student in the second assignment.</p>';
list($plugin5, $grade5) = $this->create_feedback($assign2, $user4, $user5, 'Submission text', $feedbacktext);
// Check that we have data.
$feedbackcomments = $plugin1->get_feedback_comments($grade1->id);
$this->assertNotEmpty($feedbackcomments);
$feedbackcomments = $plugin2->get_feedback_comments($grade2->id);
$this->assertNotEmpty($feedbackcomments);
$feedbackcomments = $plugin3->get_feedback_comments($grade3->id);
$this->assertNotEmpty($feedbackcomments);
$feedbackcomments = $plugin4->get_feedback_comments($grade4->id);
$this->assertNotEmpty($feedbackcomments);
$feedbackcomments = $plugin5->get_feedback_comments($grade5->id);
$this->assertNotEmpty($feedbackcomments);
$fs = new \file_storage();
// 6 including directories for assign 1.
// 4 including directories for assign 2.
$this->assertCount(6, $fs->get_area_files($assign1->get_context()->id,
ASSIGNFEEDBACK_COMMENTS_COMPONENT, ASSIGNFEEDBACK_COMMENTS_FILEAREA));
$this->assertCount(4, $fs->get_area_files($assign2->get_context()->id,
ASSIGNFEEDBACK_COMMENTS_COMPONENT, ASSIGNFEEDBACK_COMMENTS_FILEAREA));
$deletedata = new \mod_assign\privacy\assign_plugin_request_data($assign1->get_context(), $assign1);
$deletedata->set_userids([$user1->id, $user3->id]);
$deletedata->populate_submissions_and_grades();
provider::delete_feedback_for_grades($deletedata);
// Check that grade 1 and grade 3 have been removed.
$feedbackcomments = $plugin1->get_feedback_comments($grade1->id);
$this->assertEmpty($feedbackcomments);
$feedbackcomments = $plugin2->get_feedback_comments($grade2->id);
$this->assertNotEmpty($feedbackcomments);
$feedbackcomments = $plugin3->get_feedback_comments($grade3->id);
$this->assertEmpty($feedbackcomments);
$feedbackcomments = $plugin4->get_feedback_comments($grade4->id);
$this->assertNotEmpty($feedbackcomments);
$feedbackcomments = $plugin5->get_feedback_comments($grade5->id);
$this->assertNotEmpty($feedbackcomments);
// We have deleted two from assign 1, and none from assign 2.
// 2 including directories for assign 1.
// 4 including directories for assign 2.
$this->assertCount(2, $fs->get_area_files($assign1->get_context()->id,
ASSIGNFEEDBACK_COMMENTS_COMPONENT, ASSIGNFEEDBACK_COMMENTS_FILEAREA));
$this->assertCount(4, $fs->get_area_files($assign2->get_context()->id,
ASSIGNFEEDBACK_COMMENTS_COMPONENT, ASSIGNFEEDBACK_COMMENTS_FILEAREA));
}
}
+29
View File
@@ -0,0 +1,29 @@
<?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/>.
/**
* This file contains the version information for the comments feedback plugin
*
* @package assignfeedback_comments
* @copyright 2012 NetSpot {@link http://www.netspot.com.au}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2024042200;
$plugin->requires = 2024041600;
$plugin->component = 'assignfeedback_comments';