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
+232
View File
@@ -0,0 +1,232 @@
<?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/>.
if (!defined('MOODLE_INTERNAL')) {
die('Direct access to this script is forbidden.'); /// It must be included from a Moodle page
}
require_once $CFG->libdir.'/formslib.php';
class grade_export_form extends moodleform {
function definition() {
global $CFG, $COURSE, $USER, $DB;
$isdeprecatedui = false;
$mform =& $this->_form;
if (isset($this->_customdata)) { // hardcoding plugin names here is hacky
$features = $this->_customdata;
} else {
$features = array();
}
if (empty($features['simpleui'])) {
debugging('Grade export plugin needs updating to support one step exports.', DEBUG_DEVELOPER);
}
$mform->addElement('header', 'gradeitems', get_string('gradeitemsinc', 'grades'));
$mform->setExpanded('gradeitems', true);
if (!empty($features['idnumberrequired'])) {
$mform->addElement('static', 'idnumberwarning', get_string('useridnumberwarning', 'grades'));
}
$switch = grade_get_setting($COURSE->id, 'aggregationposition', $CFG->grade_aggregationposition);
// Grab the grade_seq for this course
$gseq = new grade_seq($COURSE->id, $switch);
if ($grade_items = $gseq->items) {
$needs_multiselect = false;
$canviewhidden = has_capability('moodle/grade:viewhidden', context_course::instance($COURSE->id));
foreach ($grade_items as $grade_item) {
// Is the grade_item hidden? If so, can the user see hidden grade_items?
if ($grade_item->is_hidden() && !$canviewhidden) {
continue;
}
if (!empty($features['idnumberrequired']) and empty($grade_item->idnumber)) {
$mform->addElement('checkbox', 'itemids['.$grade_item->id.']', $grade_item->get_name(), get_string('noidnumber', 'grades'));
$mform->hardFreeze('itemids['.$grade_item->id.']');
} else {
$mform->addElement('advcheckbox', 'itemids['.$grade_item->id.']', $grade_item->get_name(), null, array('group' => 1));
$mform->setDefault('itemids['.$grade_item->id.']', 1);
$needs_multiselect = true;
}
}
if ($needs_multiselect) {
$this->add_checkbox_controller(1, null, null, 1); // 1st argument is group name, 2nd is link text, 3rd is attributes and 4th is original value
}
}
$mform->addElement('header', 'options', get_string('exportformatoptions', 'grades'));
if (!empty($features['simpleui'])) {
$mform->setExpanded('options', false);
}
$mform->addElement('advcheckbox', 'export_feedback', get_string('exportfeedback', 'grades'));
$exportfeedback = isset($CFG->grade_export_exportfeedback) ? $CFG->grade_export_exportfeedback : 0;
$mform->setDefault('export_feedback', $exportfeedback);
$coursecontext = context_course::instance($COURSE->id);
if (has_capability('moodle/course:viewsuspendedusers', $coursecontext)) {
$mform->addElement('advcheckbox', 'export_onlyactive', get_string('exportonlyactive', 'grades'));
$mform->setType('export_onlyactive', PARAM_BOOL);
$mform->setDefault('export_onlyactive', 1);
$mform->addHelpButton('export_onlyactive', 'exportonlyactive', 'grades');
} else {
$mform->addElement('hidden', 'export_onlyactive', 1);
$mform->setType('export_onlyactive', PARAM_BOOL);
$mform->setConstant('export_onlyactive', 1);
}
if (empty($features['simpleui'])) {
$options = array('10'=>10, '20'=>20, '100'=>100, '1000'=>1000, '100000'=>100000);
$mform->addElement('select', 'previewrows', get_string('previewrows', 'grades'), $options);
}
if (!empty($features['updategradesonly'])) {
$mform->addElement('advcheckbox', 'updatedgradesonly', get_string('updatedgradesonly', 'grades'));
}
/// selections for decimal points and format, MDL-11667, defaults to site settings, if set
//$default_gradedisplaytype = $CFG->grade_export_displaytype;
$options = array(GRADE_DISPLAY_TYPE_REAL => get_string('real', 'grades'),
GRADE_DISPLAY_TYPE_PERCENTAGE => get_string('percentage', 'grades'),
GRADE_DISPLAY_TYPE_LETTER => get_string('letter', 'grades'));
/*
foreach ($options as $key=>$option) {
if ($key == $default_gradedisplaytype) {
$options[GRADE_DISPLAY_TYPE_DEFAULT] = get_string('defaultprev', 'grades', $option);
break;
}
}
*/
if ($features['multipledisplaytypes']) {
/*
* Using advcheckbox because we need the grade display type (name) as key and grade display type (constant) as value.
* The method format_column_name requires the lang file string and the format_grade method requires the constant.
*/
$checkboxes = array();
$checkboxes[] = $mform->createElement('advcheckbox', 'display[real]', null, get_string('real', 'grades'), null, array(0, GRADE_DISPLAY_TYPE_REAL));
$checkboxes[] = $mform->createElement('advcheckbox', 'display[percentage]', null, get_string('percentage', 'grades'), null, array(0, GRADE_DISPLAY_TYPE_PERCENTAGE));
$checkboxes[] = $mform->createElement('advcheckbox', 'display[letter]', null, get_string('letter', 'grades'), null, array(0, GRADE_DISPLAY_TYPE_LETTER));
$mform->addGroup($checkboxes, 'displaytypes', get_string('gradeexportdisplaytypes', 'grades'), ' ', false);
$mform->setDefault('display[real]', $CFG->grade_export_displaytype == GRADE_DISPLAY_TYPE_REAL);
$mform->setDefault('display[percentage]', $CFG->grade_export_displaytype == GRADE_DISPLAY_TYPE_PERCENTAGE);
$mform->setDefault('display[letter]', $CFG->grade_export_displaytype == GRADE_DISPLAY_TYPE_LETTER);
} else {
// Only used by XML grade export format.
$mform->addElement('select', 'display', get_string('gradeexportdisplaytype', 'grades'), $options);
$mform->setDefault('display', $CFG->grade_export_displaytype);
}
//$default_gradedecimals = $CFG->grade_export_decimalpoints;
$options = array(0=>0, 1=>1, 2=>2, 3=>3, 4=>4, 5=>5);
$mform->addElement('select', 'decimals', get_string('gradeexportdecimalpoints', 'grades'), $options);
$mform->setDefault('decimals', $CFG->grade_export_decimalpoints);
$mform->disabledIf('decimals', 'display', 'eq', GRADE_DISPLAY_TYPE_LETTER);
/*
if ($default_gradedisplaytype == GRADE_DISPLAY_TYPE_LETTER) {
$mform->disabledIf('decimals', 'display', "eq", GRADE_DISPLAY_TYPE_DEFAULT);
}
*/
if (!empty($features['includeseparator'])) {
$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->setDefault('separator', 'comma');
}
if (!empty($CFG->gradepublishing) and !empty($features['publishing'])) {
$mform->addElement('header', 'publishing', get_string('publishingoptions', 'grades'));
if (!empty($features['simpleui'])) {
$mform->setExpanded('publishing', false);
}
$options = array(get_string('nopublish', 'grades'), get_string('createnewkey', 'userkey'));
$keys = $DB->get_records_select('user_private_key', "script='grade/export' AND instance=? AND userid=?",
array($COURSE->id, $USER->id));
if ($keys) {
foreach ($keys as $key) {
$options[$key->value] = $key->value; // TODO: add more details - ip restriction, valid until ??
}
}
$mform->addElement('select', 'key', get_string('userkey', 'userkey'), $options);
$mform->addHelpButton('key', 'userkey', 'userkey');
$mform->addElement('static', 'keymanagerlink', get_string('keymanager', 'userkey'),
'<a href="'.$CFG->wwwroot.'/grade/export/keymanager.php?id='.$COURSE->id.'">'.get_string('keymanager', 'userkey').'</a>');
$mform->addElement('text', 'iprestriction', get_string('keyiprestriction', 'userkey'), array('size'=>80));
$mform->addHelpButton('iprestriction', 'keyiprestriction', 'userkey');
$mform->setDefault('iprestriction', getremoteaddr()); // own IP - just in case somebody does not know what user key is
$mform->setType('iprestriction', PARAM_RAW_TRIMMED);
$mform->addElement('date_time_selector', 'validuntil', get_string('keyvaliduntil', 'userkey'), array('optional'=>true));
$mform->addHelpButton('validuntil', 'keyvaliduntil', 'userkey');
$mform->setDefault('validuntil', time()+3600*24*7); // only 1 week default duration - just in case somebody does not know what user key is
$mform->setType('validuntil', PARAM_INT);
$mform->disabledIf('iprestriction', 'key', 'noteq', 1);
$mform->disabledIf('validuntil', 'key', 'noteq', 1);
}
$mform->addElement('hidden', 'id', $COURSE->id);
$mform->setType('id', PARAM_INT);
$submitstring = get_string('download');
if (empty($features['simpleui'])) {
$submitstring = get_string('submit');
} else if (!empty($CFG->gradepublishing)) {
$submitstring = get_string('export', 'grades');
}
$this->add_sticky_action_buttons(false, $submitstring);
}
/**
* Overrides the mform get_data method.
*
* Created to force a value since the validation method does not work with multiple checkbox.
*
* @return stdClass form data object.
*/
public function get_data() {
global $CFG;
$data = parent::get_data();
if ($data && $this->_customdata['multipledisplaytypes']) {
if (count(array_filter($data->display)) == 0) {
// Ensure that a value was selected as the export plugins expect at least one value.
if ($CFG->grade_export_displaytype == GRADE_DISPLAY_TYPE_LETTER) {
$data->display['letter'] = GRADE_DISPLAY_TYPE_LETTER;
} else if ($CFG->grade_export_displaytype == GRADE_DISPLAY_TYPE_PERCENTAGE) {
$data->display['percentage'] = GRADE_DISPLAY_TYPE_PERCENTAGE;
} else {
$data->display['real'] = GRADE_DISPLAY_TYPE_REAL;
}
}
}
return $data;
}
}
+64
View File
@@ -0,0 +1,64 @@
<?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/>.
/**
* Redirects the user to a default grades export plugin page.
*
* @package core_grades
* @copyright 2021 Mihail Geshoski <mihail@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once(__DIR__ . '/../../config.php');
// Course ID.
$courseid = required_param('id', PARAM_INT);
$PAGE->set_url(new moodle_url('/grade/export/index.php', ['id' => $courseid]));
// Basic access checks.
if (!$course = $DB->get_record('course', ['id' => $courseid])) {
throw new moodle_exception('invalidcourseid', 'error');
}
require_login($course);
$context = context_course::instance($courseid);
require_capability('moodle/grade:export', $context);
// Retrieve all grade export plugins the current user can access.
$exportplugins = array_filter(core_component::get_plugin_list('gradeexport'),
static function(string $exportplugin) use ($context): bool {
return has_capability("gradeexport/{$exportplugin}:view", $context);
},
ARRAY_FILTER_USE_KEY
);
if (!empty($exportplugins)) {
$exportplugin = isset($CFG->gradeexport_default, $exportplugins[$CFG->gradeexport_default])
? $CFG->gradeexport_default : array_key_first($exportplugins);
$url = new moodle_url("/grade/export/{$exportplugin}/index.php", ['id' => $courseid]);
redirect($url);
}
// Otherwise, output the page with a notification stating that there are no available grade export options.
$PAGE->set_title(get_string('export', 'grades'));
$PAGE->set_pagelayout('incourse');
$PAGE->set_heading($course->fullname);
$PAGE->set_pagetype('course-view-' . $course->format);
echo $OUTPUT->header();
echo $OUTPUT->heading(get_string('export', 'grades'));
echo html_writer::div($OUTPUT->notification(get_string('nogradeexport', 'debug'), 'error'), 'mt-3');
echo $OUTPUT->footer();
+145
View File
@@ -0,0 +1,145 @@
<?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/>.
/**
* Grade export key edit page.
*
* @package moodlecore
* @copyright 2008 Petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once('../../config.php');
require_once('key_form.php');
require_once($CFG->dirroot.'/grade/lib.php');
/// get url variables
$courseid = optional_param('courseid', 0, PARAM_INT);
$id = optional_param('id', 0, PARAM_INT); // The key's id
$delete = optional_param('delete', 0, PARAM_BOOL);
$confirm = optional_param('confirm', 0, PARAM_BOOL);
$PAGE->set_url('/grade/export/key.php', array('id' => $id, 'courseid' => $courseid));
if ($id) {
if (!$key = $DB->get_record('user_private_key', array('id' => $id))) {
throw new \moodle_exception('invalidgroupid');
}
if (empty($courseid)) {
$courseid = $key->instance;
} else if ($courseid != $key->instance) {
throw new \moodle_exception('invalidcourseid');
}
if (!$course = $DB->get_record('course', array('id'=>$courseid))) {
throw new \moodle_exception('invalidcourseid');
}
} else {
if (!$course = $DB->get_record('course', array('id'=>$courseid))) {
throw new \moodle_exception('invalidcourseid');
}
$key = new stdClass();
}
$key->courseid = $course->id;
require_login($course);
$context = context_course::instance($course->id);
require_capability('moodle/grade:export', $context);
// Check if the user has at least one grade publishing capability.
$plugins = grade_helper::get_plugins_export($course->id);
if (!isset($plugins['keymanager'])) {
throw new \moodle_exception('nopermissions');
}
// extra security check
if (!empty($key->userid) and $USER->id != $key->userid) {
throw new \moodle_exception('notownerofkey');
}
$returnurl = $CFG->wwwroot.'/grade/export/keymanager.php?id='.$course->id;
$strkeys = get_string('keymanager', 'userkey');
$strexportgrades = get_string('export', 'grades');
$PAGE->navbar->add($strexportgrades, new moodle_url('/grade/export/index.php', ['id' => $courseid]));
$PAGE->navbar->add($strkeys, new moodle_url('/grade/export/keymanager.php', ['id' => $courseid]));
if ($id and $delete) {
if (!$confirm) {
$PAGE->set_title(get_string('deleteselectedkey'));
$PAGE->set_heading($course->fullname);
$PAGE->set_secondary_active_tab('grades');
$PAGE->navbar->add(get_string('deleteuserkey', 'userkey'));
echo $OUTPUT->header();
$optionsyes = array('id'=>$id, 'delete'=>1, 'courseid'=>$courseid, 'sesskey'=>sesskey(), 'confirm'=>1);
$optionsno = array('id'=>$courseid);
$formcontinue = new single_button(new moodle_url('key.php', $optionsyes), get_string('yes'), 'get');
$formcancel = new single_button(new moodle_url('keymanager.php', $optionsno), get_string('no'), 'get');
echo $OUTPUT->confirm(get_string('deletekeyconfirm', 'userkey', $key->value), $formcontinue, $formcancel);
echo $OUTPUT->footer();
die;
} else if (confirm_sesskey()){
$DB->delete_records('user_private_key', array('id' => $id));
redirect('keymanager.php?id='.$course->id);
}
}
/// First create the form
$editform = new key_form();
$editform->set_data($key);
if ($editform->is_cancelled()) {
redirect($returnurl);
} elseif ($data = $editform->get_data()) {
if ($data->id) {
$record = new stdClass();
$record->id = $data->id;
$record->iprestriction = $data->iprestriction;
$record->validuntil = $data->validuntil;
$DB->update_record('user_private_key', $record);
} else {
create_user_key('grade/export', $USER->id, $course->id, $data->iprestriction, $data->validuntil);
}
redirect($returnurl);
}
if ($id) {
$strheading = get_string('edituserkey', 'userkey');
} else {
$strheading = get_string('createuserkey', 'userkey');
}
$PAGE->navbar->add($strheading);
/// Print header
$PAGE->set_title($strkeys);
$PAGE->set_heading($course->fullname);
$PAGE->set_secondary_active_tab('grades');
echo $OUTPUT->header();
echo $OUTPUT->heading($strheading);
$editform->display();
echo $OUTPUT->footer();
+58
View File
@@ -0,0 +1,58 @@
<?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/>.
/**
* Grade export key management form.
*
* @package moodlecore
* @copyright 2008 Petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
if (!defined('MOODLE_INTERNAL')) {
die('Direct access to this script is forbidden.'); /// It must be included from a Moodle page
}
require_once($CFG->dirroot.'/lib/formslib.php');
class key_form extends moodleform {
// Define the form
function definition() {
global $USER, $CFG, $COURSE;
$mform =& $this->_form;
$mform->addElement('static', 'value', get_string('keyvalue', 'userkey'));
$mform->addElement('text', 'iprestriction', get_string('keyiprestriction', 'userkey'), array('size'=>80));
$mform->setType('iprestriction', PARAM_RAW_TRIMMED);
$mform->addElement('date_time_selector', 'validuntil', get_string('keyvaliduntil', 'userkey'), array('optional'=>true));
$mform->setType('validuntil', PARAM_INT);
$mform->addHelpButton('iprestriction', 'keyiprestriction', 'userkey');
$mform->addHelpButton('validuntil', 'keyvaliduntil', 'userkey');
$mform->addElement('hidden','id');
$mform->setType('id', PARAM_INT);
$mform->addElement('hidden','courseid');
$mform->setType('courseid', PARAM_INT);
$this->add_action_buttons();
}
}
+88
View File
@@ -0,0 +1,88 @@
<?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/>.
/**
* Grade export key management page.
*
* @package moodlecore
* @copyright 2008 Petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once '../../config.php';
require_once $CFG->dirroot.'/grade/export/lib.php';
$id = required_param('id', PARAM_INT); // course id
$PAGE->set_url('/grade/export/keymanager.php', array('id' => $id));
if (!$course = $DB->get_record('course', array('id'=>$id))) {
throw new \moodle_exception('invalidcourseid');
}
require_login($course);
$context = context_course::instance($id);
require_capability('moodle/grade:export', $context);
// Check if the user has at least one grade publishing capability.
$plugins = grade_helper::get_plugins_export($course->id);
if (!isset($plugins['keymanager'])) {
throw new \moodle_exception('nopermissions');
}
$actionbar = new \core_grades\output\export_key_manager_action_bar($context);
print_grade_page_head($COURSE->id, 'export', 'keymanager',
get_string('keymanager', 'grades'), false, false, true, null,
null, null, $actionbar);
$stredit = get_string('edit');
$strdelete = get_string('delete');
$data = array();
$keys = $DB->get_records_select('user_private_key', "script='grade/export' AND instance=? AND userid=?", array($course->id, $USER->id));
if ($keys) {
foreach($keys as $key) {
$line = array();
$line[0] = format_string($key->value);
$line[1] = $key->iprestriction;
$line[2] = empty($key->validuntil) ? get_string('always') : userdate($key->validuntil);
$url = new moodle_url('key.php');
if (!empty($key->id)) {
$url->param('id', $key->id);
}
$buttons = $OUTPUT->action_icon($url, new pix_icon('t/edit', $stredit));
$url->param('delete', 1);
$url->param('sesskey', sesskey());
$buttons .= $OUTPUT->action_icon($url, new pix_icon('t/delete', $strdelete));
$line[3] = $buttons;
$data[] = $line;
}
}
$table = new html_table();
$table->head = array(get_string('keyvalue', 'userkey'), get_string('keyiprestriction', 'userkey'), get_string('keyvaliduntil', 'userkey'), $stredit);
$table->size = array('50%', '30%', '10%', '10%');
$table->align = array('left', 'left', 'left', 'center');
$table->width = '90%';
$table->data = $data;
echo html_writer::table($table);
echo $OUTPUT->footer();
+720
View File
@@ -0,0 +1,720 @@
<?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/>.
require_once($CFG->dirroot.'/lib/gradelib.php');
require_once($CFG->dirroot.'/grade/lib.php');
require_once($CFG->dirroot.'/grade/export/grade_export_form.php');
/**
* Base export class
*/
abstract class grade_export {
/** @var int Value to state nothing is being exported. */
protected const EXPORT_SELECT_NONE = -1;
public $plugin; // plgin name - must be filled in subclasses!
public $grade_items; // list of all course grade items
public $groupid; // groupid, 0 means all groups
public $course; // course object
public $columns; // array of grade_items selected for export
public $export_letters; // export letters
public $export_feedback; // export feedback
public $userkey; // export using private user key
public $updatedgradesonly; // only export updated grades
/**
* Grade display type (real, percentages or letter).
*
* This attribute is an integer for XML file export. Otherwise is an array for all other formats (ODS, XLS and TXT).
*
* @var $displaytype Grade display type constant (1, 2 or 3) or an array of display types where the key is the name
* and the value is the grade display type constant or 0 for unchecked display types.
* @access public.
*/
public $displaytype;
public $decimalpoints; // number of decimal points for exports
public $onlyactive; // only include users with an active enrolment
public $usercustomfields; // include users custom fields
/**
* @deprecated since Moodle 2.8
* @var $previewrows Number of rows in preview.
*/
public $previewrows;
/**
* Constructor should set up all the private variables ready to be pulled.
*
* This constructor used to accept the individual parameters as separate arguments, in
* 2.8 this was simplified to just accept the data from the moodle form.
*
* @access public
* @param object $course
* @param int $groupid
* @param stdClass|null $formdata
* @note Exporting as letters will lead to data loss if that exported set it re-imported.
*/
public function __construct($course, $groupid, $formdata) {
if (func_num_args() != 3 || ($formdata != null && get_class($formdata) != "stdClass")) {
$args = func_get_args();
return call_user_func_array(array($this, "deprecated_constructor"), $args);
}
$this->course = $course;
$this->groupid = $groupid;
$this->grade_items = grade_item::fetch_all(array('courseid'=>$this->course->id));
$this->process_form($formdata);
}
/**
* Old deprecated constructor.
*
* This deprecated constructor accepts the individual parameters as separate arguments, in
* 2.8 this was simplified to just accept the data from the moodle form.
*
* @deprecated since 2.8 MDL-46548. Instead call the shortened constructor which accepts the data
* directly from the grade_export_form.
*/
protected function deprecated_constructor($course,
$groupid=0,
$itemlist='',
$export_feedback=false,
$updatedgradesonly = false,
$displaytype = GRADE_DISPLAY_TYPE_REAL,
$decimalpoints = 2,
$onlyactive = false,
$usercustomfields = false) {
debugging('Many argument constructor for class "grade_export" is deprecated. Call the 3 argument version instead.', DEBUG_DEVELOPER);
$this->course = $course;
$this->groupid = $groupid;
$this->grade_items = grade_item::fetch_all(array('courseid'=>$this->course->id));
//Populating the columns here is required by /grade/export/(whatever)/export.php
//however index.php, when the form is submitted, will construct the collection here
//with an empty $itemlist then reconstruct it in process_form() using $formdata
$this->columns = array();
if (!empty($itemlist)) {
// Check that user selected something.
if ($itemlist != self::EXPORT_SELECT_NONE) {
$itemids = explode(',', $itemlist);
// remove items that are not requested
foreach ($itemids as $itemid) {
if (array_key_exists($itemid, $this->grade_items)) {
$this->columns[$itemid] =& $this->grade_items[$itemid];
}
}
}
} else {
foreach ($this->grade_items as $itemid=>$unused) {
$this->columns[$itemid] =& $this->grade_items[$itemid];
}
}
$this->export_feedback = $export_feedback;
$this->userkey = '';
$this->previewrows = false;
$this->updatedgradesonly = $updatedgradesonly;
$this->displaytype = $displaytype;
$this->decimalpoints = $decimalpoints;
$this->onlyactive = $onlyactive;
$this->usercustomfields = $usercustomfields;
}
/**
* Init object based using data from form
* @param object $formdata
*/
function process_form($formdata) {
global $USER;
$this->columns = array();
if (!empty($formdata->itemids)) {
// Check that user selected something.
if ($formdata->itemids != self::EXPORT_SELECT_NONE) {
foreach ($formdata->itemids as $itemid=>$selected) {
if ($selected and array_key_exists($itemid, $this->grade_items)) {
$this->columns[$itemid] =& $this->grade_items[$itemid];
}
}
}
} else {
foreach ($this->grade_items as $itemid=>$unused) {
$this->columns[$itemid] =& $this->grade_items[$itemid];
}
}
if (isset($formdata->key)) {
if ($formdata->key == 1 && isset($formdata->iprestriction) && isset($formdata->validuntil)) {
// Create a new key
$formdata->key = create_user_key('grade/export', $USER->id, $this->course->id, $formdata->iprestriction, $formdata->validuntil);
}
$this->userkey = $formdata->key;
}
if (isset($formdata->decimals)) {
$this->decimalpoints = $formdata->decimals;
}
if (isset($formdata->export_letters)) {
$this->export_letters = $formdata->export_letters;
}
if (isset($formdata->export_feedback)) {
$this->export_feedback = $formdata->export_feedback;
}
if (isset($formdata->export_onlyactive)) {
$this->onlyactive = $formdata->export_onlyactive;
}
if (isset($formdata->previewrows)) {
$this->previewrows = $formdata->previewrows;
}
if (isset($formdata->display)) {
$this->displaytype = $formdata->display;
// Used by grade exports which accept multiple display types.
// If the checkbox value is 0 (unchecked) then remove it.
if (is_array($formdata->display)) {
$this->displaytype = array_filter($formdata->display);
}
}
if (isset($formdata->updatedgradesonly)) {
$this->updatedgradesonly = $formdata->updatedgradesonly;
}
}
/**
* Update exported field in grade_grades table
* @return boolean
*/
public function track_exports() {
global $CFG;
/// Whether this plugin is entitled to update export time
if ($expplugins = explode(",", $CFG->gradeexport)) {
if (in_array($this->plugin, $expplugins)) {
return true;
} else {
return false;
}
} else {
return false;
}
}
/**
* Returns string representation of final grade
* @param object $grade instance of grade_grade class
* @param integer $gradedisplayconst grade display type constant.
* @return string
*/
public function format_grade($grade, $gradedisplayconst = null) {
$displaytype = $this->displaytype;
if (is_array($this->displaytype) && !is_null($gradedisplayconst)) {
$displaytype = $gradedisplayconst;
}
$gradeitem = $this->grade_items[$grade->itemid];
// We are going to store the min and max so that we can "reset" the grade_item for later.
$grademax = $gradeitem->grademax;
$grademin = $gradeitem->grademin;
// Updating grade_item with this grade_grades min and max.
$gradeitem->grademax = $grade->get_grade_max();
$gradeitem->grademin = $grade->get_grade_min();
$formattedgrade = grade_format_gradevalue($grade->finalgrade, $gradeitem, false, $displaytype, $this->decimalpoints);
// Resetting the grade item in case it is reused.
$gradeitem->grademax = $grademax;
$gradeitem->grademin = $grademin;
return $formattedgrade;
}
/**
* Returns the name of column in export
* @param object $grade_item
* @param boolean $feedback feedback colum
* @param string $gradedisplayname grade display name.
* @return string
*/
public function format_column_name($grade_item, $feedback=false, $gradedisplayname = null) {
$column = new stdClass();
if ($grade_item->itemtype == 'mod') {
$column->name = get_string('modulename', $grade_item->itemmodule).get_string('labelsep', 'langconfig').$grade_item->get_name();
} else {
$column->name = $grade_item->get_name(true);
}
// We can't have feedback and display type at the same time.
$column->extra = ($feedback) ? get_string('feedback') : get_string($gradedisplayname, 'grades');
return html_to_text(get_string('gradeexportcolumntype', 'grades', $column), 0, false);
}
/**
* Returns formatted grade feedback
* @param object $feedback object with properties feedback and feedbackformat
* @param object $grade Grade object with grade properties
* @return string
*/
public function format_feedback($feedback, $grade = null) {
$string = $feedback->feedback;
if (!empty($grade)) {
// Rewrite links to get the export working for 36, refer MDL-63488.
$string = file_rewrite_pluginfile_urls(
$feedback->feedback,
'pluginfile.php',
$grade->get_context()->id,
GRADE_FILE_COMPONENT,
GRADE_FEEDBACK_FILEAREA,
$grade->id
);
}
return strip_tags(format_text($string, $feedback->feedbackformat));
}
/**
* Implemented by child class
*/
abstract public function print_grades();
/**
* Prints preview of exported grades on screen as a feedback mechanism
* @param bool $require_user_idnumber true means skip users without idnumber
* @deprecated since 2.8 MDL-46548. Previews are not useful on export.
*/
public function display_preview($require_user_idnumber=false) {
global $OUTPUT;
debugging('function grade_export::display_preview is deprecated.', DEBUG_DEVELOPER);
$userprofilefields = grade_helper::get_user_profile_fields($this->course->id, $this->usercustomfields);
$formatoptions = new stdClass();
$formatoptions->para = false;
echo $OUTPUT->heading(get_string('previewrows', 'grades'));
echo '<table>';
echo '<tr>';
foreach ($userprofilefields as $field) {
echo '<th>' . $field->fullname . '</th>';
}
if (!$this->onlyactive) {
echo '<th>'.get_string("suspended")."</th>";
}
foreach ($this->columns as $grade_item) {
echo '<th>'.$this->format_column_name($grade_item).'</th>';
/// add a column_feedback column
if ($this->export_feedback) {
echo '<th>'.$this->format_column_name($grade_item, true).'</th>';
}
}
echo '</tr>';
/// Print all the lines of data.
$i = 0;
$gui = new graded_users_iterator($this->course, $this->columns, $this->groupid);
$gui->require_active_enrolment($this->onlyactive);
$gui->allow_user_custom_fields($this->usercustomfields);
$gui->init();
while ($userdata = $gui->next_user()) {
// number of preview rows
if ($this->previewrows and $this->previewrows <= $i) {
break;
}
$user = $userdata->user;
if ($require_user_idnumber and empty($user->idnumber)) {
// some exports require user idnumber so we can match up students when importing the data
continue;
}
$gradeupdated = false; // if no grade is update at all for this user, do not display this row
$rowstr = '';
foreach ($this->columns as $itemid=>$unused) {
$gradetxt = $this->format_grade($userdata->grades[$itemid]);
// get the status of this grade, and put it through track to get the status
$g = new grade_export_update_buffer();
$grade_grade = new grade_grade(array('itemid'=>$itemid, 'userid'=>$user->id));
$status = $g->track($grade_grade);
if ($this->updatedgradesonly && ($status == 'nochange' || $status == 'unknown')) {
$rowstr .= '<td>'.get_string('unchangedgrade', 'grades').'</td>';
} else {
$rowstr .= "<td>$gradetxt</td>";
$gradeupdated = true;
}
if ($this->export_feedback) {
$rowstr .= '<td>'.$this->format_feedback($userdata->feedbacks[$itemid]).'</td>';
}
}
// if we are requesting updated grades only, we are not interested in this user at all
if (!$gradeupdated && $this->updatedgradesonly) {
continue;
}
echo '<tr>';
foreach ($userprofilefields as $field) {
$fieldvalue = grade_helper::get_user_field_value($user, $field);
// @see profile_field_base::display_data().
echo '<td>' . format_text($fieldvalue, FORMAT_MOODLE, $formatoptions) . '</td>';
}
if (!$this->onlyactive) {
$issuspended = ($user->suspendedenrolment) ? get_string('yes') : '';
echo "<td>$issuspended</td>";
}
echo $rowstr;
echo "</tr>";
$i++; // increment the counter
}
echo '</table>';
$gui->close();
}
/**
* Returns array of parameters used by dump.php and export.php.
* @return array
*/
public function get_export_params() {
$itemids = array_keys($this->columns);
$itemidsparam = implode(',', $itemids);
if (empty($itemidsparam)) {
$itemidsparam = self::EXPORT_SELECT_NONE;
}
// We have a single grade display type constant.
if (!is_array($this->displaytype)) {
$displaytypes = $this->displaytype;
} else {
// Implode the grade display types array as moodle_url function doesn't accept arrays.
$displaytypes = implode(',', $this->displaytype);
}
if (!empty($this->updatedgradesonly)) {
$updatedgradesonly = $this->updatedgradesonly;
} else {
$updatedgradesonly = 0;
}
$params = array('id' => $this->course->id,
'groupid' => $this->groupid,
'itemids' => $itemidsparam,
'export_letters' => $this->export_letters,
'export_feedback' => $this->export_feedback,
'updatedgradesonly' => $updatedgradesonly,
'decimalpoints' => $this->decimalpoints,
'export_onlyactive' => $this->onlyactive,
'usercustomfields' => $this->usercustomfields,
'displaytype' => $displaytypes,
'key' => $this->userkey);
return $params;
}
/**
* Either prints a "Export" box, which will redirect the user to the download page,
* or prints the URL for the published data.
*
* @deprecated since 2.8 MDL-46548. Call get_export_url and set the
* action of the grade_export_form instead.
* @return void
*/
public function print_continue() {
global $CFG, $OUTPUT;
debugging('function grade_export::print_continue is deprecated.', DEBUG_DEVELOPER);
$params = $this->get_export_params();
echo $OUTPUT->heading(get_string('export', 'grades'));
echo $OUTPUT->container_start('gradeexportlink');
if (!$this->userkey) {
// This button should trigger a download prompt.
$url = new moodle_url('/grade/export/'.$this->plugin.'/export.php', $params);
echo $OUTPUT->single_button($url, get_string('download', 'admin'));
} else {
$paramstr = '';
$sep = '?';
foreach($params as $name=>$value) {
$paramstr .= $sep.$name.'='.$value;
$sep = '&';
}
$link = $CFG->wwwroot.'/grade/export/'.$this->plugin.'/dump.php'.$paramstr.'&key='.$this->userkey;
echo get_string('download', 'admin').': ' . html_writer::link($link, $link);
}
echo $OUTPUT->container_end();
return;
}
/**
* Generate the export url.
*
* Get submitted form data and create the url to be used on the grade publish feature.
*
* @return moodle_url the url of grade publishing export.
*/
public function get_export_url() {
return new moodle_url('/grade/export/'.$this->plugin.'/dump.php', $this->get_export_params());
}
/**
* Convert the grade display types parameter into the required array to grade exporting class.
*
* In order to export, the array key must be the display type name and the value must be the grade display type
* constant.
*
* Note: Added support for combined display types constants like the (GRADE_DISPLAY_TYPE_PERCENTAGE_REAL) as
* the $CFG->grade_export_displaytype config is still used on 2.7 in case of missing displaytype url param.
* In these cases, the file will be exported with a column for each display type.
*
* @param string $displaytypes can be a single or multiple display type constants comma separated.
* @return array $types
*/
public static function convert_flat_displaytypes_to_array($displaytypes) {
$types = array();
// We have a single grade display type constant.
if (is_int($displaytypes)) {
$displaytype = clean_param($displaytypes, PARAM_INT);
// Let's set a default value, will be replaced below by the grade display type constant.
$display[$displaytype] = 1;
} else {
// Multiple grade display types constants.
$display = array_flip(explode(',', $displaytypes));
}
// Now, create the array in the required format by grade exporting class.
foreach ($display as $type => $value) {
$type = clean_param($type, PARAM_INT);
if ($type == GRADE_DISPLAY_TYPE_LETTER) {
$types['letter'] = GRADE_DISPLAY_TYPE_LETTER;
} else if ($type == GRADE_DISPLAY_TYPE_PERCENTAGE) {
$types['percentage'] = GRADE_DISPLAY_TYPE_PERCENTAGE;
} else if ($type == GRADE_DISPLAY_TYPE_REAL) {
$types['real'] = GRADE_DISPLAY_TYPE_REAL;
} else if ($type == GRADE_DISPLAY_TYPE_REAL_PERCENTAGE) {
$types['real'] = GRADE_DISPLAY_TYPE_REAL;
$types['percentage'] = GRADE_DISPLAY_TYPE_PERCENTAGE;
} else if ($type == GRADE_DISPLAY_TYPE_REAL_LETTER) {
$types['real'] = GRADE_DISPLAY_TYPE_REAL;
$types['letter'] = GRADE_DISPLAY_TYPE_LETTER;
} else if ($type == GRADE_DISPLAY_TYPE_LETTER_REAL) {
$types['letter'] = GRADE_DISPLAY_TYPE_LETTER;
$types['real'] = GRADE_DISPLAY_TYPE_REAL;
} else if ($type == GRADE_DISPLAY_TYPE_LETTER_PERCENTAGE) {
$types['letter'] = GRADE_DISPLAY_TYPE_LETTER;
$types['percentage'] = GRADE_DISPLAY_TYPE_PERCENTAGE;
} else if ($type == GRADE_DISPLAY_TYPE_PERCENTAGE_LETTER) {
$types['percentage'] = GRADE_DISPLAY_TYPE_PERCENTAGE;
$types['letter'] = GRADE_DISPLAY_TYPE_LETTER;
} else if ($type == GRADE_DISPLAY_TYPE_PERCENTAGE_REAL) {
$types['percentage'] = GRADE_DISPLAY_TYPE_PERCENTAGE;
$types['real'] = GRADE_DISPLAY_TYPE_REAL;
}
}
return $types;
}
/**
* Convert the item ids parameter into the required array to grade exporting class.
*
* In order to export, the array key must be the grade item id and all values must be one.
*
* @param string $itemids can be a single item id or many item ids comma separated.
* @return array $items correctly formatted array.
*/
public static function convert_flat_itemids_to_array($itemids) {
$items = array();
// We just have one single item id.
if (is_int($itemids)) {
$itemid = clean_param($itemids, PARAM_INT);
$items[$itemid] = 1;
} else {
// Few grade items.
$items = array_flip(explode(',', $itemids));
foreach ($items as $itemid => $value) {
$itemid = clean_param($itemid, PARAM_INT);
$items[$itemid] = 1;
}
}
return $items;
}
/**
* Create the html code of the grade publishing feature.
*
* @return string $output html code of the grade publishing.
*/
public function get_grade_publishing_url() {
$url = $this->get_export_url();
$output = html_writer::start_div();
$output .= html_writer::tag('p', get_string('gradepublishinglink', 'grades', html_writer::link($url, $url)));
$output .= html_writer::end_div();
return $output;
}
/**
* Create a stdClass object from URL parameters to be used by grade_export class.
*
* @param int $id course id.
* @param string $itemids grade items comma separated.
* @param bool $exportfeedback export feedback option.
* @param bool $onlyactive only enrolled active students.
* @param string $displaytype grade display type constants comma separated.
* @param int $decimalpoints grade decimal points.
* @param null $updatedgradesonly recently updated grades only (Used by XML exporting only).
* @param null $separator separator character: tab, comma, colon and semicolon (Used by TXT exporting only).
*
* @return stdClass $formdata
*/
public static function export_bulk_export_data($id, $itemids, $exportfeedback, $onlyactive, $displaytype,
$decimalpoints, $updatedgradesonly = null, $separator = null) {
$formdata = new \stdClass();
$formdata->id = $id;
$formdata->itemids = self::convert_flat_itemids_to_array($itemids);
$formdata->exportfeedback = $exportfeedback;
$formdata->export_onlyactive = $onlyactive;
$formdata->display = self::convert_flat_displaytypes_to_array($displaytype);
$formdata->decimals = $decimalpoints;
if (!empty($updatedgradesonly)) {
$formdata->updatedgradesonly = $updatedgradesonly;
}
if (!empty($separator)) {
$formdata->separator = $separator;
}
return $formdata;
}
}
/**
* This class is used to update the exported field in grade_grades.
* It does internal buffering to speedup the db operations.
*/
class grade_export_update_buffer {
public $update_list;
public $export_time;
/**
* Constructor - creates the buffer and initialises the time stamp
*/
public function __construct() {
$this->update_list = array();
$this->export_time = time();
}
/**
* Old syntax of class constructor. Deprecated in PHP7.
*
* @deprecated since Moodle 3.1
*/
public function grade_export_update_buffer() {
debugging('Use of class name as constructor is deprecated', DEBUG_DEVELOPER);
self::__construct();
}
public function flush($buffersize) {
global $CFG, $DB;
if (count($this->update_list) > $buffersize) {
list($usql, $params) = $DB->get_in_or_equal($this->update_list);
$params = array_merge(array($this->export_time), $params);
$sql = "UPDATE {grade_grades} SET exported = ? WHERE id $usql";
$DB->execute($sql, $params);
$this->update_list = array();
}
}
/**
* Track grade export status
* @param object $grade_grade
* @return string $status (unknow, new, regrade, nochange)
*/
public function track($grade_grade) {
if (empty($grade_grade->exported) or empty($grade_grade->timemodified)) {
if (is_null($grade_grade->finalgrade)) {
// grade does not exist yet
$status = 'unknown';
} else {
$status = 'new';
$this->update_list[] = $grade_grade->id;
}
} else if ($grade_grade->exported < $grade_grade->timemodified) {
$status = 'regrade';
$this->update_list[] = $grade_grade->id;
} else if ($grade_grade->exported >= $grade_grade->timemodified) {
$status = 'nochange';
} else {
// something is wrong?
$status = 'unknown';
}
$this->flush(100);
return $status;
}
/**
* Flush and close the buffer.
*/
public function close() {
$this->flush(0);
}
}
/**
* Verify that there is a valid set of grades to export.
* @param $courseid int The course being exported
*/
function export_verify_grades($courseid) {
if (grade_needs_regrade_final_grades($courseid)) {
throw new moodle_exception('gradesneedregrading', 'grades');
}
}
@@ -0,0 +1,38 @@
<?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/>.
/**
* Grade export event.
*
* @package gradeexport_ods
* @copyright 2016 Zane Karl <zkarl@oid.ucla.edu>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace gradeexport_ods\event;
defined('MOODLE_INTERNAL') || die();
/**
* Grade export event class.
*
* @package gradeexport_ods
* @since Moodle 3.2
* @copyright 2016 Zane Karl <zkarl@oid.ucla.edu>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class grade_exported extends \core\event\grade_exported {
}
@@ -0,0 +1,46 @@
<?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 Subsystem implementation for gradeexport_ods.
*
* @package gradeexport_ods
* @copyright 2018 Sara Arjona <sara@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace gradeexport_ods\privacy;
defined('MOODLE_INTERNAL') || die();
/**
* Privacy Subsystem for gradeexport_ods implementing null_provider.
*
* @copyright 2018 Sara Arjona <sara@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:metadata';
}
}
+51
View File
@@ -0,0 +1,51 @@
<?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/>.
/**
* Capabilities gradeexport plugin.
*
* @package gradeexport_ods
* @copyright 2007 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$capabilities = array(
'gradeexport/ods:view' => array(
'riskbitmask' => RISK_PERSONAL,
'captype' => 'read',
'contextlevel' => CONTEXT_COURSE,
'archetypes' => array(
'teacher' => CAP_ALLOW,
'editingteacher' => CAP_ALLOW,
'manager' => CAP_ALLOW
)
),
'gradeexport/ods:publish' => array(
'riskbitmask' => RISK_PERSONAL,
'captype' => 'read',
'contextlevel' => CONTEXT_COURSE,
'archetypes' => array(
'manager' => CAP_ALLOW
)
)
);
+56
View File
@@ -0,0 +1,56 @@
<?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/>.
define('NO_MOODLE_COOKIES', true); // session not used here
require_once '../../../config.php';
require_once($CFG->dirroot.'/grade/export/ods/grade_export_ods.php');
$id = required_param('id', PARAM_INT);
$groupid = optional_param('groupid', 0, PARAM_INT);
$itemids = required_param('itemids', PARAM_RAW);
$exportfeedback = optional_param('export_feedback', 0, PARAM_BOOL);
$displaytype = optional_param('displaytype', $CFG->grade_export_displaytype, PARAM_RAW);
$decimalpoints = optional_param('decimalpoints', $CFG->grade_export_decimalpoints, PARAM_INT);
$onlyactive = optional_param('export_onlyactive', 0, PARAM_BOOL);
if (!$course = $DB->get_record('course', array('id'=>$id))) {
throw new \moodle_exception('invalidcourseid');
}
require_user_key_login('grade/export', $id); // we want different keys for each course
if (empty($CFG->gradepublishing)) {
throw new \moodle_exception('gradepubdisable');
}
$context = context_course::instance($id);
require_capability('moodle/grade:export', $context);
require_capability('gradeexport/ods:view', $context);
require_capability('gradeexport/ods:publish', $context);
if (!groups_group_visible($groupid, $COURSE)) {
throw new \moodle_exception('cannotaccessgroup', 'grades');
}
// Get all url parameters and create an object to simulate a form submission.
$formdata = grade_export::export_bulk_export_data($id, $itemids, $exportfeedback, $onlyactive, $displaytype,
$decimalpoints);
$export = new grade_export_ods($course, $groupid, $formdata);
$export->print_grades();
+64
View File
@@ -0,0 +1,64 @@
<?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/>.
require_once '../../../config.php';
require_once $CFG->dirroot.'/grade/export/lib.php';
require_once 'grade_export_ods.php';
$id = required_param('id', PARAM_INT); // course id
$PAGE->set_url('/grade/export/ods/export.php', array('id'=>$id));
if (!$course = $DB->get_record('course', array('id'=>$id))) {
throw new \moodle_exception('invalidcourseid');
}
require_login($course);
$context = context_course::instance($id);
$groupid = groups_get_course_group($course, true);
require_capability('moodle/grade:export', $context);
require_capability('gradeexport/ods:view', $context);
// We need to call this method here before any output otherwise the menu won't display.
// If you use this method without this check, will break the direct grade exporting (without publishing).
$key = optional_param('key', '', PARAM_RAW);
if (!empty($CFG->gradepublishing) && !empty($key)) {
$actionbar = new \core_grades\output\export_publish_action_bar($context, 'ods');
print_grade_page_head($COURSE->id, 'export', 'ods',
get_string('exportto', 'grades') . ' ' . get_string('pluginname', 'gradeexport_ods'),
false, false, true, null, null, null, $actionbar);
}
if (groups_get_course_groupmode($COURSE) == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context)) {
if (!groups_is_member($groupid, $USER->id)) {
throw new \moodle_exception('cannotaccessgroup', 'grades');
}
}
$mform = new grade_export_form(null, array('publishing' => true, 'simpleui' => true, 'multipledisplaytypes' => true));
$data = $mform->get_data();
$export = new grade_export_ods($course, $groupid, $data);
// If the gradepublishing is enabled and user key is selected print the grade publishing link.
if (!empty($CFG->gradepublishing) && !empty($key)) {
groups_print_course_menu($course, 'index.php?id='.$id);
echo $export->get_grade_publishing_url();
echo $OUTPUT->footer();
} else {
$event = \gradeexport_ods\event\grade_exported::create(array('context' => $context));
$event->trigger();
$export->print_grades();
}
+135
View File
@@ -0,0 +1,135 @@
<?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/>.
require_once($CFG->dirroot.'/grade/export/lib.php');
class grade_export_ods extends grade_export {
public $plugin = 'ods';
/**
* Constructor should set up all the private variables ready to be pulled
* @param object $course
* @param int $groupid id of selected group, 0 means all
* @param stdClass $formdata The validated data from the grade export form.
*/
public function __construct($course, $groupid, $formdata) {
parent::__construct($course, $groupid, $formdata);
// Overrides.
$this->usercustomfields = true;
}
/**
* To be implemented by child classes
*/
function print_grades() {
global $CFG;
require_once($CFG->dirroot.'/lib/odslib.class.php');
$export_tracking = $this->track_exports();
$strgrades = get_string('grades');
$shortname = format_string($this->course->shortname, true, array('context' => context_course::instance($this->course->id)));
// Calculate file name
$downloadfilename = clean_filename("$shortname $strgrades.ods");
// Creating a workbook
$workbook = new MoodleODSWorkbook("-");
// Sending HTTP headers
$workbook->send($downloadfilename);
// Adding the worksheet
$myxls = $workbook->add_worksheet($strgrades);
// Print names of all the fields.
$profilefields = grade_helper::get_user_profile_fields($this->course->id, $this->usercustomfields);
foreach ($profilefields as $id => $field) {
$myxls->write_string(0, $id, $field->fullname);
}
$pos = count($profilefields);
if (!$this->onlyactive) {
$myxls->write_string(0, $pos++, get_string("suspended"));
}
foreach ($this->columns as $grade_item) {
foreach ($this->displaytype as $gradedisplayname => $gradedisplayconst) {
$myxls->write_string(0, $pos++, $this->format_column_name($grade_item, false, $gradedisplayname));
}
// Add a column_feedback column.
if ($this->export_feedback) {
$myxls->write_string(0, $pos++, $this->format_column_name($grade_item, true));
}
}
// Last downloaded column header.
$myxls->write_string(0, $pos++, get_string('timeexported', 'gradeexport_ods'));
// Print all the lines of data.
$i = 0;
$geub = new grade_export_update_buffer();
$gui = new graded_users_iterator($this->course, $this->columns, $this->groupid);
$gui->require_active_enrolment($this->onlyactive);
$gui->allow_user_custom_fields($this->usercustomfields);
$gui->init();
while ($userdata = $gui->next_user()) {
$i++;
$user = $userdata->user;
foreach($profilefields as $id => $field) {
$fieldvalue = grade_helper::get_user_field_value($user, $field);
$myxls->write_string($i, $id, $fieldvalue);
}
$j = count($profilefields);
if (!$this->onlyactive) {
$issuspended = ($user->suspendedenrolment) ? get_string('yes') : '';
$myxls->write_string($i, $j++, $issuspended);
}
foreach ($userdata->grades as $itemid => $grade) {
if ($export_tracking) {
$status = $geub->track($grade);
}
foreach ($this->displaytype as $gradedisplayconst) {
$gradestr = $this->format_grade($grade, $gradedisplayconst);
if (is_numeric($gradestr)) {
$myxls->write_number($i, $j++, $gradestr);
} else {
$myxls->write_string($i, $j++, $gradestr);
}
}
// writing feedback if requested
if ($this->export_feedback) {
$myxls->write_string($i, $j++, $this->format_feedback($userdata->feedbacks[$itemid], $grade));
}
}
// Time exported.
$myxls->write_string($i, $j++, time());
}
$gui->close();
$geub->close();
// Close the workbook.
$workbook->close();
exit;
}
}
+72
View File
@@ -0,0 +1,72 @@
<?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/>.
require_once '../../../config.php';
require_once $CFG->dirroot.'/grade/export/lib.php';
require_once 'grade_export_ods.php';
$id = required_param('id', PARAM_INT); // course id
$PAGE->set_url('/grade/export/ods/index.php', array('id'=>$id));
if (!$course = $DB->get_record('course', array('id'=>$id))) {
throw new \moodle_exception('invalidcourseid');
}
require_login($course);
$context = context_course::instance($id);
require_capability('moodle/grade:export', $context);
require_capability('gradeexport/ods:view', $context);
$actionbar = new \core_grades\output\export_action_bar($context, null, 'ods');
print_grade_page_head($COURSE->id, 'export', 'ods',
get_string('exportto', 'grades') . ' ' . get_string('pluginname', 'gradeexport_ods'),
false, false, true, null, null, null, $actionbar);
export_verify_grades($COURSE->id);
if (!empty($CFG->gradepublishing)) {
$CFG->gradepublishing = has_capability('gradeexport/ods:publish', $context);
}
$actionurl = new moodle_url('/grade/export/ods/export.php');
$formoptions = array(
'publishing' => true,
'simpleui' => true,
'multipledisplaytypes' => true
);
$mform = new grade_export_form($actionurl, $formoptions);
$groupmode = groups_get_course_groupmode($course); // Groups are being used.
$currentgroup = groups_get_course_group($course, true);
if (($groupmode == SEPARATEGROUPS) &&
(!$currentgroup) &&
(!has_capability('moodle/site:accessallgroups', $context))) {
echo $OUTPUT->heading(get_string("notingroup"));
echo $OUTPUT->footer();
die;
}
groups_print_course_menu($course, 'index.php?id='.$id);
echo '<div class="clearer"></div>';
$mform->display();
echo $OUTPUT->footer();
@@ -0,0 +1,31 @@
<?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 'gradeexport_ods', language 'en', branch 'MOODLE_20_STABLE'
*
* @package gradeexport_ods
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$string['eventgradeexported'] = 'OpenDocument grade exported';
$string['pluginname'] = 'OpenDocument spreadsheet';
$string['ods:publish'] = 'Publish ODS grade export';
$string['ods:view'] = 'Use OpenDocument grade export';
$string['privacy:metadata'] = 'The OpenDocument spreadsheet grade export plugin does not store any personal data.';
$string['timeexported'] = 'Last downloaded from this course';
@@ -0,0 +1,57 @@
<?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 gradeexport_ods\event;
/**
* ODS grade export events test cases.
*
* @package gradeexport_ods
* @copyright 2016 Zane Karl zkarl@oid.ucla.edu
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class events_test extends \advanced_testcase {
/**
* Setup is called before calling test case.
*/
public function setUp(): void {
$this->resetAfterTest();
}
/**
* Test course_module_instance_list_viewed event.
*/
public function test_logging(): void {
// There is no proper API to call to trigger this event, so what we are
// doing here is simply making sure that the events returns the right information.
$course = $this->getDataGenerator()->create_course();
$params = array(
'context' => \context_course::instance($course->id)
);
$event = \gradeexport_ods\event\grade_exported::create($params);
// Triggering and capturing the event.
$sink = $this->redirectEvents();
$event->trigger();
$events = $sink->get_events();
$this->assertCount(1, $events);
$event = reset($events);
// Checking that the event contains the expected values.
$this->assertInstanceOf('\gradeexport_ods\event\grade_exported', $event);
$this->assertEquals(\context_course::instance($course->id), $event->get_context());
$this->assertEquals('ods', $event->get_export_type());
}
}
+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/>.
/**
* Version details
*
* @package gradeexport
* @subpackage ods
* @copyright 1999 onwards Martin Dougiamas (http://dougiamas.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2024042200; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2024041600; // Requires this Moodle version.
$plugin->component = 'gradeexport_ods'; // Full name of the plugin (used for diagnostics)
@@ -0,0 +1,38 @@
<?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/>.
/**
* Grade export event.
*
* @package gradeexport_txt
* @copyright 2016 Zane Karl <zkarl@oid.ucla.edu>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace gradeexport_txt\event;
defined('MOODLE_INTERNAL') || die();
/**
* Grade export event class.
*
* @package gradeexport_txt
* @since Moodle 3.2
* @copyright 2016 Zane Karl <zkarl@oid.ucla.edu>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class grade_exported extends \core\event\grade_exported {
}
@@ -0,0 +1,46 @@
<?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 Subsystem implementation for gradeexport_txt.
*
* @package gradeexport_txt
* @copyright 2018 Sara Arjona <sara@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace gradeexport_txt\privacy;
defined('MOODLE_INTERNAL') || die();
/**
* Privacy Subsystem for gradeexport_txt implementing null_provider.
*
* @copyright 2018 Sara Arjona <sara@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:metadata';
}
}
+51
View File
@@ -0,0 +1,51 @@
<?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/>.
/**
* Capabilities gradeexport plugin.
*
* @package gradeexport_txt
* @copyright 2007 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$capabilities = array(
'gradeexport/txt:view' => array(
'riskbitmask' => RISK_PERSONAL,
'captype' => 'read',
'contextlevel' => CONTEXT_COURSE,
'archetypes' => array(
'teacher' => CAP_ALLOW,
'editingteacher' => CAP_ALLOW,
'manager' => CAP_ALLOW
)
),
'gradeexport/txt:publish' => array(
'riskbitmask' => RISK_PERSONAL,
'captype' => 'read',
'contextlevel' => CONTEXT_COURSE,
'archetypes' => array(
'manager' => CAP_ALLOW
)
)
);
+57
View File
@@ -0,0 +1,57 @@
<?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/>.
define('NO_MOODLE_COOKIES', true); // session not used here
require_once '../../../config.php';
require_once($CFG->dirroot.'/grade/export/txt/grade_export_txt.php');
$id = required_param('id', PARAM_INT);
$groupid = optional_param('groupid', 0, PARAM_INT);
$itemids = required_param('itemids', PARAM_RAW);
$exportfeedback = optional_param('export_feedback', 0, PARAM_BOOL);
$separator = optional_param('separator', 'comma', PARAM_ALPHA);
$displaytype = optional_param('displaytype', $CFG->grade_export_displaytype, PARAM_RAW);
$decimalpoints = optional_param('decimalpoints', $CFG->grade_export_decimalpoints, PARAM_INT);
$onlyactive = optional_param('export_onlyactive', 0, PARAM_BOOL);
if (!$course = $DB->get_record('course', array('id'=>$id))) {
throw new \moodle_exception('invalidcourseid');
}
require_user_key_login('grade/export', $id); // we want different keys for each course
if (empty($CFG->gradepublishing)) {
throw new \moodle_exception('gradepubdisable');
}
$context = context_course::instance($id);
require_capability('moodle/grade:export', $context);
require_capability('gradeexport/txt:publish', $context);
require_capability('gradeexport/txt:view', $context);
if (!groups_group_visible($groupid, $COURSE)) {
throw new \moodle_exception('cannotaccessgroup', 'grades');
}
// Get all url parameters and create an object to simulate a form submission.
$formdata = grade_export::export_bulk_export_data($id, $itemids, $exportfeedback, $onlyactive, $displaytype,
$decimalpoints, null, $separator);
$export = new grade_export_txt($course, $groupid, $formdata);
$export->print_grades();
+71
View File
@@ -0,0 +1,71 @@
<?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/>.
require_once '../../../config.php';
require_once $CFG->dirroot.'/grade/export/lib.php';
require_once 'grade_export_txt.php';
$id = required_param('id', PARAM_INT); // course id
$PAGE->set_url('/grade/export/txt/export.php', array('id'=>$id));
if (!$course = $DB->get_record('course', array('id'=>$id))) {
throw new \moodle_exception('invalidcourseid');
}
require_login($course);
$context = context_course::instance($id);
$groupid = groups_get_course_group($course, true);
require_capability('moodle/grade:export', $context);
require_capability('gradeexport/txt:view', $context);
// We need to call this method here before any print otherwise the menu won't display.
// If you use this method without this check, will break the direct grade exporting (without publishing).
$key = optional_param('key', '', PARAM_RAW);
if (!empty($CFG->gradepublishing) && !empty($key)) {
$actionbar = new \core_grades\output\export_publish_action_bar($context, 'txt');
print_grade_page_head($COURSE->id, 'export', 'txt',
get_string('exportto', 'grades') . ' ' . get_string('pluginname', 'gradeexport_txt'),
false, false, true, null, null, null, $actionbar);
}
if (groups_get_course_groupmode($COURSE) == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context)) {
if (!groups_is_member($groupid, $USER->id)) {
throw new \moodle_exception('cannotaccessgroup', 'grades');
}
}
$params = array(
'includeseparator'=>true,
'publishing' => true,
'simpleui' => true,
'multipledisplaytypes' => true
);
$mform = new grade_export_form(null, $params);
$data = $mform->get_data();
$export = new grade_export_txt($course, $groupid, $data);
// If the gradepublishing is enabled and user key is selected print the grade publishing link.
if (!empty($CFG->gradepublishing) && !empty($key)) {
groups_print_course_menu($course, 'index.php?id='.$id);
echo $export->get_grade_publishing_url();
echo $OUTPUT->footer();
} else {
$event = \gradeexport_txt\event\grade_exported::create(array('context' => $context));
$event->trigger();
$export->print_grades();
}
+126
View File
@@ -0,0 +1,126 @@
<?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/>.
require_once($CFG->dirroot.'/grade/export/lib.php');
require_once($CFG->libdir . '/csvlib.class.php');
class grade_export_txt extends grade_export {
public $plugin = 'txt';
public $separator; // default separator
/**
* Constructor should set up all the private variables ready to be pulled
* @param object $course
* @param int $groupid id of selected group, 0 means all
* @param stdClass $formdata The validated data from the grade export form.
*/
public function __construct($course, $groupid, $formdata) {
parent::__construct($course, $groupid, $formdata);
$this->separator = $formdata->separator;
// Overrides.
$this->usercustomfields = true;
}
public function get_export_params() {
$params = parent::get_export_params();
$params['separator'] = $this->separator;
return $params;
}
public function print_grades() {
global $CFG;
$export_tracking = $this->track_exports();
$strgrades = get_string('grades');
$profilefields = grade_helper::get_user_profile_fields($this->course->id, $this->usercustomfields);
$shortname = format_string($this->course->shortname, true, array('context' => context_course::instance($this->course->id)));
$downloadfilename = clean_filename("$shortname $strgrades");
$csvexport = new csv_export_writer($this->separator);
$csvexport->set_filename($downloadfilename);
// Print names of all the fields
$exporttitle = array();
foreach ($profilefields as $field) {
$exporttitle[] = $field->fullname;
}
if (!$this->onlyactive) {
$exporttitle[] = get_string("suspended");
}
// Add grades and feedback columns.
foreach ($this->columns as $grade_item) {
foreach ($this->displaytype as $gradedisplayname => $gradedisplayconst) {
$exporttitle[] = $this->format_column_name($grade_item, false, $gradedisplayname);
}
if ($this->export_feedback) {
$exporttitle[] = $this->format_column_name($grade_item, true);
}
}
// Last downloaded column header.
$exporttitle[] = get_string('timeexported', 'gradeexport_txt');
$csvexport->add_data($exporttitle);
// Print all the lines of data.
$geub = new grade_export_update_buffer();
$gui = new graded_users_iterator($this->course, $this->columns, $this->groupid);
$gui->require_active_enrolment($this->onlyactive);
$gui->allow_user_custom_fields($this->usercustomfields);
$gui->init();
while ($userdata = $gui->next_user()) {
$exportdata = array();
$user = $userdata->user;
foreach ($profilefields as $field) {
$fieldvalue = grade_helper::get_user_field_value($user, $field);
$exportdata[] = $fieldvalue;
}
if (!$this->onlyactive) {
$issuspended = ($user->suspendedenrolment) ? get_string('yes') : '';
$exportdata[] = $issuspended;
}
foreach ($userdata->grades as $itemid => $grade) {
if ($export_tracking) {
$status = $geub->track($grade);
}
foreach ($this->displaytype as $gradedisplayconst) {
$exportdata[] = $this->format_grade($grade, $gradedisplayconst);
}
if ($this->export_feedback) {
$exportdata[] = $this->format_feedback($userdata->feedbacks[$itemid], $grade);
}
}
// Time exported.
$exportdata[] = time();
$csvexport->add_data($exportdata);
}
$gui->close();
$geub->close();
$csvexport->download_file();
exit;
}
}
+73
View File
@@ -0,0 +1,73 @@
<?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/>.
require_once '../../../config.php';
require_once $CFG->dirroot.'/grade/export/lib.php';
require_once 'grade_export_txt.php';
$id = required_param('id', PARAM_INT); // course id
$PAGE->set_url('/grade/export/txt/index.php', array('id'=>$id));
if (!$course = $DB->get_record('course', array('id'=>$id))) {
throw new \moodle_exception('invalidcourseid');
}
require_login($course);
$context = context_course::instance($id);
require_capability('moodle/grade:export', $context);
require_capability('gradeexport/txt:view', $context);
$actionbar = new \core_grades\output\export_action_bar($context, null, 'txt');
print_grade_page_head($COURSE->id, 'export', 'txt',
get_string('exportto', 'grades') . ' ' . get_string('pluginname', 'gradeexport_txt'),
false, false, true, null, null, null, $actionbar);
export_verify_grades($COURSE->id);
if (!empty($CFG->gradepublishing)) {
$CFG->gradepublishing = has_capability('gradeexport/txt:publish', $context);
}
$actionurl = new moodle_url('/grade/export/txt/export.php');
$formoptions = array(
'includeseparator'=>true,
'publishing' => true,
'simpleui' => true,
'multipledisplaytypes' => true
);
$mform = new grade_export_form($actionurl, $formoptions);
$groupmode = groups_get_course_groupmode($course); // Groups are being used.
$currentgroup = groups_get_course_group($course, true);
if (($groupmode == SEPARATEGROUPS) &&
(!$currentgroup) &&
(!has_capability('moodle/site:accessallgroups', $context))) {
echo $OUTPUT->heading(get_string("notingroup"));
echo $OUTPUT->footer();
die;
}
groups_print_course_menu($course, 'index.php?id='.$id);
echo '<div class="clearer"></div>';
$mform->display();
echo $OUTPUT->footer();
@@ -0,0 +1,31 @@
<?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 'gradeexport_txt', language 'en', branch 'MOODLE_20_STABLE'
*
* @package gradeexport_txt
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$string['eventgradeexported'] = 'TXT grade exported';
$string['pluginname'] = 'Plain text file';
$string['privacy:metadata'] = 'The Plain text file grade export plugin does not store any personal data.';
$string['timeexported'] = 'Last downloaded from this course';
$string['txt:publish'] = 'Publish TXT grade export';
$string['txt:view'] = 'Use text grade export';
@@ -0,0 +1,77 @@
@gradeexport @gradeexport_txt
Feature: I need to export grades as text
In order to easily review marks
As a teacher
I need to have a export grades as text
Background:
Given the following "courses" exist:
| fullname | shortname | category | groupmode |
| Course 1 | C1 | 0 | 1 |
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 | course | idnumber | name | intro | assignsubmission_onlinetext_enabled |
| assign | C1 | a1 | Test assignment name | Submit your online text | 1 |
| assign | C1 | a2 | Test assignment name 2 | Submit your online text | 1 |
And the following "grade grades" exist:
| gradeitem | user | grade |
| Test assignment name | student1 | 80.00 |
And I am on the "Course 1" "grades > Grader report > View" page logged in as "teacher1"
@javascript
Scenario: Export grades as text
When I navigate to "Plain text file" export page in the course gradebook
And I expand all fieldsets
And I click on "Course total" "checkbox"
And I set the field "Grade export decimal places" to "1"
And I press "Download"
Then I should see "Student,1"
And I should see "80.0"
And I should not see "Course total"
And I should not see "80.00"
@javascript
Scenario: Export grades as text using real
When I navigate to "Plain text file" export page in the course gradebook
And I expand all fieldsets
And I set the following fields to these values:
| Real | 1 |
And I click on "Course total" "checkbox"
And I press "Download"
Then I should see "Student,1"
And I should see "80.00"
@javascript
Scenario: Export grades as text using percentages and letters
When I navigate to "Plain text file" export page in the course gradebook
And I set the following fields to these values:
| Percentage | 1 |
| Letter | 1 |
And I press "Download"
Then I should see "Student,1"
And I should see "80.00 %"
And I should see "B-"
And I should not see "40.00 %"
And I should not see ",F,"
@javascript
Scenario: Export grades as text using real, percentages and letters
When I navigate to "Plain text file" export page in the course gradebook
And I set the following fields to these values:
| Real | 1 |
| Percentage | 1 |
| Letter | 1 |
And I press "Download"
Then I should see "Student,1"
And I should see "80.00"
And I should see "80.00 %"
And I should see "B-"
And I should not see "40.00 %"
And I should not see ",F,"
@@ -0,0 +1,57 @@
<?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 gradeexport_txt\event;
/**
* TXT grade export events test cases.
*
* @package gradeexport_txt
* @copyright 2016 Zane Karl zkarl@oid.ucla.edu
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class events_test extends \advanced_testcase {
/**
* Setup is called before calling test case.
*/
public function setUp(): void {
$this->resetAfterTest();
}
/**
* Test course_module_instance_list_viewed event.
*/
public function test_logging(): void {
// There is no proper API to call to trigger this event, so what we are
// doing here is simply making sure that the events returns the right information.
$course = $this->getDataGenerator()->create_course();
$params = array(
'context' => \context_course::instance($course->id)
);
$event = \gradeexport_txt\event\grade_exported::create($params);
// Triggering and capturing the event.
$sink = $this->redirectEvents();
$event->trigger();
$events = $sink->get_events();
$this->assertCount(1, $events);
$event = reset($events);
// Checking that the event contains the expected values.
$this->assertInstanceOf('\gradeexport_txt\event\grade_exported', $event);
$this->assertEquals(\context_course::instance($course->id), $event->get_context());
$this->assertEquals('txt', $event->get_export_type());
}
}
+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/>.
/**
* Version details
*
* @package gradeexport
* @subpackage txt
* @copyright 1999 onwards Martin Dougiamas (http://dougiamas.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2024042200; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2024041600; // Requires this Moodle version.
$plugin->component = 'gradeexport_txt'; // Full name of the plugin (used for diagnostics)
+7
View File
@@ -0,0 +1,7 @@
This files describes API changes in /grade/export/* - plugins,
information provided here is intended especially for developers.
=== 2.8 ===
The UI for the grade export form was simplified down so it's all on one page. The export preview was removed because it was not useful (more useful on import than on export). To update your export plugins you must pass 'simpleui' => true as an option to the grade_export_form, and make your grade_export_form submit directly to your export script. It's easiest to look at a complete example - see "git show 1cc43058" for a complete example of updating the ods exporter.
Also the grade export UI form was changed to support multiples display types. The combo box was removed from (Open Document, Plain Text, Excel) and for each selected display type a column is generated. We didn't extended this solution to XML export which remains with a combo and can only select a single display type.
@@ -0,0 +1,38 @@
<?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/>.
/**
* Grade export event.
*
* @package gradeexport_xls
* @copyright 2016 Zane Karl <zkarl@oid.ucla.edu>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace gradeexport_xls\event;
defined('MOODLE_INTERNAL') || die();
/**
* Grade export event class.
*
* @package gradeexport_xls
* @since Moodle 3.2
* @copyright 2016 Zane Karl <zkarl@oid.ucla.edu>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class grade_exported extends \core\event\grade_exported {
}
@@ -0,0 +1,46 @@
<?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 Subsystem implementation for gradeexport_xls.
*
* @package gradeexport_xls
* @copyright 2018 Sara Arjona <sara@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace gradeexport_xls\privacy;
defined('MOODLE_INTERNAL') || die();
/**
* Privacy Subsystem for gradeexport_xls implementing null_provider.
*
* @copyright 2018 Sara Arjona <sara@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:metadata';
}
}
+51
View File
@@ -0,0 +1,51 @@
<?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/>.
/**
* Capabilities gradeexport plugin.
*
* @package gradeexport_xls
* @copyright 2007 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$capabilities = array(
'gradeexport/xls:view' => array(
'riskbitmask' => RISK_PERSONAL,
'captype' => 'read',
'contextlevel' => CONTEXT_COURSE,
'archetypes' => array(
'teacher' => CAP_ALLOW,
'editingteacher' => CAP_ALLOW,
'manager' => CAP_ALLOW
)
),
'gradeexport/xls:publish' => array(
'riskbitmask' => RISK_PERSONAL,
'captype' => 'read',
'contextlevel' => CONTEXT_COURSE,
'archetypes' => array(
'manager' => CAP_ALLOW
)
)
);
+56
View File
@@ -0,0 +1,56 @@
<?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/>.
define('NO_MOODLE_COOKIES', true); // session not used here
require_once '../../../config.php';
require_once($CFG->dirroot.'/grade/export/xls/grade_export_xls.php');
$id = required_param('id', PARAM_INT);
$groupid = optional_param('groupid', 0, PARAM_INT);
$itemids = required_param('itemids', PARAM_RAW);
$exportfeedback = optional_param('export_feedback', 0, PARAM_BOOL);
$displaytype = optional_param('displaytype', $CFG->grade_export_displaytype, PARAM_RAW);
$decimalpoints = optional_param('decimalpoints', $CFG->grade_export_decimalpoints, PARAM_INT);
$onlyactive = optional_param('export_onlyactive', 0, PARAM_BOOL);
if (!$course = $DB->get_record('course', array('id'=>$id))) {
throw new \moodle_exception('invalidcourseid');
}
require_user_key_login('grade/export', $id); // we want different keys for each course
if (empty($CFG->gradepublishing)) {
throw new \moodle_exception('gradepubdisable');
}
$context = context_course::instance($id);
require_capability('moodle/grade:export', $context);
require_capability('gradeexport/xls:view', $context);
require_capability('gradeexport/xls:publish', $context);
if (!groups_group_visible($groupid, $COURSE)) {
throw new \moodle_exception('cannotaccessgroup', 'grades');
}
// Get all url parameters and create an object to simulate a form submission.
$formdata = grade_export::export_bulk_export_data($id, $itemids, $exportfeedback, $onlyactive, $displaytype,
$decimalpoints);
$export = new grade_export_xls($course, $groupid, $formdata);
$export->print_grades();
+65
View File
@@ -0,0 +1,65 @@
<?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/>.
require_once '../../../config.php';
require_once $CFG->dirroot.'/grade/export/lib.php';
require_once 'grade_export_xls.php';
$id = required_param('id', PARAM_INT); // course id
$PAGE->set_url('/grade/export/xls/export.php', array('id'=>$id));
if (!$course = $DB->get_record('course', array('id'=>$id))) {
throw new \moodle_exception('invalidcourseid');
}
require_login($course);
$context = context_course::instance($id);
$groupid = groups_get_course_group($course, true);
require_capability('moodle/grade:export', $context);
require_capability('gradeexport/xls:view', $context);
// We need to call this method here before any print otherwise the menu won't display.
// If you use this method without this check, will break the direct grade exporting (without publishing).
$key = optional_param('key', '', PARAM_RAW);
if (!empty($CFG->gradepublishing) && !empty($key)) {
$actionbar = new \core_grades\output\export_publish_action_bar($context, 'xls');
print_grade_page_head($COURSE->id, 'export', 'xls',
get_string('exportto', 'grades') . ' ' . get_string('pluginname', 'gradeexport_xls'),
false, false, true, null, null, null, $actionbar);
}
if (groups_get_course_groupmode($COURSE) == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context)) {
if (!groups_is_member($groupid, $USER->id)) {
throw new \moodle_exception('cannotaccessgroup', 'grades');
}
}
$mform = new grade_export_form(null, array('publishing' => true, 'simpleui' => true, 'multipledisplaytypes' => true));
$formdata = $mform->get_data();
$export = new grade_export_xls($course, $groupid, $formdata);
// If the gradepublishing is enabled and user key is selected print the grade publishing link.
if (!empty($CFG->gradepublishing) && !empty($key)) {
groups_print_course_menu($course, 'index.php?id='.$id);
echo $export->get_grade_publishing_url();
echo $OUTPUT->footer();
} else {
$event = \gradeexport_xls\event\grade_exported::create(array('context' => $context));
$event->trigger();
$export->print_grades();
}
+132
View File
@@ -0,0 +1,132 @@
<?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/>.
require_once($CFG->dirroot.'/grade/export/lib.php');
class grade_export_xls extends grade_export {
public $plugin = 'xls';
/**
* Constructor should set up all the private variables ready to be pulled
* @param object $course
* @param int $groupid id of selected group, 0 means all
* @param stdClass $formdata The validated data from the grade export form.
*/
public function __construct($course, $groupid, $formdata) {
parent::__construct($course, $groupid, $formdata);
// Overrides.
$this->usercustomfields = true;
}
/**
* To be implemented by child classes
*/
public function print_grades() {
global $CFG;
require_once($CFG->dirroot.'/lib/excellib.class.php');
$export_tracking = $this->track_exports();
$strgrades = get_string('grades');
// If this file was requested from a form, then mark download as complete (before sending headers).
\core_form\util::form_download_complete();
// Calculate file name
$shortname = format_string($this->course->shortname, true, array('context' => context_course::instance($this->course->id)));
$downloadfilename = clean_filename("$shortname $strgrades.xls");
// Creating a workbook
$workbook = new MoodleExcelWorkbook("-");
// Sending HTTP headers
$workbook->send($downloadfilename);
// Adding the worksheet
$myxls = $workbook->add_worksheet($strgrades);
// Print names of all the fields
$profilefields = grade_helper::get_user_profile_fields($this->course->id, $this->usercustomfields);
foreach ($profilefields as $id => $field) {
$myxls->write_string(0, $id, $field->fullname);
}
$pos = count($profilefields);
if (!$this->onlyactive) {
$myxls->write_string(0, $pos++, get_string("suspended"));
}
foreach ($this->columns as $grade_item) {
foreach ($this->displaytype as $gradedisplayname => $gradedisplayconst) {
$myxls->write_string(0, $pos++, $this->format_column_name($grade_item, false, $gradedisplayname));
}
// Add a column_feedback column
if ($this->export_feedback) {
$myxls->write_string(0, $pos++, $this->format_column_name($grade_item, true));
}
}
// Last downloaded column header.
$myxls->write_string(0, $pos++, get_string('timeexported', 'gradeexport_xls'));
// Print all the lines of data.
$i = 0;
$geub = new grade_export_update_buffer();
$gui = new graded_users_iterator($this->course, $this->columns, $this->groupid);
$gui->require_active_enrolment($this->onlyactive);
$gui->allow_user_custom_fields($this->usercustomfields);
$gui->init();
while ($userdata = $gui->next_user()) {
$i++;
$user = $userdata->user;
foreach ($profilefields as $id => $field) {
$fieldvalue = grade_helper::get_user_field_value($user, $field);
$myxls->write_string($i, $id, $fieldvalue);
}
$j = count($profilefields);
if (!$this->onlyactive) {
$issuspended = ($user->suspendedenrolment) ? get_string('yes') : '';
$myxls->write_string($i, $j++, $issuspended);
}
foreach ($userdata->grades as $itemid => $grade) {
if ($export_tracking) {
$status = $geub->track($grade);
}
foreach ($this->displaytype as $gradedisplayconst) {
$gradestr = $this->format_grade($grade, $gradedisplayconst);
if (is_numeric($gradestr)) {
$myxls->write_number($i, $j++, $gradestr);
} else {
$myxls->write_string($i, $j++, $gradestr);
}
}
// writing feedback if requested
if ($this->export_feedback) {
$myxls->write_string($i, $j++, $this->format_feedback($userdata->feedbacks[$itemid], $grade));
}
}
// Time exported.
$myxls->write_string($i, $j++, time());
}
$gui->close();
$geub->close();
/// Close the workbook
$workbook->close();
exit;
}
}
+69
View File
@@ -0,0 +1,69 @@
<?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/>.
require_once '../../../config.php';
require_once $CFG->dirroot.'/grade/export/lib.php';
require_once 'grade_export_xls.php';
$id = required_param('id', PARAM_INT); // course id
$PAGE->set_url('/grade/export/xls/index.php', array('id'=>$id));
if (!$course = $DB->get_record('course', array('id'=>$id))) {
throw new \moodle_exception('invalidcourseid');
}
require_login($course);
$context = context_course::instance($id);
require_capability('moodle/grade:export', $context);
require_capability('gradeexport/xls:view', $context);
$actionbar = new \core_grades\output\export_action_bar($context, null, 'xls');
print_grade_page_head($COURSE->id, 'export', 'xls',
get_string('exportto', 'grades') . ' ' . get_string('pluginname', 'gradeexport_xls'),
false, false, true, null, null, null, $actionbar);
export_verify_grades($COURSE->id);
if (!empty($CFG->gradepublishing)) {
$CFG->gradepublishing = has_capability('gradeexport/xls:publish', $context);
}
$actionurl = new moodle_url('/grade/export/xls/export.php');
$formoptions = array(
'publishing' => true,
'simpleui' => true,
'multipledisplaytypes' => true
);
$mform = new grade_export_form($actionurl, $formoptions);
$groupmode = groups_get_course_groupmode($course); // Groups are being used
$currentgroup = groups_get_course_group($course, true);
if ($groupmode == SEPARATEGROUPS and !$currentgroup and !has_capability('moodle/site:accessallgroups', $context)) {
echo $OUTPUT->heading(get_string("notingroup"));
echo $OUTPUT->footer();
die;
}
groups_print_course_menu($course, 'index.php?id='.$id);
echo '<div class="clearer"></div>';
$mform->display();
echo $OUTPUT->footer();
@@ -0,0 +1,31 @@
<?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 'gradeexport_xls', language 'en', branch 'MOODLE_20_STABLE'
*
* @package gradeexport_xls
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$string['eventgradeexported'] = 'XLS grade exported';
$string['pluginname'] = 'Excel spreadsheet';
$string['privacy:metadata'] = 'The Excel spreadsheet grade export plugin does not store any personal data.';
$string['timeexported'] = 'Last downloaded from this course';
$string['xls:publish'] = 'Publish XLS grade export';
$string['xls:view'] = 'Use Excel grade export';
@@ -0,0 +1,57 @@
<?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 gradeexport_xls\event;
/**
* XLS grade export events test cases.
*
* @package gradeexport_xls
* @copyright 2016 Zane Karl zkarl@oid.ucla.edu
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class events_test extends \advanced_testcase {
/**
* Setup is called before calling test case.
*/
public function setUp(): void {
$this->resetAfterTest();
}
/**
* Test course_module_instance_list_viewed event.
*/
public function test_logging(): void {
// There is no proper API to call to trigger this event, so what we are
// doing here is simply making sure that the events returns the right information.
$course = $this->getDataGenerator()->create_course();
$params = array(
'context' => \context_course::instance($course->id)
);
$event = \gradeexport_xls\event\grade_exported::create($params);
// Triggering and capturing the event.
$sink = $this->redirectEvents();
$event->trigger();
$events = $sink->get_events();
$this->assertCount(1, $events);
$event = reset($events);
// Checking that the event contains the expected values.
$this->assertInstanceOf('\gradeexport_xls\event\grade_exported', $event);
$this->assertEquals(\context_course::instance($course->id), $event->get_context());
$this->assertEquals('xls', $event->get_export_type());
}
}
+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/>.
/**
* Version details
*
* @package gradeexport
* @subpackage xls
* @copyright 1999 onwards Martin Dougiamas (http://dougiamas.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2024042200; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2024041600; // Requires this Moodle version.
$plugin->component = 'gradeexport_xls'; // Full name of the plugin (used for diagnostics)
@@ -0,0 +1,38 @@
<?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/>.
/**
* Grade export event.
*
* @package gradeexport_xml
* @copyright 2016 Zane Karl <zkarl@oid.ucla.edu>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace gradeexport_xml\event;
defined('MOODLE_INTERNAL') || die();
/**
* Grade export event class.
*
* @package gradeexport_xml
* @since Moodle 3.2
* @copyright 2016 Zane Karl <zkarl@oid.ucla.edu>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class grade_exported extends \core\event\grade_exported {
}
@@ -0,0 +1,46 @@
<?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 Subsystem implementation for gradeexport_xml.
*
* @package gradeexport_xml
* @copyright 2018 Sara Arjona <sara@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace gradeexport_xml\privacy;
defined('MOODLE_INTERNAL') || die();
/**
* Privacy Subsystem for gradeexport_xml implementing null_provider.
*
* @copyright 2018 Sara Arjona <sara@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:metadata';
}
}
+51
View File
@@ -0,0 +1,51 @@
<?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/>.
/**
* Capabilities gradeexport plugin.
*
* @package gradeexport_xml
* @copyright 2007 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$capabilities = array(
'gradeexport/xml:view' => array(
'riskbitmask' => RISK_PERSONAL,
'captype' => 'read',
'contextlevel' => CONTEXT_COURSE,
'archetypes' => array(
'teacher' => CAP_ALLOW,
'editingteacher' => CAP_ALLOW,
'manager' => CAP_ALLOW
)
),
'gradeexport/xml:publish' => array(
'riskbitmask' => RISK_PERSONAL,
'captype' => 'read',
'contextlevel' => CONTEXT_COURSE,
'archetypes' => array(
'manager' => CAP_ALLOW
)
)
);
+57
View File
@@ -0,0 +1,57 @@
<?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/>.
define('NO_MOODLE_COOKIES', true); // session not used here
require_once '../../../config.php';
require_once($CFG->dirroot.'/grade/export/xml/grade_export_xml.php');
$id = required_param('id', PARAM_INT);
$groupid = optional_param('groupid', 0, PARAM_INT);
$itemids = required_param('itemids', PARAM_RAW);
$exportfeedback = optional_param('export_feedback', 0, PARAM_BOOL);
$updatedgradesonly = optional_param('updatedgradesonly', false, PARAM_BOOL);
$displaytype = optional_param('displaytype', $CFG->grade_export_displaytype, PARAM_RAW);
$decimalpoints = optional_param('decimalpoints', $CFG->grade_export_decimalpoints, PARAM_INT);
$onlyactive = optional_param('export_onlyactive', 0, PARAM_BOOL);
if (!$course = $DB->get_record('course', array('id'=>$id))) {
throw new \moodle_exception('invalidcourseid');
}
require_user_key_login('grade/export', $id); // we want different keys for each course
if (empty($CFG->gradepublishing)) {
throw new \moodle_exception('gradepubdisable');
}
$context = context_course::instance($id);
require_capability('moodle/grade:export', $context);
require_capability('gradeexport/xml:publish', $context);
require_capability('gradeexport/xml:view', $context);
if (!groups_group_visible($groupid, $COURSE)) {
throw new \moodle_exception('cannotaccessgroup', 'grades');
}
// Get all url parameters and create an object to simulate a form submission.
$formdata = grade_export::export_bulk_export_data($id, $itemids, $exportfeedback, $onlyactive, $displaytype,
$decimalpoints, $updatedgradesonly, null);
$export = new grade_export_xml($course, $groupid, $formdata);
$export->print_grades();
+67
View File
@@ -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/>.
require_once '../../../config.php';
require_once $CFG->dirroot.'/grade/export/lib.php';
require_once 'grade_export_xml.php';
$id = required_param('id', PARAM_INT); // course id
$PAGE->set_url('/grade/export/xml/export.php', array('id'=>$id));
if (!$course = $DB->get_record('course', array('id'=>$id))) {
throw new \moodle_exception('invalidcourseid');
}
require_login($course);
$context = context_course::instance($id);
$groupid = groups_get_course_group($course, true);
require_capability('moodle/grade:export', $context);
require_capability('gradeexport/xml:view', $context);
// We need to call this method here before any print otherwise the menu won't display.
// If you use this method without this check, will break the direct grade exporting (without publishing).
$key = optional_param('key', '', PARAM_RAW);
if (!empty($CFG->gradepublishing) && !empty($key)) {
$actionbar = new \core_grades\output\export_publish_action_bar($context, 'xml');
print_grade_page_head($COURSE->id, 'export', 'xml',
get_string('exportto', 'grades') . ' ' . get_string('pluginname', 'gradeexport_xml'),
false, false, true, null, null, null, $actionbar);
}
if (groups_get_course_groupmode($COURSE) == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context)) {
if (!groups_is_member($groupid, $USER->id)) {
throw new \moodle_exception('cannotaccessgroup', 'grades');
}
}
$mform = new grade_export_form(null, array('publishing' => true, 'simpleui' => true, 'multipledisplaytypes' => false,
'idnumberrequired' => true, 'updategradesonly' => true));
$formdata = $mform->get_data();
$export = new grade_export_xml($course, $groupid, $formdata);
// If the gradepublishing is enabled and user key is selected print the grade publishing link.
if (!empty($CFG->gradepublishing) && !empty($key)) {
groups_print_course_menu($course, 'index.php?id='.$id);
echo $export->get_grade_publishing_url();
echo $OUTPUT->footer();
} else {
$event = \gradeexport_xml\event\grade_exported::create(array('context' => $context));
$event->trigger();
$export->print_grades();
}
+151
View File
@@ -0,0 +1,151 @@
<?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/>.
require_once($CFG->dirroot.'/grade/export/lib.php');
require_once($CFG->libdir.'/filelib.php');
class grade_export_xml extends grade_export {
public $plugin = 'xml';
public $updatedgradesonly = false; // default to export ALL grades
/**
* Ensure we produce correctly formed XML content by encoding idnumbers appropriately
*
* @param string $idnumber
* @return string
*/
private static function xml_export_idnumber(string $idnumber): string {
return htmlspecialchars($idnumber, ENT_QUOTES | ENT_XML1);
}
/**
* Handle form processing for export. Note we need to handle the case where there are no 'itemids[]' being included in the
* form, because each is disabled for selection due to having empty idnumber
*
* @param stdClass $formdata
*/
public function process_form($formdata) {
if (!isset($formdata->itemids)) {
$formdata->itemids = self::EXPORT_SELECT_NONE;
}
parent::process_form($formdata);
}
/**
* To be implemented by child classes
* @param boolean $feedback
* @param boolean $publish Whether to output directly, or send as a file
* @return string
*/
public function print_grades($feedback = false) {
global $CFG;
require_once($CFG->libdir.'/filelib.php');
$export_tracking = $this->track_exports();
$strgrades = get_string('grades');
/// Calculate file name
$shortname = format_string($this->course->shortname, true, array('context' => context_course::instance($this->course->id)));
$downloadfilename = clean_filename("$shortname $strgrades.xml");
make_temp_directory('gradeexport');
$tempfilename = $CFG->tempdir .'/gradeexport/'. md5(sesskey().microtime().$downloadfilename);
if (!$handle = fopen($tempfilename, 'w+b')) {
throw new \moodle_exception('cannotcreatetempdir');
}
/// time stamp to ensure uniqueness of batch export
fwrite($handle, '<results batch="xml_export_'.time().'">'."\n");
$export_buffer = array();
$geub = new grade_export_update_buffer();
$gui = new graded_users_iterator($this->course, $this->columns, $this->groupid);
$gui->require_active_enrolment($this->onlyactive);
$gui->init();
while ($userdata = $gui->next_user()) {
$user = $userdata->user;
if (empty($user->idnumber)) {
//id number must exist otherwise we cant match up students when importing
continue;
}
// studentgrades[] index should match with corresponding $index
foreach ($userdata->grades as $itemid => $grade) {
$grade_item = $this->grade_items[$itemid];
$grade->grade_item =& $grade_item;
// MDL-11669, skip exported grades or bad grades (if setting says so)
if ($export_tracking) {
$status = $geub->track($grade);
if ($this->updatedgradesonly && ($status == 'nochange' || $status == 'unknown')) {
continue;
}
}
fwrite($handle, "\t<result>\n");
if ($export_tracking) {
fwrite($handle, "\t\t<state>$status</state>\n");
}
// only need id number
$gradeitemidnumber = self::xml_export_idnumber($grade_item->idnumber);
fwrite($handle, "\t\t<assignment>{$gradeitemidnumber}</assignment>\n");
// this column should be customizable to use either student id, idnumber, uesrname or email.
$useridnumber = self::xml_export_idnumber($user->idnumber);
fwrite($handle, "\t\t<student>{$useridnumber}</student>\n");
// Format and display the grade in the selected display type (real, letter, percentage).
if (is_array($this->displaytype)) {
// Grades display type came from the return of export_bulk_export_data() on grade publishing.
foreach ($this->displaytype as $gradedisplayconst) {
$gradestr = $this->format_grade($grade, $gradedisplayconst);
fwrite($handle, "\t\t<score>$gradestr</score>\n");
}
} else {
// Grade display type submitted directly from the grade export form.
$gradestr = $this->format_grade($grade, $this->displaytype);
fwrite($handle, "\t\t<score>$gradestr</score>\n");
}
if ($this->export_feedback) {
$feedbackstr = $this->format_feedback($userdata->feedbacks[$itemid], $grade);
fwrite($handle, "\t\t<feedback>$feedbackstr</feedback>\n");
}
fwrite($handle, "\t</result>\n");
}
}
fwrite($handle, "</results>");
fclose($handle);
$gui->close();
$geub->close();
if (defined('BEHAT_SITE_RUNNING')) {
// If behat is running, we cannot test the output if we force a file download.
include($tempfilename);
} else {
@header("Content-type: text/xml; charset=UTF-8");
send_temp_file($tempfilename, $downloadfilename, false);
}
}
}
+74
View File
@@ -0,0 +1,74 @@
<?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/>.
require_once '../../../config.php';
require_once $CFG->dirroot.'/grade/export/lib.php';
require_once 'grade_export_xml.php';
$id = required_param('id', PARAM_INT); // course id
$PAGE->set_url('/grade/export/xml/index.php', array('id'=>$id));
if (!$course = $DB->get_record('course', array('id'=>$id))) {
throw new \moodle_exception('invalidcourseid');
}
require_login($course);
$context = context_course::instance($id);
require_capability('moodle/grade:export', $context);
require_capability('gradeexport/xml:view', $context);
$actionbar = new \core_grades\output\export_action_bar($context, null, 'xml');
print_grade_page_head($COURSE->id, 'export', 'xml',
get_string('exportto', 'grades') . ' ' . get_string('pluginname', 'gradeexport_xml'),
false, false, true, null, null, null, $actionbar);
export_verify_grades($COURSE->id);
if (!empty($CFG->gradepublishing)) {
$CFG->gradepublishing = has_capability('gradeexport/xml:publish', $context);
}
$actionurl = new moodle_url('/grade/export/xml/export.php');
// The option 'idnumberrequired' excludes grade items that dont have an ID to use during import.
$formoptions = array(
'idnumberrequired' => true,
'updategradesonly' => true,
'publishing' => true,
'simpleui' => true,
'multipledisplaytypes' => false
);
$mform = new grade_export_form($actionurl, $formoptions);
$groupmode = groups_get_course_groupmode($course); // Groups are being used.
$currentgroup = groups_get_course_group($course, true);
if (($groupmode == SEPARATEGROUPS) &&
(!$currentgroup) &&
(!has_capability('moodle/site:accessallgroups', $context))) {
echo $OUTPUT->heading(get_string("notingroup"));
echo $OUTPUT->footer();
die;
}
groups_print_course_menu($course, 'index.php?id='.$id);
echo '<div class="clearer"></div>';
$mform->display();
echo $OUTPUT->footer();
@@ -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/>.
/**
* Strings for component 'gradeexport_xml', language 'en', branch 'MOODLE_20_STABLE'
*
* @package gradeexport_xml
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$string['eventgradeexported'] = 'XML grade exported';
$string['pluginname'] = 'XML file';
$string['privacy:metadata'] = 'The XML file grade export plugin does not store any personal data.';
$string['xml:publish'] = 'Publish XML grade export';
$string['xml:view'] = 'Use XML grade export';
@@ -0,0 +1,44 @@
@gradeexport @gradeexport_xml
Feature: I need to export grades as xml
In order to easily review marks
As a teacher
I need to have a export grades as xml
Background:
Given the following "courses" exist:
| fullname | shortname | category | groupmode |
| Course 1 | C1 | 0 | 1 |
And the following "users" exist:
| username | firstname | lastname | email | idnumber |
| teacher1 | Teacher | 1 | teacher1@example.com | t1 |
| student1 | Student | 1 | student1@example.com | s1 |
| student2 | Student | 2 | student2@example.com | 'Bill'&"Ben"<tag>Hello</tag> |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| student1 | C1 | student |
| student2 | C1 | student |
And the following "activities" exist:
| activity | course | idnumber | name |
| assign | C1 | a1 | Test assignment name |
And the following "grade grades" exist:
| gradeitem | user | grade |
| Test assignment name | student1 | 80.00 |
| Test assignment name | student2 | 42.00 |
And I am on the "Course 1" course page logged in as teacher1
@javascript
Scenario: Export grades as XML
When I navigate to "XML file" export page in the course gradebook
And I expand all fieldsets
And I set the field "Grade export decimal places" to "1"
And I press "Download"
Then I should see "s1" in the "//results//result[1]//student" "xpath_element"
And I should see "a1" in the "//results//result[1]//assignment" "xpath_element"
And I should see "80.0" in the "//results//result[1]//score" "xpath_element"
And I should not see "80.00" in the "//results//result[1]//score" "xpath_element"
# Ensure we have the encoded ID number of student 2.
And I should see "'Bill'&\"Ben\"<tag>Hello</tag>" in the "//results//result[2]//student" "xpath_element"
And I should see "a1" in the "//results//result[2]//assignment" "xpath_element"
And I should see "42.0" in the "//results//result[2]//score" "xpath_element"
And I should not see "42.00" in the "//results//result[2]//score" "xpath_element"
@@ -0,0 +1,57 @@
<?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 gradeexport_xml\event;
/**
* XML grade export events test cases.
*
* @package gradeexport_xml
* @copyright 2016 Zane Karl zkarl@oid.ucla.edu
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class events_test extends \advanced_testcase {
/**
* Setup is called before calling test case.
*/
public function setUp(): void {
$this->resetAfterTest();
}
/**
* Test course_module_instance_list_viewed event.
*/
public function test_logging(): void {
// There is no proper API to call to trigger this event, so what we are
// doing here is simply making sure that the events returns the right information.
$course = $this->getDataGenerator()->create_course();
$params = array(
'context' => \context_course::instance($course->id)
);
$event = \gradeexport_xml\event\grade_exported::create($params);
// Triggering and capturing the event.
$sink = $this->redirectEvents();
$event->trigger();
$events = $sink->get_events();
$this->assertCount(1, $events);
$event = reset($events);
// Checking that the event contains the expected values.
$this->assertInstanceOf('\gradeexport_xml\event\grade_exported', $event);
$this->assertEquals(\context_course::instance($course->id), $event->get_context());
$this->assertEquals('xml', $event->get_export_type());
}
}
+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/>.
/**
* Version details
*
* @package gradeexport
* @subpackage xml
* @copyright 1999 onwards Martin Dougiamas (http://dougiamas.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2024042200; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2024041600; // Requires this Moodle version.
$plugin->component = 'gradeexport_xml'; // Full name of the plugin (used for diagnostics)