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,47 @@
<?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_offline
* @copyright 2018 Adrian Greeve <adrian@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace assignfeedback_offline\privacy;
defined('MOODLE_INTERNAL') || die();
/**
* Privacy class for requesting user data.
*
* @package assignfeedback_offline
* @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\null_provider {
/**
* Get the language string identifier with the component's language
* file to explain why this plugin stores no data.
*
* @return string
*/
public static function get_reason(): string {
return 'privacy:nullproviderreason';
}
}
+26
View File
@@ -0,0 +1,26 @@
<?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_offline
* @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,204 @@
<?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 forms to create and edit an instance of this module
*
* @package assignfeedback_offline
* @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('Direct access to this script is forbidden.');
require_once($CFG->libdir.'/formslib.php');
require_once($CFG->dirroot.'/mod/assign/feedback/offline/importgradeslib.php');
/**
* Import grades form
*
* @package assignfeedback_offline
* @copyright 2012 NetSpot {@link http://www.netspot.com.au}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class assignfeedback_offline_import_grades_form extends moodleform implements renderable {
/**
* Create this grade import form
*/
public function definition() {
global $CFG, $PAGE, $DB;
$mform = $this->_form;
$params = $this->_customdata;
$renderer = $PAGE->get_renderer('assign');
// Visible elements.
$assignment = $params['assignment'];
$csvdata = $params['csvdata'];
$gradeimporter = $params['gradeimporter'];
$update = false;
$ignoremodified = $params['ignoremodified'];
$draftid = $params['draftid'];
if (!$gradeimporter) {
throw new \moodle_exception('invalidarguments');
return;
}
if ($csvdata) {
$gradeimporter->parsecsv($csvdata);
}
$scaleoptions = null;
if ($assignment->get_instance()->grade < 0) {
if ($scale = $DB->get_record('scale', array('id'=>-($assignment->get_instance()->grade)))) {
$scaleoptions = make_menu_from_list($scale->scale);
}
}
if (!$gradeimporter->init()) {
$thisurl = new moodle_url('/mod/assign/view.php', array('action'=>'viewpluginpage',
'pluginsubtype'=>'assignfeedback',
'plugin'=>'offline',
'pluginaction'=>'uploadgrades',
'id'=>$assignment->get_course_module()->id));
throw new \moodle_exception('invalidgradeimport', 'assignfeedback_offline', $thisurl);
return;
}
$mform->addElement('header', 'importgrades', get_string('importgrades', 'assignfeedback_offline'));
$updates = array();
while ($record = $gradeimporter->next()) {
$user = $record->user;
$grade = $record->grade;
$modified = $record->modified;
$userdesc = fullname($user);
if ($assignment->is_blind_marking()) {
$userdesc = get_string('hiddenuser', 'assign') . $assignment->get_uniqueid_for_user($user->id);
}
$usergrade = $assignment->get_user_grade($user->id, false);
// Note: we lose the seconds when converting to user date format - so must not count seconds in comparision.
$skip = false;
$stalemodificationdate = ($usergrade && $usergrade->timemodified > ($modified + 60));
if (!empty($scaleoptions)) {
// This is a scale - we need to convert any grades to indexes in the scale.
$scaleindex = array_search($grade, $scaleoptions);
if ($scaleindex !== false) {
$grade = $scaleindex;
} else {
$grade = '';
}
} else {
$grade = unformat_float($grade);
}
if ($usergrade && $usergrade->grade == $grade) {
// Skip - grade not modified.
$skip = true;
} else if (!isset($grade) || $grade === '' || $grade < 0) {
// Skip - grade has no value.
$skip = true;
} else if (!$ignoremodified && $stalemodificationdate) {
// Skip - grade has been modified.
$skip = true;
} else if ($assignment->grading_disabled($user->id)) {
// Skip grade is locked.
$skip = true;
} else if (($assignment->get_instance()->grade > -1) &&
(($grade < 0) || ($grade > $assignment->get_instance()->grade))) {
// Out of range.
$skip = true;
}
if (!$skip) {
$update = true;
if (!empty($scaleoptions)) {
$formattedgrade = $scaleoptions[$grade];
} else {
$gradeitem = $assignment->get_grade_item();
$formattedgrade = format_float($grade, $gradeitem->get_decimals());
}
$updates[] = get_string('gradeupdate', 'assignfeedback_offline',
array('grade'=>$formattedgrade, 'student'=>$userdesc));
}
if ($ignoremodified || !$stalemodificationdate) {
foreach ($record->feedback as $feedback) {
$plugin = $feedback['plugin'];
$field = $feedback['field'];
$newvalue = $feedback['value'];
$description = $feedback['description'];
$oldvalue = '';
if ($usergrade) {
$oldvalue = $plugin->get_editor_text($field, $usergrade->id);
}
if ($newvalue != $oldvalue) {
$update = true;
$updates[] = get_string('feedbackupdate', 'assignfeedback_offline',
array('text'=>$newvalue, 'field'=>$description, 'student'=>$userdesc));
}
}
}
}
$gradeimporter->close(false);
if ($update) {
$mform->addElement('html', $renderer->list_block_contents(array(), $updates));
} else {
$mform->addElement('html', get_string('nochanges', 'assignfeedback_offline'));
}
$mform->addElement('hidden', 'id', $assignment->get_course_module()->id);
$mform->setType('id', PARAM_INT);
$mform->addElement('hidden', 'action', 'viewpluginpage');
$mform->setType('action', PARAM_ALPHA);
$mform->addElement('hidden', 'confirm', 'true');
$mform->setType('confirm', PARAM_BOOL);
$mform->addElement('hidden', 'plugin', 'offline');
$mform->setType('plugin', PARAM_PLUGIN);
$mform->addElement('hidden', 'pluginsubtype', 'assignfeedback');
$mform->setType('pluginsubtype', PARAM_PLUGIN);
$mform->addElement('hidden', 'pluginaction', 'uploadgrades');
$mform->setType('pluginaction', PARAM_ALPHA);
$mform->addElement('hidden', 'importid', $gradeimporter->importid);
$mform->setType('importid', PARAM_INT);
$mform->addElement('hidden', 'encoding', $gradeimporter->get_encoding());
$mform->setType('encoding', PARAM_ALPHAEXT);
$mform->addElement('hidden', 'separator', $gradeimporter->get_separator());
$mform->setType('separator', PARAM_ALPHA);
$mform->addElement('hidden', 'ignoremodified', $ignoremodified);
$mform->setType('ignoremodified', PARAM_BOOL);
$mform->addElement('hidden', 'draftid', $draftid);
$mform->setType('draftid', PARAM_INT);
if ($update) {
$this->add_action_buttons(true, get_string('confirm'));
} else {
$mform->addElement('cancel');
$mform->closeHeaderBefore('cancel');
}
}
}
@@ -0,0 +1,216 @@
<?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 forms to create and edit an instance of this module
*
* @package assignfeedback_offline
* @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('Direct access to this script is forbidden.');
/**
* CSV Grade importer
*
* @package assignfeedback_offline
* @copyright 2012 NetSpot {@link http://www.netspot.com.au}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class assignfeedback_offline_grade_importer {
/** @var string $importid - unique id for this import operation - must be passed between requests */
public $importid;
/** @var csv_import_reader $csvreader - the csv importer class */
private $csvreader;
/** @var assignment $assignment - the assignment class */
private $assignment;
/** @var int $gradeindex the column index containing the grades */
private $gradeindex = -1;
/** @var int $idindex the column index containing the unique id */
private $idindex = -1;
/** @var int $modifiedindex the column index containing the last modified time */
private $modifiedindex = -1;
/** @var array $validusers only the enrolled users with the correct capability in this course */
private $validusers;
/** @var array $feedbackcolumnindexes A lookup of column indexes for feedback plugin text import columns */
private $feedbackcolumnindexes = array();
/** @var string $encoding Encoding to use when reading the csv file. Defaults to utf-8. */
private $encoding;
/** @var string $separator How each bit of information is separated in the file. Defaults to comma separated. */
private $separator;
/**
* Constructor
*
* @param string $importid A unique id for this import
* @param assign $assignment The current assignment
*/
public function __construct($importid, assign $assignment, $encoding = 'utf-8', $separator = 'comma') {
$this->importid = $importid;
$this->assignment = $assignment;
$this->encoding = $encoding;
$this->separator = $separator;
}
/**
* Parse a csv file and save the content to a temp file
* Should be called before init()
*
* @param string $csvdata The csv data
* @return bool false is a failed import
*/
public function parsecsv($csvdata) {
$this->csvreader = new csv_import_reader($this->importid, 'assignfeedback_offline');
$this->csvreader->load_csv_content($csvdata, $this->encoding, $this->separator);
}
/**
* Initialise the import reader and locate the column indexes.
*
* @return bool false is a failed import
*/
public function init() {
if ($this->csvreader == null) {
$this->csvreader = new csv_import_reader($this->importid, 'assignfeedback_offline');
}
$this->csvreader->init();
$columns = $this->csvreader->get_columns();
$strgrade = get_string('gradenoun');
$strid = get_string('recordid', 'assign');
$strmodified = get_string('lastmodifiedgrade', 'assign');
foreach ($this->assignment->get_feedback_plugins() as $plugin) {
if ($plugin->is_enabled() && $plugin->is_visible()) {
foreach ($plugin->get_editor_fields() as $field => $description) {
$this->feedbackcolumnindexes[$description] = array('plugin'=>$plugin,
'field'=>$field,
'description'=>$description);
}
}
}
if ($columns) {
foreach ($columns as $index => $column) {
if (isset($this->feedbackcolumnindexes[$column])) {
$this->feedbackcolumnindexes[$column]['index'] = $index;
}
if ($column == $strgrade) {
$this->gradeindex = $index;
}
if ($column == $strid) {
$this->idindex = $index;
}
if ($column == $strmodified) {
$this->modifiedindex = $index;
}
}
}
if ($this->idindex < 0 || $this->gradeindex < 0 || $this->modifiedindex < 0) {
return false;
}
$groupmode = groups_get_activity_groupmode($this->assignment->get_course_module());
// All users.
$groupid = 0;
$groupname = '';
if ($groupmode) {
$groupid = groups_get_activity_group($this->assignment->get_course_module(), true);
$groupname = groups_get_group_name($groupid).'-';
}
$this->validusers = $this->assignment->list_participants($groupid, false);
return true;
}
/**
* Return the encoding for this csv import.
*
* @return string The encoding for this csv import.
*/
public function get_encoding() {
return $this->encoding;
}
/**
* Return the separator for this csv import.
*
* @return string The separator for this csv import.
*/
public function get_separator() {
return $this->separator;
}
/**
* Get the next row of data from the csv file (only the columns we care about)
*
* @return stdClass or false The stdClass is an object containing user, grade and lastmodified
*/
public function next() {
global $DB;
$result = new stdClass();
while ($record = $this->csvreader->next()) {
$idstr = $record[$this->idindex];
// Strip the integer from the end of the participant string.
$id = substr($idstr, strlen(get_string('hiddenuser', 'assign')));
if ($userid = $this->assignment->get_user_id_for_uniqueid($id)) {
if (array_key_exists($userid, $this->validusers)) {
$result->grade = $record[$this->gradeindex];
$result->modified = strtotime($record[$this->modifiedindex]);
$result->user = $this->validusers[$userid];
$result->feedback = array();
foreach ($this->feedbackcolumnindexes as $description => $details) {
if (!empty($details['index'])) {
$details['value'] = $record[$details['index']];
$result->feedback[] = $details;
}
}
return $result;
}
}
}
// If we got here the csvreader had no more rows.
return false;
}
/**
* Close the grade importer file and optionally delete any temp files
*
* @param bool $delete
*/
public function close($delete) {
$this->csvreader->close();
if ($delete) {
$this->csvreader->cleanup();
}
}
}
@@ -0,0 +1,49 @@
<?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 'feedback_offline', language 'en'
*
* @package assignfeedback_offline
* @copyright 2012 NetSpot {@link http://www.netspot.com.au}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$string['confirmimport'] = 'Confirm grades import';
$string['default'] = 'Enabled by default';
$string['default_help'] = 'If set, offline grading with worksheets will be enabled by default for all new assignments.';
$string['downloadgrades'] = 'Download grading worksheet';
$string['enabled'] = 'Offline grading worksheet';
$string['enabled_help'] = 'If enabled, the teacher will be able to download and upload a worksheet with student grades when marking the assignments.';
$string['feedbackupdate'] = 'Set field "{$a->field}" for "{$a->student}" to "{$a->text}"';
$string['graderecentlymodified'] = 'The grade has been modified in Moodle more recently than in the grading worksheet for {$a}';
$string['gradelockedingradebook'] = 'The grade has been locked in the gradebook for {$a}';
$string['gradeupdate'] = 'Set grade for {$a->student} to {$a->grade}';
$string['ignoremodified'] = 'Allow updating records that have been modified more recently in Moodle than in the spreadsheet.';
$string['ignoremodified_help'] = 'When the grading worksheet is downloaded from Moodle it contains the last modified date for each of the grades. If any of the grades are updated in Moodle after this worksheet is downloaded, by default Moodle will refuse to overwrite this updated information when importing the grades. By selecting this option Moodle will disable this safety check and it may be possible for multiple markers to overwrite each others grades.';
$string['importgrades'] = 'Confirm changes in grading worksheet';
$string['invalidgradeimport'] = 'Moodle could not read the uploaded worksheet. Make sure it is saved in comma separated value format (.csv) and try again.';
$string['gradesfile'] = 'Grading worksheet (csv format)';
$string['gradesfile_help'] = 'Grading worksheet with modified grades. This file must be a CSV file with UTF-8 encoding that has been downloaded from the assignment, with columns for student grade and identifier.';
$string['privacy:nullproviderreason'] = 'This plugin has no database to store user information. It only uses APIs in mod_assign to help with displaying the grading interface.';
$string['nochanges'] = 'No modified grades found in uploaded worksheet';
$string['offlinegradingworksheet'] = 'Grades';
$string['pluginname'] = 'Offline grading worksheet';
$string['processgrades'] = 'Import grades';
$string['skiprecord'] = 'Skip record';
$string['updaterecord'] = 'Update record';
$string['uploadgrades'] = 'Upload grading worksheet';
$string['updatedgrades'] = 'Updated <strong>{$a->gradeupdatescount}</strong> grades and <strong>{$a->feedbackupdatescount}</strong> feedback instances.';
+425
View File
@@ -0,0 +1,425 @@
<?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 file feedback plugin
*
*
* @package assignfeedback_offline
* @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();
use \mod_assign\output\assign_header;
require_once($CFG->dirroot.'/grade/grading/lib.php');
/**
* library class for file feedback plugin extending feedback plugin base class
*
* @package assignfeedback_offline
* @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_offline extends assign_feedback_plugin {
/** @var boolean|null $enabledcache Cached lookup of the is_enabled function */
private $enabledcache = null;
/**
* Get the name of the file feedback plugin
* @return string
*/
public function get_name() {
return get_string('pluginname', 'assignfeedback_offline');
}
/**
* Get form elements for grading form
*
* @param stdClass $grade
* @param MoodleQuickForm $mform
* @param stdClass $data
* @return bool true if elements were added to the form
*/
public function get_form_elements($grade, MoodleQuickForm $mform, stdClass $data) {
return false;
}
/**
* Return true if there are no feedback files
* @param stdClass $grade
*/
public function is_empty(stdClass $grade) {
return true;
}
/**
* This plugin does not save through the normal interface so this returns false.
*
* @param stdClass $grade The grade.
* @param stdClass $data Form data from the feedback form.
* @return boolean - False
*/
public function is_feedback_modified(stdClass $grade, stdClass $data) {
return false;
}
/**
* Loop through uploaded grades and update the grades for this assignment
*
* @param int $draftid - The unique draft item id for this import
* @param int $importid - The unique import ID for this csv import operation
* @param bool $ignoremodified - Ignore the last modified date when checking fields
* @param string $encoding - Encoding of the file being processed.
* @param string $separator - The character used to separate the information.
* @return string - The html response
*/
public function process_import_grades($draftid, $importid, $ignoremodified, $encoding = 'utf-8', $separator = 'comma') {
global $USER, $DB;
require_sesskey();
require_capability('mod/assign:grade', $this->assignment->get_context());
$gradeimporter = new assignfeedback_offline_grade_importer($importid, $this->assignment, $encoding, $separator);
$context = context_user::instance($USER->id);
$fs = get_file_storage();
if (!$files = $fs->get_area_files($context->id, 'user', 'draft', $draftid, 'id DESC', false)) {
redirect(new moodle_url('view.php',
array('id'=>$this->assignment->get_course_module()->id,
'action'=>'grading')));
return;
}
$file = reset($files);
$csvdata = $file->get_content();
if ($csvdata) {
$gradeimporter->parsecsv($csvdata);
}
if (!$gradeimporter->init()) {
$thisurl = new moodle_url('/mod/assign/view.php', array('action'=>'viewpluginpage',
'pluginsubtype'=>'assignfeedback',
'plugin'=>'offline',
'pluginaction'=>'uploadgrades',
'id' => $this->assignment->get_course_module()->id));
throw new \moodle_exception('invalidgradeimport', 'assignfeedback_offline', $thisurl);
return;
}
// Does this assignment use a scale?
$scaleoptions = null;
if ($this->assignment->get_instance()->grade < 0) {
if ($scale = $DB->get_record('scale', array('id'=>-($this->assignment->get_instance()->grade)))) {
$scaleoptions = make_menu_from_list($scale->scale);
}
}
// We may need to upgrade the gradebook comments after this update.
$adminconfig = $this->assignment->get_admin_config();
$gradebookplugin = $adminconfig->feedback_plugin_for_gradebook;
$updategradecount = 0;
$updatefeedbackcount = 0;
while ($record = $gradeimporter->next()) {
$user = $record->user;
$modified = $record->modified;
$userdesc = fullname($user);
$usergrade = $this->assignment->get_user_grade($user->id, false);
if (!empty($scaleoptions)) {
// This is a scale - we need to convert any grades to indexes in the scale.
$scaleindex = array_search($record->grade, $scaleoptions);
if ($scaleindex !== false) {
$record->grade = $scaleindex;
} else {
$record->grade = '';
}
} else {
$record->grade = unformat_float($record->grade);
}
// Note: Do not count the seconds when comparing modified dates.
$skip = false;
$stalemodificationdate = ($usergrade && $usergrade->timemodified > ($modified + 60));
if ($usergrade && $usergrade->grade == $record->grade) {
// Skip - grade not modified.
$skip = true;
} else if (!isset($record->grade) || $record->grade === '' || $record->grade < 0) {
// Skip - grade has no value.
$skip = true;
} else if (!$ignoremodified && $stalemodificationdate) {
// Skip - grade has been modified.
$skip = true;
} else if ($this->assignment->grading_disabled($record->user->id)) {
// Skip grade is locked.
$skip = true;
} else if (($this->assignment->get_instance()->grade > -1) &&
(($record->grade < 0) || ($record->grade > $this->assignment->get_instance()->grade))) {
// Out of range.
$skip = true;
}
if (!$skip) {
$grade = $this->assignment->get_user_grade($record->user->id, true);
$grade->grade = $record->grade;
$grade->grader = $USER->id;
if ($this->assignment->update_grade($grade)) {
$this->assignment->notify_grade_modified($grade);
$updategradecount += 1;
}
}
if ($ignoremodified || !$stalemodificationdate) {
foreach ($record->feedback as $feedback) {
$plugin = $feedback['plugin'];
$field = $feedback['field'];
$newvalue = $feedback['value'];
$description = $feedback['description'];
$oldvalue = '';
if ($usergrade) {
$oldvalue = $plugin->get_editor_text($field, $usergrade->id);
if (empty($oldvalue)) {
$oldvalue = '';
}
}
if ($newvalue != $oldvalue) {
$updatefeedbackcount += 1;
$grade = $this->assignment->get_user_grade($record->user->id, true);
$this->assignment->notify_grade_modified($grade);
$plugin->set_editor_text($field, $newvalue, $grade->id);
// If this is the gradebook comments plugin - post an update to the gradebook.
if (($plugin->get_subtype() . '_' . $plugin->get_type()) == $gradebookplugin) {
$grade->feedbacktext = $plugin->text_for_gradebook($grade);
$grade->feedbackformat = $plugin->format_for_gradebook($grade);
$this->assignment->update_grade($grade);
}
}
}
}
}
$gradeimporter->close(true);
$renderer = $this->assignment->get_renderer();
$o = '';
$o .= $renderer->render(new assign_header($this->assignment->get_instance(),
$this->assignment->get_context(),
false,
$this->assignment->get_course_module()->id,
get_string('importgrades', 'assignfeedback_offline')));
$strparams = [
'gradeupdatescount' => $updategradecount,
'feedbackupdatescount' => $updatefeedbackcount,
];
$o .= $renderer->box(get_string('updatedgrades', 'assignfeedback_offline', $strparams));
$url = new moodle_url('view.php',
array('id'=>$this->assignment->get_course_module()->id,
'action'=>'grading'));
$o .= $renderer->continue_button($url);
$o .= $renderer->render_footer();
return $o;
}
/**
* Display upload grades form
*
* @return string The response html
*/
public function upload_grades() {
global $CFG, $USER;
require_capability('mod/assign:grade', $this->assignment->get_context());
require_once($CFG->dirroot . '/mod/assign/feedback/offline/uploadgradesform.php');
require_once($CFG->dirroot . '/mod/assign/feedback/offline/importgradesform.php');
require_once($CFG->dirroot . '/mod/assign/feedback/offline/importgradeslib.php');
require_once($CFG->libdir . '/csvlib.class.php');
$mform = new assignfeedback_offline_upload_grades_form(null,
array('context'=>$this->assignment->get_context(),
'cm'=>$this->assignment->get_course_module()->id));
$o = '';
$confirm = optional_param('confirm', 0, PARAM_BOOL);
$renderer = $this->assignment->get_renderer();
if ($mform->is_cancelled()) {
redirect(new moodle_url('view.php',
array('id'=>$this->assignment->get_course_module()->id,
'action'=>'grading')));
return;
} else if (($data = $mform->get_data()) &&
($csvdata = $mform->get_file_content('gradesfile'))) {
$importid = csv_import_reader::get_new_iid('assignfeedback_offline');
$gradeimporter = new assignfeedback_offline_grade_importer($importid, $this->assignment,
$data->encoding, $data->separator);
// File exists and was valid.
$ignoremodified = !empty($data->ignoremodified);
$draftid = $data->gradesfile;
// Preview import.
$mform = new assignfeedback_offline_import_grades_form(null, array('assignment'=>$this->assignment,
'csvdata'=>$csvdata,
'ignoremodified'=>$ignoremodified,
'gradeimporter'=>$gradeimporter,
'draftid'=>$draftid));
$o .= $renderer->render(new assign_header($this->assignment->get_instance(),
$this->assignment->get_context(),
false,
$this->assignment->get_course_module()->id,
get_string('confirmimport', 'assignfeedback_offline')));
$o .= $renderer->render(new assign_form('confirmimport', $mform));
$o .= $renderer->render_footer();
} else if ($confirm) {
$importid = optional_param('importid', 0, PARAM_INT);
$draftid = optional_param('draftid', 0, PARAM_INT);
$encoding = optional_param('encoding', 'utf-8', PARAM_ALPHANUMEXT);
$separator = optional_param('separator', 'comma', PARAM_ALPHA);
$ignoremodified = optional_param('ignoremodified', 0, PARAM_BOOL);
$gradeimporter = new assignfeedback_offline_grade_importer($importid, $this->assignment, $encoding, $separator);
$mform = new assignfeedback_offline_import_grades_form(null, array('assignment'=>$this->assignment,
'csvdata'=>'',
'ignoremodified'=>$ignoremodified,
'gradeimporter'=>$gradeimporter,
'draftid'=>$draftid));
if ($mform->is_cancelled()) {
redirect(new moodle_url('view.php',
array('id'=>$this->assignment->get_course_module()->id,
'action'=>'grading')));
return;
}
$o .= $this->process_import_grades($draftid, $importid, $ignoremodified, $encoding, $separator);
} else {
$o .= $renderer->render(new assign_header($this->assignment->get_instance(),
$this->assignment->get_context(),
false,
$this->assignment->get_course_module()->id,
get_string('uploadgrades', 'assignfeedback_offline')));
$o .= $renderer->render(new assign_form('batchuploadfiles', $mform));
$o .= $renderer->render_footer();
}
return $o;
}
/**
* Download a marking worksheet
*
* @return string The response html
*/
public function download_grades() {
global $CFG;
require_capability('mod/assign:grade', $this->assignment->get_context());
require_once($CFG->dirroot . '/mod/assign/gradingtable.php');
$groupmode = groups_get_activity_groupmode($this->assignment->get_course_module());
// All users.
$groupid = 0;
$groupname = '';
if ($groupmode) {
$groupid = groups_get_activity_group($this->assignment->get_course_module(), true);
$groupname = groups_get_group_name($groupid) . '-';
}
$filename = clean_filename(get_string('offlinegradingworksheet', 'assignfeedback_offline') . '-' .
$this->assignment->get_course()->shortname . '-' .
$this->assignment->get_instance()->name . '-' .
$groupname .
$this->assignment->get_course_module()->id);
$table = new assign_grading_table($this->assignment, 0, '', 0, false, $filename);
$table->out(0, false);
return;
}
/**
* Print a sub page in this plugin
*
* @param string $action - The plugin action
* @return string The response html
*/
public function view_page($action) {
if ($action == 'downloadgrades') {
return $this->download_grades();
} else if ($action == 'uploadgrades') {
return $this->upload_grades();
}
return '';
}
/**
* Return a list of the grading actions performed by this plugin
* This plugin supports upload zip
*
* @return array The list of grading actions
*/
public function get_grading_actions() {
return array('uploadgrades'=>get_string('uploadgrades', 'assignfeedback_offline'),
'downloadgrades'=>get_string('downloadgrades', 'assignfeedback_offline'));
}
/**
* Override the default is_enabled to disable this plugin if advanced grading is active
*
* @return bool
*/
public function is_enabled() {
if ($this->enabledcache === null) {
$gradingmanager = get_grading_manager($this->assignment->get_context(), 'mod_assign', 'submissions');
$controller = $gradingmanager->get_active_controller();
$active = !empty($controller);
if ($active) {
$this->enabledcache = false;
} else {
$this->enabledcache = parent::is_enabled();
}
}
return $this->enabledcache;
}
/**
* Do not show this plugin in the grading table or on the front page
*
* @return bool
*/
public function has_user_summary() {
return false;
}
/**
* 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();
}
}
+28
View File
@@ -0,0 +1,28 @@
<?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_offline
* @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_offline/default',
new lang_string('default', 'assignfeedback_offline'),
new lang_string('default_help', 'assignfeedback_offline'), 0));
@@ -0,0 +1,89 @@
<?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 forms to create and edit an instance of this module
*
* @package assignfeedback_offline
* @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('Direct access to this script is forbidden.');
require_once($CFG->libdir.'/formslib.php');
/**
* Upload modified grading worksheet
*
* @package assignfeedback_offline
* @copyright 2012 NetSpot {@link http://www.netspot.com.au}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class assignfeedback_offline_upload_grades_form extends moodleform {
/**
* Define this form - called by the parent constructor
*/
public function definition() {
global $COURSE, $USER;
$mform = $this->_form;
$params = $this->_customdata;
$mform->addElement('header', 'uploadgrades', get_string('uploadgrades', 'assignfeedback_offline'));
$fileoptions = array('subdirs'=>0,
'maxbytes'=>$COURSE->maxbytes,
'accepted_types'=>'csv',
'maxfiles'=>1,
'return_types'=>FILE_INTERNAL);
$mform->addElement('filepicker', 'gradesfile', get_string('uploadafile'), null, $fileoptions);
$mform->addRule('gradesfile', get_string('uploadnofilefound'), 'required', null, 'client');
$mform->addHelpButton('gradesfile', 'gradesfile', 'assignfeedback_offline');
$encodings = core_text::get_encodings();
$mform->addElement('select', 'encoding', get_string('encoding', 'grades'), $encodings);
$mform->addHelpButton('encoding', 'encoding', 'grades');
$radio = array();
$radio[] = $mform->createElement('radio', 'separator', null, get_string('septab', 'grades'), 'tab');
$radio[] = $mform->createElement('radio', 'separator', null, get_string('sepcomma', 'grades'), 'comma');
$radio[] = $mform->createElement('radio', 'separator', null, get_string('sepcolon', 'grades'), 'colon');
$radio[] = $mform->createElement('radio', 'separator', null, get_string('sepsemicolon', 'grades'), 'semicolon');
$mform->addGroup($radio, 'separator', get_string('separator', 'grades'), ' ', false);
$mform->addHelpButton('separator', 'separator', 'grades');
$mform->setDefault('separator', 'comma');
$mform->addElement('checkbox', 'ignoremodified', '', get_string('ignoremodified', 'assignfeedback_offline'));
$mform->addHelpButton('ignoremodified', 'ignoremodified', 'assignfeedback_offline');
$mform->addElement('hidden', 'id', $params['cm']);
$mform->setType('id', PARAM_INT);
$mform->addElement('hidden', 'action', 'viewpluginpage');
$mform->setType('action', PARAM_ALPHA);
$mform->addElement('hidden', 'pluginaction', 'uploadgrades');
$mform->setType('pluginaction', PARAM_ALPHA);
$mform->addElement('hidden', 'plugin', 'offline');
$mform->setType('plugin', PARAM_PLUGIN);
$mform->addElement('hidden', 'pluginsubtype', 'assignfeedback');
$mform->setType('pluginsubtype', PARAM_PLUGIN);
$this->add_action_buttons(true, get_string('uploadgrades', 'assignfeedback_offline'));
}
}
+30
View File
@@ -0,0 +1,30 @@
<?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 offline feedback plugin
*
* @package assignfeedback_offline
* @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_offline';