MDL-7028 rewritten course reset + forum role_unassign cleanup fixes; merged from MOODLE_19_STABLE

This commit is contained in:
skodak 2007-11-29 14:43:04 +00:00
parent 80f29a5947
commit 0b5a80a1a5
39 changed files with 1726 additions and 447 deletions

View File

@ -7,101 +7,78 @@ of general course data like students, teachers, logs, events and groups as well
specific data. Each module must be modified to take advantage of this new feature.
The feature will also reset the start date of the course if necessary.
*/
require('../config.php');
$id = required_param('id', PARAM_INT);
require('../config.php');
require_once('reset_form.php');
if (! $course = get_record('course', 'id', $id)) {
error("Course is misconfigured");
}
$id = required_param('id', PARAM_INT);
require_login($course->id);
if (!$course = get_record('course', 'id', $id)) {
error("Course is misconfigured");
}
require_capability('moodle/course:update', get_context_instance(CONTEXT_COURSE, $course->id));
require_login($course);
require_capability('moodle/course:update', get_context_instance(CONTEXT_COURSE, $course->id));
$strreset = get_string('reset');
$strresetcourse = get_string('resetcourse');
$strremove = get_string('remove');
$strreset = get_string('reset');
$strresetcourse = get_string('resetcourse');
$strremove = get_string('remove');
$navlinks = array();
$navlinks[] = array('name' => $strresetcourse, 'link' => null, 'type' => 'misc');
$navigation = build_navigation($navlinks);
$navlinks = array(array('name' => $strresetcourse, 'link' => null, 'type' => 'misc'));
$navigation = build_navigation($navlinks);
print_header($course->fullname.': '.$strresetcourse, $course->fullname.': '.$strresetcourse, $navigation);
$mform = new course_reset_form();
print_simple_box_start();
if ($mform->is_cancelled()) {
redirect($CFG->wwwroot.'/course/view.php?id='.$id);
print_heading($strresetcourse);
} else if ($data = $mform->get_data(false)) { // no magic quotes
/// If we have data, then process it.
if ($data = data_submitted() and confirm_sesskey()) {
if (isset($data->selectdefault)) {
$_POST = array();
$mform = new course_reset_form();
$mform->load_defaults();
$data->courseid = $course->id;
} else if (isset($data->deselectall)) {
$_POST = array();
$mform = new course_reset_form();
reset_course_userdata($data, true);
} else {
print_header($course->fullname.': '.$strresetcourse, $course->fullname.': '.$strresetcourse, $navigation);
print_heading($strresetcourse);
if (!empty($data->reset_start_date)) {
if (set_field('course', 'startdate',
make_timestamp($data->startyear, $data->startmonth, $data->startday),
'id', $course->id)) {
notify(get_string('datechanged'), 'notifysuccess');
}
$data->reset_start_date_old = $course->startdate;
$status = reset_course_userdata($data);
$data = array();;
foreach ($status as $item) {
$line = array();
$line[] = $item['component'];
$line[] = $item['item'];
$line[] = ($item['error']===false) ? get_string('ok') : '<div class="notifyproblem">'.$item['error'].'</div>';
$data[] = $line;
}
$table = new object();
$table->head = array(get_string('resetcomponent'), get_string('resettask'), get_string('resetstatus'));
$table->size = array('20%', '40%', '40%');
$table->align = array('left', 'left', 'left');
$table->width = '80%';
$table->data = $data;
print_table($table);
print_continue('view.php?id='.$course->id); // Back to course page
print_simple_box_end();
print_footer($course);
exit;
}
}
print_header($course->fullname.': '.$strresetcourse, $course->fullname.': '.$strresetcourse, $navigation);
print_heading($strresetcourse);
print_simple_box(get_string('resetinfo'), 'center', '60%');
/// Print forms so the user can make choices about what to delete
print_simple_box(get_string('resetinfo'), 'center', '60%');
echo '<form id="reset" action="reset.php" method="POST">';
print_heading(get_string('course'), 'left', 3);
echo '<div class="courseinfo">';
echo $strremove.':<br />';
print_checkbox('reset_teachers', 1, false, get_string('teachers'), '', ''); echo '<br />';
print_checkbox('reset_students', 1, true, get_string('students'), '', ''); echo '<br />';
print_checkbox('reset_events', 1, true, get_string('courseevents', 'calendar'), '', ''); echo '<br />';
print_checkbox('reset_logs', 1, true, get_string('logs'), '', ''); echo '<br />';
print_checkbox('reset_groups', 1, true, get_string('groups'), '', ''); echo '<br />';
print_checkbox('reset_start_date', 1, true, get_string('startdate'), '', '');
print_date_selector('startday', 'startmonth', 'startyear');
helpbutton('coursestartdate', get_string('startdate'));
echo '</div>';
// Check each module and see if there is specific data to be removed
if ($allmods = get_records('modules') ) {
foreach ($allmods as $mod) {
$modname = $mod->name;
$modfile = $CFG->dirroot .'/mod/'. $modname .'/lib.php';
$mod_reset_course_form = $modname .'_reset_course_form';
if (file_exists($modfile)) {
@include_once($modfile);
if (function_exists($mod_reset_course_form)) {
print_heading(get_string('modulenameplural', $modname), 'left', 3);
echo '<div class="'.$modname.'info">';
$mod_reset_course_form($course);
echo '</div>';
}
}
}
} else {
error('No modules are installed!');
}
echo '<input name="id" value="'.$course->id.'" type="hidden" />';
echo '<input name="sesskey" value="'.sesskey().'" type="hidden" />';
echo '<p align="center"><input name="submit" value="'.$strresetcourse.'" type="submit" /></p>';
echo '</form>';
print_simple_box_end();
print_footer($course);
$mform->display();
print_footer($course);
?>

124
course/reset_form.php Normal file
View File

@ -0,0 +1,124 @@
<?php // $Id$
require_once $CFG->libdir.'/formslib.php';
class course_reset_form extends moodleform {
function definition (){
global $CFG, $COURSE;
$mform =& $this->_form;
$mform->addElement('header', 'generalheader', get_string('general'));
$mform->addElement('date_selector', 'reset_start_date', get_string('startdate'), array('optional'=>true));
$mform->setHelpButton('reset_start_date', array('coursestartdate', get_string('startdate')));
$mform->addElement('checkbox', 'reset_events', get_string('deleteevents', 'calendar'));
$mform->addElement('checkbox', 'reset_logs', get_string('deletelogs'));
$mform->addElement('checkbox', 'reset_notes', get_string('deletenotes', 'notes'));
$mform->addElement('header', 'rolesheader', get_string('roles'));
$roles = get_assignable_roles(get_context_instance(CONTEXT_COURSE, $COURSE->id));
$mform->addElement('select', 'reset_roles', get_string('unenrolroleusers'), $roles, array('multiple' => 'multiple'));
$mform->addElement('checkbox', 'reset_roles_overrides', get_string('deletecourseoverrides', 'role'));
$mform->setAdvanced('reset_roles_overrides');
$mform->addElement('checkbox', 'reset_roles_local', get_string('deletelocalroles', 'role'));
$mform->addElement('header', 'gradebookheader', get_string('gradebook', 'grades'));
$mform->addElement('checkbox', 'reset_gradebook_items', get_string('removeallcourseitems', 'grades'));
$mform->addElement('checkbox', 'reset_gradebook_grades', get_string('removeallcoursegrades', 'grades'));
$mform->disabledIf('reset_gradebook_grades', 'reset_gradebook_items', 'checked');
$mform->addElement('header', 'groupheader', get_string('groups'));
$mform->addElement('checkbox', 'reset_groups_remove', get_string('deleteallgroups', 'group'));
$mform->setAdvanced('reset_groups_remove');
$mform->addElement('checkbox', 'reset_groups_members', get_string('removegroupsmembers', 'group'));
$mform->setAdvanced('reset_groups_members');
$mform->disabledIf('reset_groups_members', 'reset_groups_remove', 'checked');
if (!empty($CFG->enablegroupings)) {
$mform->addElement('checkbox', 'reset_groupings_remove', get_string('deleteallgroupings', 'group'));
$mform->setAdvanced('reset_groupings_remove');
$mform->addElement('checkbox', 'reset_groupings_members', get_string('removegroupingsmembers', 'group'));
$mform->setAdvanced('reset_groupings_members');
$mform->disabledIf('reset_groupings_members', 'reset_groupings_remove', 'checked');
}
$unsupported_mods = array();
if ($allmods = get_records('modules') ) {
foreach ($allmods as $mod) {
$modname = $mod->name;
if (!count_records($modname, 'course', $COURSE->id)) {
continue; // skip mods with no instances
}
$modfile = $CFG->dirroot."/mod/$modname/lib.php";
$mod_reset_course_form_definition = $modname.'_reset_course_form_definition';
$mod_reset__userdata = $modname.'_reset_userdata';
if (file_exists($modfile)) {
include_once($modfile);
if (function_exists($mod_reset_course_form_definition)) {
$mod_reset_course_form_definition($mform);
} else if (!function_exists($mod_reset__userdata)) {
$unsupported_mods[] = $mod;
}
} else {
debugging('Missing lib.php in '.$modname.' module');
}
}
}
// mention unsupported mods
if (!empty($unsupported_mods)) {
$mform->addElement('header', 'unsupportedheader', get_string('resetnotimplemented'));
foreach($unsupported_mods as $mod) {
$mform->addElement('static', 'unsup'.$mod->name, get_string('modulenameplural', $mod->name));
$mform->setAdvanced('unsup'.$mod->name);
}
}
$mform->addElement('hidden', 'id', $COURSE->id);
$buttonarray = array();
$buttonarray[] = &$mform->createElement('submit', 'submitbutton', get_string('resetcourse'));
$buttonarray[] = &$mform->createElement('submit', 'selectdefault', get_string('selectdefault'));
$buttonarray[] = &$mform->createElement('submit', 'deselectall', get_string('deselectall'));
$buttonarray[] = &$mform->createElement('cancel');
$mform->addGroup($buttonarray, 'buttonar', '', array(' '), false);
$mform->closeHeaderBefore('buttonar');
}
function load_defaults() {
global $CFG, $COURSE;
$mform =& $this->_form;
$defaults = array ('reset_events'=>1, 'reset_logs'=>1, 'reset_roles_local'=>1, 'reset_gradebook_grades'=>1, 'reset_notes'=>1);
if (!empty($COURSE->defaultrole)) {
$defaults['reset_roles'] = array($COURSE->defaultrole);
} else {
$defaults['reset_roles'] = array($CFG->defaultcourseroleid);
}
if ($allmods = get_records('modules') ) {
foreach ($allmods as $mod) {
$modname = $mod->name;
$modfile = $CFG->dirroot."/mod/$modname/lib.php";
$mod_reset_course_form_defaults = $modname.'_reset_course_form_defaults';
if (file_exists($modfile)) {
@include_once($modfile);
if (function_exists($mod_reset_course_form_defaults)) {
$defaults = $defaults + $mod_reset_course_form_defaults($COURSE);
}
}
}
}
foreach ($defaults as $element=>$default) {
$mform->setDefault($element, $default);
}
}
}

View File

@ -67,7 +67,7 @@ if ($groupings = get_records('groupings', 'courseid', $course->id)) {
$data[] = $line;
}
}
$tabke = new object();
$table = new object();
$table->head = array($strgrouping, $strgroups, $struses, $stredit);
$table->size = array('30%', '50%', '10%', '10%');
$table->align = array('left', 'left', 'center', 'center');

View File

@ -163,6 +163,8 @@ function groups_delete_group($groupid) {
return false;
}
// delete group calendar events
delete_records('event', 'groupid', $groupid);
//first delete usage in groupings_groups
delete_records('groupings_groups', 'groupid', $groupid);
//delete members
@ -195,7 +197,7 @@ function groups_delete_grouping($groupingid) {
}
/**
* Remove all users from group
* Remove all users from all groups in course
* @param int $courseid
* @param bool $showfeedback
* @return bool success
@ -203,10 +205,9 @@ function groups_delete_grouping($groupingid) {
function groups_delete_group_members($courseid, $showfeedback=false) {
global $CFG;
$sql = "DELETE FROM {$CFG->prefix}groups_members
WHERE groupid in (SELECT id FROM {$CFG->prefix}groups g WHERE g.courseid = $courseid)";
$groupssql = "SELECT id FROM {$CFG->prefix}groups g WHERE g.courseid = $courseid";
delete_records_select('groups_members', "groupid IN ($groupssql)");
execute_sql($sql, false);
if ($showfeedback) {
notify(get_string('deleted').' groups_members');
}
@ -214,6 +215,25 @@ function groups_delete_group_members($courseid, $showfeedback=false) {
return true;
}
/**
* Remove all groups from all groupings in course
* @param int $courseid
* @param bool $showfeedback
* @return bool success
*/
function groups_delete_groupings_groups($courseid, $showfeedback=false) {
global $CFG;
$groupssql = "SELECT id FROM {$CFG->prefix}groups g WHERE g.courseid = $courseid";
delete_records_select('groupings_groups', "groupid IN ($groupssql)");
if ($showfeedback) {
notify(get_string('deleted').' groupings_groups');
}
return true;
}
/**
* Delete all groups from course
* @param int $courseid
@ -224,12 +244,11 @@ function groups_delete_groups($courseid, $showfeedback=false) {
global $CFG;
require_once($CFG->libdir.'/gdlib.php');
// delete any uses of groups
$sql = "DELETE FROM {$CFG->prefix}groupings_groups
WHERE groupid in (SELECT id FROM {$CFG->prefix}groups g WHERE g.courseid = $courseid)";
execute_sql($sql, false);
$groupssql = "SELECT id FROM {$CFG->prefix}groups g WHERE g.courseid = $courseid";
groups_delete_group_members($courseid, false);
// delete any uses of groups
groups_delete_groupings_groups($courseid, $showfeedback);
groups_delete_group_members($courseid, $showfeedback);
// delete group pictures
if ($groups = get_records('groups', 'courseid', $courseid)) {
@ -238,6 +257,9 @@ function groups_delete_groups($courseid, $showfeedback=false) {
}
}
// delete group calendar events
delete_records_select('event', "groupid IN ($groupssql)");
delete_records('groups', 'courseid', $courseid);
if ($showfeedback) {
notify(get_string('deleted').' groups');

View File

@ -27,6 +27,7 @@ $string['commentinline'] = 'Comment inline';
$string['configitemstocount'] = 'Nature of items to be counted for student submissions in online assignments.';
$string['configmaxbytes'] = 'Default maximum assignment size for all assignments on the site (subject to course limits and other local settings)';
$string['confirmdeletefile'] = 'Are you absolutely sure you want to delete this file?<br /><strong>$a</strong>';
$string['deleteallsubmissions'] = 'Delete all submissions';
$string['deletefilefailed'] = 'Deleting of file failed.';
$string['description'] = 'Description';
$string['draft'] = 'Draft';

View File

@ -17,6 +17,7 @@ $string['dayview'] = 'Day View';
$string['daywithnoevents'] = 'There are no events this day.';
$string['default'] = 'Default';
$string['deleteevent'] = 'Delete event';
$string['deleteevents'] = 'Delete events';
$string['detailedmonthview'] = 'Detailed Month View';
$string['durationminutes'] = 'Duration in minutes';
$string['durationnone'] = 'Without duration';

View File

@ -48,6 +48,7 @@ $string['nomessages'] = 'No messages yet';
$string['normalkeepalive'] = 'KeepAlive';
$string['normalstream'] = 'Stream';
$string['noscheduledsession'] = 'No scheduled session';
$string['removemessages'] = 'Remove all messages';
$string['repeatdaily'] = 'At the same time every day';
$string['repeatnone'] = 'No repeats - publish the specified time only';
$string['repeattimes'] = 'Repeat sessions';

View File

@ -38,6 +38,7 @@ $string['publishalways'] = 'Always show results to students';
$string['publishanonymous'] = 'Publish anonymous results, do not show student names';
$string['publishnames'] = 'Publish full results, showing names and their choices';
$string['publishnot'] = 'Do not publish results to students';
$string['removeresponses'] = 'Remove all responses';
$string['responses'] = 'Responses';
$string['responsesto'] = 'Responses to $a';
$string['savemychoice'] = 'Save my choice';

View File

@ -58,7 +58,9 @@ $string['defaultfielddelimiter'] = '(default is the comma character)';
$string['defaultfieldenclosure'] = '(default is none)';
$string['defaultsortfield'] = 'Default sort field';
$string['delete'] = 'Delete';
$string['deleteallentries'] = 'Delete all entries';
$string['deletecomment'] = 'Are you sure you want to delete this comment?';
$string['deletenotenrolled'] = 'Delete entries by users not enrolled';
$string['deleted'] = 'deleted';
$string['deletefield'] = 'Delete an existing field';
$string['deletewarning'] = 'Are you sure you want to delete this preset?';

View File

@ -206,8 +206,10 @@ $string['repliesmany'] = '$a replies so far';
$string['repliesone'] = '$a reply so far';
$string['reply'] = 'Reply';
$string['replyforum'] = 'Reply to forum';
$string['resetforums'] = 'Remove all posts from these types of forums';
$string['resetsubscriptions'] = 'Remove forum subscriptions';
$string['resetforumsall'] = 'Delete all posts';
$string['resetforums'] = 'Delete posts from';
$string['resetsubscriptions'] = 'Delete all forum subscriptions';
$string['resettrackprefs'] = 'Delete all forum tracking preferences';
$string['rsssubscriberssdiscussions'] = 'Display the RSS feed for \'$a\' discussions';
$string['rsssubscriberssposts'] = 'Display the RSS feed for \'$a\' posts';
$string['search'] = 'Search';

View File

@ -52,7 +52,7 @@ $string['commentson'] = 'Comments on';
$string['commentupdated'] = 'The comment has been updated.';
$string['concept'] = 'Concept';
$string['concepts'] = 'Concepts';
$string['configenablerssfeeds'] = 'This switch will enable the possibility of RSS feeds for all glosaries. You will still need to turn feeds on manually in the settings for each glossary.';
$string['configenablerssfeeds'] = 'This switch will enable the possibility of RSS feeds for all glossaries. You will still need to turn feeds on manually in the settings for each glossary.';
$string['currentglossary'] = 'Current glossary';
$string['changeto'] = 'change to $a';
$string['current']= 'Currently sorted $a';
@ -69,6 +69,7 @@ $string['defaultsortorder'] = 'Default sort order';
$string['definition'] = 'Definition';
$string['definitions'] = 'Definitions';
$string['deleteentry'] = 'Delete entry';
$string['deletenotenrolled'] = 'Delete entries by users not enrolled';
$string['deletingcomment'] = 'Deleting comment';
$string['deletingnoneemptycategory'] = 'Deleting this category will not delete the entries it contains - they will be marked as uncategorised.';
$string['descending'] = 'descending';
@ -172,6 +173,8 @@ $string['ratingsuse'] = 'Use ratings';
$string['ratingtime'] = 'Restrict ratings to entries with dates in this range:';
$string['rejectedentries'] = 'Rejected entries';
$string['rejectionrpt'] = 'Rejection Report';
$string['resetglossariesall'] = 'Delete entries from all glossaries';
$string['resetglossaries'] = 'Delete entries from';
$string['rsssubscriberss'] = 'Display the RSS feed for \'$a\' concepts';
$string['searchindefinition'] = 'Search full text';
$string['secondaryglossary'] = 'Secondary glossary';

View File

@ -375,6 +375,8 @@ $string['rangesdisplaytype'] = 'Range display type';
$string['rank'] = 'Rank';
$string['rawpct'] = 'Raw %%';
$string['real'] = 'Real';
$string['removeallcoursegrades'] = 'Delete all grades';
$string['removeallcourseitems'] = 'Delete all items and categories';
$string['hideforcedsettings'] = 'Hide forced settings';
$string['report'] = 'Report';
$string['reportdefault'] = 'Report default ($a)';

View File

@ -128,4 +128,9 @@ $string['nousersinrole'] = 'There are no suitable users in the selected role';
$string['nogroupsassigned'] = 'No groups assigned';
$string['evenallocation'] = 'Note: To keep group allocation even, the actual number of members per group differs from the number you specified.';
$string['removegroupsmembers'] = 'Remove all group members';
$string['removegroupingsmembers'] = 'Remove all groups from groupings';
$string['deleteallgroups'] = 'Delete all groups';
$string['deleteallgroupings'] = 'Delete all groupings';
?>

View File

@ -223,6 +223,7 @@ $string['previewlesson'] = 'Preview $a';
$string['previouspage'] = 'Previous page';
$string['progressbar'] = 'Progress Bar';
$string['progressbarteacherwarning'] = 'Progress Bar does not display for $a';
$string['deleteallattempts'] = 'Delete all lesson attempts';
$string['qtype'] = 'Page type';
$string['question'] = 'Question';
$string['questionoption'] = 'Question';

View File

@ -360,6 +360,8 @@ $string['defaultcourseteacherdescription'] = 'Teachers can do anything within a
$string['defaultcourseteachers'] = 'Teachers';
$string['delete'] = 'Delete';
$string['deleteall'] = 'Delete all';
$string['deleteallcomments'] = 'Delete all comments';
$string['deleteallratings'] = 'Delete all ratings';
$string['deletecategorycheck'] = 'Are you absolutely sure you want to completely delete this category <b>\'$a\'</b>?<br />This will move all courses into the parent category if there is one, or into Miscellaneous.';
$string['deletecheck'] = 'Delete $a ?';
$string['deletecheckfiles'] = 'Are you absolutely sure you want to delete these files?';
@ -372,6 +374,7 @@ $string['deleted'] = 'Deleted';
$string['deletedactivity'] = 'Deleted $a';
$string['deletedcourse'] = '$a has been completely deleted';
$string['deletednot'] = 'Could not delete $a !';
$string['deletelogs'] = 'Delete logs';
$string['deleteselected'] = 'Delete selected';
$string['deletingcourse'] = 'Deleting $a';
$string['deletingexistingcoursedata'] = 'Deleting existing course data';
@ -1224,6 +1227,10 @@ $string['required'] = 'Required';
$string['requireskey'] = 'This course requires an enrolment key';
$string['requirespayment'] = 'This course requires payment for access';
$string['reset'] = 'Reset';
$string['resetcomponent'] = 'Component';
$string['resettask'] = 'Task';
$string['resetnotimplemented'] = 'Reset not implemented';
$string['resetstatus'] = 'Status';
$string['resetcourse'] = 'Reset course';
$string['resetinfo'] = 'This page allows you to empty a course of user data, while retaining the activities and other settings. Please be warned that by choosing items below and submitting this page you will delete your chosen user data from this course forever!';
$string['resetstartdate'] = 'Reset start date';
@ -1288,6 +1295,7 @@ $string['seealsostats'] = 'See also: stats';
$string['select'] = 'Select';
$string['selectacountry'] = 'Select a country';
$string['selectall'] = 'Select all';
$string['selectdefault'] = 'Select default';
$string['selectamodule'] = 'Please select an activity module';
$string['selectednowmove'] = '$a files selected for moving. Now go to the destination and press \'Move files to here\'';
$string['selectnos'] = 'Select all \'no\'';
@ -1467,6 +1475,7 @@ $string['turneditingoff'] = 'Turn editing off';
$string['turneditingon'] = 'Turn editing on';
$string['undecided'] = 'Undecided';
$string['unenrol'] = 'Unenrol';
$string['unenrolroleusers'] = 'Unenrol users';
$string['unenrolallstudents'] = 'Unenrol all students';
$string['unenrolallstudentssure'] = 'Are you sure you want to completely unenrol all students from this course?';
$string['unenrolme'] = 'Unenrol me from $a';

View File

@ -1,25 +1,26 @@
<?PHP // $Id$
// note.php
$string['note'] = 'Note';
$string['notes'] = 'Notes';
$string['sitenotes'] = 'Site notes';
$string['coursenotes'] = 'Course notes';
$string['personalnotes'] = 'Personal notes';
$string['created'] = 'created';
$string['nonotes'] = 'There are no notes of this type yet';
$string['notesnotvisible'] = 'You are not allowed to view the notes.';
$string['addnewnote'] = 'Add a new note';
$string['addnewnoteselect'] = 'Select users to write notes about';
$string['groupaddnewnote'] = 'Add a new note for all';
$string['deleteconfirm'] = 'Delete this note?';
$string['content'] = 'Content';
$string['nocontent'] = 'Note content can not be empty';
$string['nouser'] = 'You must select a user';
$string['unknown'] = 'unknown';
$string['bynameondate'] = 'by $a->name - $a->date';
$string['publishstate'] = 'Status';
$string['personal'] = 'personal';
$string['course'] = 'course';
$string['site'] = 'site';
$string['editnote'] = 'Edit note';
?>
<?PHP // $Id$
// note.php
$string['note'] = 'Note';
$string['notes'] = 'Notes';
$string['sitenotes'] = 'Site notes';
$string['coursenotes'] = 'Course notes';
$string['personalnotes'] = 'Personal notes';
$string['created'] = 'created';
$string['nonotes'] = 'There are no notes of this type yet';
$string['notesnotvisible'] = 'You are not allowed to view the notes.';
$string['addnewnote'] = 'Add a new note';
$string['addnewnoteselect'] = 'Select users to write notes about';
$string['groupaddnewnote'] = 'Add a new note for all';
$string['deleteconfirm'] = 'Delete this note?';
$string['content'] = 'Content';
$string['nocontent'] = 'Note content can not be empty';
$string['nouser'] = 'You must select a user';
$string['unknown'] = 'unknown';
$string['bynameondate'] = 'by $a->name - $a->date';
$string['publishstate'] = 'Status';
$string['personal'] = 'personal';
$string['course'] = 'course';
$string['site'] = 'site';
$string['editnote'] = 'Edit note';
$string['deletenotes'] = 'Delete all notes';
?>

View File

@ -455,7 +455,7 @@ $string['regradingquestion'] = 'Regrading \"$a\".';
$string['regradingquiz'] = 'Regrading Quiz \"$a\"';
$string['relative'] = 'Relative';
$string['remove'] = 'Remove';
$string['removeallquizattempts'] = 'Remove all quiz attempts';
$string['removeallquizattempts'] = 'Delete all quiz attempts';
$string['rename'] = 'Rename';
$string['renderingserverconnectfailed'] = 'The server $a failed to process an RQP request. Check that the URL is correct.';
$string['reordertool'] = 'Show the reordering tool';

View File

@ -46,6 +46,8 @@ $string['course:viewhiddenuserfields'] = 'View hidden user fields';
$string['course:viewparticipants'] = 'View participants';
$string['course:viewscales'] = 'View scales';
$string['course:visibility'] = 'Hide/show courses';
$string['deletecourseoverrides'] = 'Delete all overrides in course';
$string['deletelocalroles'] = 'Delete all local role assignments';
$string['grade:edit'] = 'Edit grades';
$string['grade:export'] = 'Export grades';
$string['grade:hide'] = 'Hide/unhide grades or items';

View File

@ -110,6 +110,7 @@ $string['position_error'] = 'The $a->tag tag can\'t be child of $a->parent tag';
$string['prev'] = 'Previous';
$string['raw'] = 'Raw score';
$string['regular'] = 'Regular Manifest';
$string['deleteallattempts'] = 'Delete all SCORM attempts';
$string['report'] = 'Report';
$string['resizable'] = 'Allow the window to be resized';
$string['result'] = 'Result';

View File

@ -192,6 +192,8 @@ $string['preferredstudent'] = '$a preferred';
$string['question'] = 'Question';
$string['questions'] = 'Questions';
$string['questionsnotanswered'] = 'Some of the multiple choice questions have not been answered.';
$string['deleteallanswers'] = 'Delete all survey responses';
$string['deleteanalysis'] = 'Delete response analysis';
$string['report'] = 'Survey report';
$string['responses'] = 'Responses';
$string['savednotes'] = 'Your notes were saved';

View File

@ -1077,32 +1077,35 @@ function grade_update_mod_grades($modinstance, $userid=0) {
return false;
}
$grades = array();
foreach ($oldgrades->grades as $uid=>$usergrade) {
if ($userid and $uid != $userid) {
continue;
if (!empty($oldgrades->grades)) {
$grades = array();
foreach ($oldgrades->grades as $uid=>$usergrade) {
if ($userid and $uid != $userid) {
continue;
}
$grade = new object();
$grade->userid = $uid;
if ($usergrade == '-') {
// no grade
$grade->rawgrade = null;
} else if ($scaleid) {
// scale in use, words used
$gradescale = explode(",", $scale->scale);
$grade->rawgrade = array_search($usergrade, $gradescale) + 1;
} else {
// good old numeric value
$grade->rawgrade = $usergrade;
}
$grades[] = $grade;
}
$grade = new object();
$grade->userid = $uid;
if ($usergrade == '-') {
// no grade
$grade->rawgrade = null;
} else if ($scaleid) {
// scale in use, words used
$gradescale = explode(",", $scale->scale);
$grade->rawgrade = array_search($usergrade, $gradescale) + 1;
} else {
// good old numeric value
$grade->rawgrade = $usergrade;
}
$grades[] = $grade;
grade_update('legacygrab', $grade_item->courseid, $grade_item->itemtype, $grade_item->itemmodule,
$grade_item->iteminstance, $grade_item->itemnumber, $grades);
}
grade_update('legacygrab', $grade_item->courseid, $grade_item->itemtype, $grade_item->itemmodule,
$grade_item->iteminstance, $grade_item->itemnumber, $grades);
}
} else if (function_exists($updategradesfunc) and function_exists($updateitemfunc)) {

View File

@ -3544,110 +3544,208 @@ function remove_course_contents($courseid, $showfeedback=true) {
return $result;
}
/**
* Change dates in module - used from course reset.
* @param strin $modname forum, assignent, etc
* @param array $fields array of date fields from mod table
* @param int $timeshift time difference
* @return success
*/
function shift_course_mod_dates($modname, $fields, $timeshift, $courseid) {
global $CFG;
include_once($CFG->dirroot.'/mod/'.$modname.'/lib.php');
$return = true;
foreach ($fields as $field) {
$updatesql = "UPDATE {$CFG->prefix}$modname
SET $field = $field + ($timeshift)
WHERE course=$courseid AND $field<>0 AND $field<>0";
$return = execute_sql($updatesql, false) && $return;
}
$refreshfunction = $modname.'_refresh_events';
if (function_exists($refreshfunction)) {
$refreshfunction($courseid);
}
return $return;
}
/**
* This function will empty a course of USER data as much as
/// possible. It will retain the activities and the structure
/// of the course.
*
* @uses $USER
* @uses $SESSION
* @uses $CFG
* @param object $data an object containing all the boolean settings and courseid
* @param bool $showfeedback if false then do it all silently
* @return bool
* @todo Finish documenting this function
* This function will empty a course of user data.
* It will retain the activities and the structure of the course.
* @param object $data an object containing all the settings including courseid (without magic quotes)
* @return array status array of array component, item, error
*/
function reset_course_userdata($data, $showfeedback=true) {
global $CFG, $USER, $SESSION;
function reset_course_userdata($data) {
global $CFG, $USER;
require_once($CFG->libdir.'/gradelib.php');
require_once($CFG->dirroot.'/group/lib.php');
$result = true;
$strdeleted = get_string('deleted');
// Look in every instance of every module for data to delete
if ($allmods = get_records('modules') ) {
foreach ($allmods as $mod) {
$modname = $mod->name;
$modfile = $CFG->dirroot .'/mod/'. $modname .'/lib.php';
$moddeleteuserdata = $modname .'_delete_userdata'; // Function to delete user data
if (file_exists($modfile)) {
@include_once($modfile);
if (function_exists($moddeleteuserdata)) {
$moddeleteuserdata($data, $showfeedback);
}
}
}
} else {
error('No modules are installed!');
}
// Delete other stuff
$data->courseid = $data->id;
$context = get_context_instance(CONTEXT_COURSE, $data->courseid);
if (!empty($data->reset_students) or !empty($data->reset_teachers)) {
$teachers = array_keys(get_users_by_capability($context, 'moodle/course:update'));
$participants = array_keys(get_users_by_capability($context, 'moodle/course:view'));
$students = array_diff($participants, $teachers);
if (!empty($data->reset_students)) {
foreach ($students as $studentid) {
role_unassign(0, $studentid, 0, $context->id);
}
if ($showfeedback) {
notify($strdeleted .' '.get_string('students'), 'notifysuccess');
}
/// Delete group members (but keep the groups)
$result = groups_delete_group_members($data->courseid, $showfeedback) && $result;
}
if (!empty($data->reset_teachers)) {
foreach ($teachers as $teacherid) {
role_unassign(0, $teacherid, 0, $context->id);
}
if ($showfeedback) {
notify($strdeleted .' '.get_string('teachers'), 'notifysuccess');
}
}
// calculate the time shift of dates
if (!empty($data->reset_start_date)) {
// time part of course startdate should be zero
$data->timeshift = $data->reset_start_date - usergetmidnight($data->reset_start_date_old);
} else {
$data->timeshift = 0;
}
if (!empty($data->reset_groups)) {
$result = groups_delete_groupings($data->courseid, $showfeedback) && $result;
$result = groups_delete_groups($data->courseid, $showfeedback) && $result;
}
// result array: component, item, error
$status = array();
if (!empty($data->reset_events)) {
if (delete_records('event', 'courseid', $data->courseid)) {
if ($showfeedback) {
notify($strdeleted .' event', 'notifysuccess');
}
} else {
$result = false;
}
// start the resetting
$componentstr = get_string('general');
// move the course start time
if (!empty($data->reset_start_date) and $data->timeshift) {
// change course start data
set_field('course', 'startdate', $data->reset_start_date, 'id', $data->courseid);
// update all course and group events - do not move activity events
$updatesql = "UPDATE {$CFG->prefix}event
SET timestart = timestart + ({$data->timeshift})
WHERE courseid={$data->courseid} AND instance=0";
execute_sql($updatesql, false);
$status[] = array('component'=>$componentstr, 'item'=>get_string('datechanged'), 'error'=>false);
}
if (!empty($data->reset_logs)) {
if (delete_records('log', 'course', $data->courseid)) {
if ($showfeedback) {
notify($strdeleted .' log', 'notifysuccess');
delete_records('log', 'course', $data->courseid);
$status[] = array('component'=>$componentstr, 'item'=>get_string('deletelogs'), 'error'=>false);
}
if (!empty($data->reset_events)) {
delete_records('event', 'courseid', $data->courseid);
$status[] = array('component'=>$componentstr, 'item'=>get_string('deleteevents', 'calendar'), 'error'=>false);
}
if (!empty($data->reset_notes)) {
require_once($CFG->dirroot.'/notes/lib.php');
note_delete_all($data->courseid);
$status[] = array('component'=>$componentstr, 'item'=>get_string('deletenotes', 'notes'), 'error'=>false);
}
$componentstr = get_string('roles');
if (!empty($data->reset_roles_overrides)) {
$children = get_child_contexts($context);
foreach ($children as $child) {
delete_records('role_capabilities', 'contextid', $child->id);
}
delete_records('role_capabilities', 'contextid', $context->id);
//force refresh for logged in users
mark_context_dirty($context->path);
$status[] = array('component'=>$componentstr, 'item'=>get_string('deletecourseoverrides', 'role'), 'error'=>false);
}
if (!empty($data->reset_roles_local)) {
$children = get_child_contexts($context);
foreach ($children as $child) {
role_unassign(0, 0, 0, $child->id);
}
//force refresh for logged in users
mark_context_dirty($context->path);
$status[] = array('component'=>$componentstr, 'item'=>get_string('deletelocalroles', 'role'), 'error'=>false);
}
// First unenrol users - this cleans some of related user data too, such as forum subscriptions, tracking, etc.
$data->unenrolled = array();
if (!empty($data->reset_roles)) {
foreach($data->reset_roles as $roleid) {
if ($users = get_role_users($roleid, $context, false, 'u.id', 'u.id ASC')) {
foreach ($users as $user) {
role_unassign($roleid, $user->id, 0, $context->id);
if (!has_capability('moodle/course:view', $context, $user->id)) {
$data->unenrolled[$user->id] = $user->id;
}
}
}
}
}
if (!empty($data->unenrolled)) {
$status[] = array('component'=>$componentstr, 'item'=>get_string('unenrol').' ('.count($data->unenrolled).')', 'error'=>false);
}
$componentstr = get_string('groups');
// remove all group members
if (!empty($data->reset_groups_members)) {
groups_delete_group_members($data->courseid, false);
$status[] = array('component'=>$componentstr, 'item'=>get_string('removegroupsmembers', 'group'), 'error'=>false);
}
// remove all groups
if (!empty($data->reset_groups_remove)) {
groups_delete_groups($data->courseid, false);
$status[] = array('component'=>$componentstr, 'item'=>get_string('deleteallgroups', 'group'), 'error'=>false);
}
// remove all grouping members
if (!empty($data->reset_groupings_members)) {
groups_delete_groupings_groups($data->courseid, false);
$status[] = array('component'=>$componentstr, 'item'=>get_string('removegroupingsmembers', 'group'), 'error'=>false);
}
// remove all groupings
if (!empty($data->reset_groupings_remove)) {
groups_delete_groupings($data->courseid, false);
$status[] = array('component'=>$componentstr, 'item'=>get_string('deleteallgroupings', 'group'), 'error'=>false);
}
// Look in every instance of every module for data to delete
$unsupported_mods = array();
if ($allmods = get_records('modules') ) {
foreach ($allmods as $mod) {
$modname = $mod->name;
if (!count_records($modname, 'course', $data->courseid)) {
continue; // skip mods with no instances
}
$modfile = $CFG->dirroot.'/mod/'. $modname.'/lib.php';
$moddeleteuserdata = $modname.'_reset_userdata'; // Function to delete user data
if (file_exists($modfile)) {
include_once($modfile);
if (function_exists($moddeleteuserdata)) {
$modstatus = $moddeleteuserdata($data);
if (is_array($modstatus)) {
$status = array_merge($status, $modstatus);
} else {
debugging('Module '.$modname.' returned incorrect staus - must be an array!');
}
} else {
$unsupported_mods[] = $mod;
}
} else {
debugging('Missing lib.php in '.$modname.' module!');
}
} else {
$result = false;
}
}
// deletes all role assignments, and local override,
// these have no courseid in table and needs separate process
delete_records('role_capabilities', 'contextid', $context->id);
// mention unsupported mods
if (!empty($unsupported_mods)) {
foreach($unsupported_mods as $mod) {
$status[] = array('component'=>get_string('modulenameplural', $mod->name), 'item'=>'', 'error'=>get_string('resetnotimplemented'));
}
}
// force accessinfo refresh for users visiting this context...
mark_context_dirty($context->path);
return $result;
$componentstr = get_string('gradebook', 'grades');
// reset gradebook
if (!empty($data->reset_gradebook_items)) {
remove_course_grades($data->courseid, false);
grade_grab_course_grades($data->courseid);
grade_regrade_final_grades($data->courseid);
$status[] = array('component'=>$componentstr, 'item'=>get_string('removeallcourseitems', 'grades'), 'error'=>false);
} else if (!empty($data->reset_gradebook_grades)) {
grade_course_reset($data->courseid);
$status[] = array('component'=>$componentstr, 'item'=>get_string('removeallcoursegrades', 'grades'), 'error'=>false);
}
return $status;
}
function generate_email_processing_address($modid,$modargs) {

View File

@ -32,6 +32,7 @@ class assignment_base {
var $usehtmleditor;
var $defaultformat;
var $context;
var $type;
/**
* Constructor for the base assignment class
@ -1730,18 +1731,18 @@ class assignment_base {
}
}
/*
/**
* Return true if is set description is hidden till available date
*
* This is needed by calendar so that hidden descriptions do not
* This is needed by calendar so that hidden descriptions do not
* come up in upcoming events.
*
* Check that description is hidden till available date
* Check that description is hidden till available date
* By default return false
* Assignments types should implement this method if needed
* @return boolen
*/
*/
function description_is_hidden() {
return false;
}
@ -1851,6 +1852,51 @@ class assignment_base {
//no plugin cron by default - override if needed
}
/**
* Reset all submissions
*/
function reset_userdata($data) {
global $CFG;
require_once($CFG->libdir.'/filelib.php');
if (!count_records('assignment', 'course', $data->courseid, 'assignmenttype', $this->type)) {
return array(); // no assignments of this type present
}
$componentstr = get_string('modulenameplural', 'assignment');
$status = array();
$typestr = get_string('type'.$this->type, 'assignment');
if (!empty($data->reset_assignment_submissions)) {
$assignmentssql = "SELECT a.id
FROM {$CFG->prefix}assignment a
WHERE a.course={$data->courseid} AND a.assignmenttype='{$this->type}'";
delete_records_select('assignment_submissions', "assignment IN ($assignmentssql)");
if ($assignments = get_records_sql($assignmentssql)) {
foreach ($assignments as $assignmentid=>$unused) {
fulldelete($CFG->dataroot.'/'.$data->courseid.'/moddata/assignment/'.$assignmentid);
}
}
$status[] = array('component'=>$componentstr, 'item'=>get_string('deleteallsubmissions','assignment').': '.$typestr, 'error'=>false);
if (empty($data->reset_gradebook_grades)) {
// remove all grades from gradebook
assignment_reset_gradebook($data->courseid, $this->type);
}
}
/// updating dates - shift may be negative too
if ($data->timeshift) {
shift_course_mod_dates('assignment', array('timedue', 'timeavailable'), $data->timeshift, $data->courseid);
$status[] = array('component'=>$componentstr, 'item'=>get_string('datechanged').': '.$typestr, 'error'=>false);
}
return $status;
}
} ////// End of the assignment_base class
@ -2130,7 +2176,7 @@ function assignment_update_grades($assignment=null, $userid=0, $nullifnone=true)
* Create grade item for given assignment
*
* @param object $assignment object with extra cmidnumber
* @param mixed optional array/object of grade(s)
* @param mixed optional array/object of grade(s); 'reset' means reset grades in gradebook
* @return int 0 if ok, error code otherwise
*/
function assignment_grade_item_update($assignment, $grades=NULL) {
@ -2158,6 +2204,11 @@ function assignment_grade_item_update($assignment, $grades=NULL) {
$params['gradetype'] = GRADE_TYPE_NONE;
}
if ($grades === 'reset') {
$params['reset'] = true;
$grades = NULL;
}
return grade_update('mod/assignment', $assignment->courseid, 'mod', 'assignment', $assignment->id, 0, $grades, $params);
}
@ -2803,4 +2854,64 @@ function assignment_get_types() {
return $types;
}
/**
* Removes all grades from gradebook
* @param int $courseid
* @param string optional type
*/
function assignment_reset_gradebook($courseid, $type='') {
global $CFG;
$type = $type ? "AND a.assignmenttype='$type'" : '';
$sql = "SELECT a.*, cm.idnumber as cmidnumber, a.course as courseid
FROM {$CFG->prefix}assignment a, {$CFG->prefix}course_modules cm, {$CFG->prefix}modules m
WHERE m.name='assignment' AND m.id=cm.module AND cm.instance=a.id AND a.course=$courseid $type";
if ($assignments = get_records_sql($sql)) {
foreach ($assignments as $assignment) {
assignment_grade_item_update($assignment, 'reset');
}
}
}
/**
* This function is used by the reset_course_userdata function in moodlelib.
* This function will remove all posts from the specified assignment
* and clean up any related data.
* @param $data the data submitted from the reset course.
* @return array status array
*/
function assignment_reset_userdata($data) {
global $CFG;
$status = array();
foreach (get_list_of_plugins('mod/assignment/type') as $type) {
require_once("$CFG->dirroot/mod/assignment/type/$type/assignment.class.php");
$assignmentclass = "assignment_$type";
$ass = new $assignmentclass();
$status = array_merge($status, $ass->reset_userdata($data));
}
return $status;
}
/**
* Implementation of the function for printing the form elements that control
* whether the course reset functionality affects the assignment.
* @param $mform form passed by reference
*/
function assignment_reset_course_form_definition(&$mform) {
$mform->addElement('header', 'assignmentheader', get_string('modulenameplural', 'assignment'));
$mform->addElement('advcheckbox', 'reset_assignment_submissions', get_string('deleteallsubmissions','assignment'));
}
/**
* Course reset form defaults.
*/
function assignment_reset_course_form_defaults($course) {
return array('reset_assignment_submissions'=>1);
}
?>

View File

@ -8,6 +8,7 @@ class assignment_offline extends assignment_base {
function assignment_offline($cmid='staticonly', $assignment=NULL, $cm=NULL, $course=NULL) {
parent::assignment_base($cmid, $assignment, $cm, $course);
$this->type = 'offline';
}
function display_lateness($timesubmitted) {

View File

@ -9,6 +9,7 @@ class assignment_online extends assignment_base {
function assignment_online($cmid='staticonly', $assignment=NULL, $cm=NULL, $course=NULL) {
parent::assignment_base($cmid, $assignment, $cm, $course);
$this->type = 'online';
}
function view() {

View File

@ -11,7 +11,7 @@ class assignment_upload extends assignment_base {
function assignment_upload($cmid='staticonly', $assignment=NULL, $cm=NULL, $course=NULL) {
parent::assignment_base($cmid, $assignment, $cm, $course);
$this->type = 'upload';
}
function view() {

View File

@ -41,7 +41,7 @@ class assignment_uploadsingle extends assignment_base {
function assignment_uploadsingle($cmid='staticonly', $assignment=NULL, $cm=NULL, $course=NULL) {
parent::assignment_base($cmid, $assignment, $cm, $course);
$this->type = 'uploadsingle';
}
function view() {

View File

@ -686,4 +686,53 @@ function chat_print_overview($courses, &$htmlarray) {
}
}
/**
* Implementation of the function for printing the form elements that control
* whether the course reset functionality affects the chat.
* @param $mform form passed by reference
*/
function chat_reset_course_form_definition(&$mform) {
$mform->addElement('header', 'chatheader', get_string('modulenameplural', 'chat'));
$mform->addElement('advcheckbox', 'reset_chat', get_string('removemessages','chat'));
}
/**
* Course reset form defaults.
*/
function chat_reset_course_form_defaults($course) {
return array('reset_chat'=>1);
}
/**
* Actual implementation of the rest coures functionality, delete all the
* chat messages for course $data->courseid.
* @param $data the data submitted from the reset course.
* @return array status array
*/
function chat_reset_userdata($data) {
global $CFG;
$componentstr = get_string('modulenameplural', 'chat');
$status = array();
if (!empty($data->reset_chat)) {
$chatessql = "SELECT ch.id
FROM {$CFG->prefix}chat ch
WHERE ch.course={$data->courseid}";
delete_records_select('chat_messages', "chatid IN ($chatessql)");
delete_records_select('chat_users', "chatid IN ($chatessql)");
$status[] = array('component'=>$componentstr, 'item'=>get_string('removemessages', 'chat'), 'error'=>false);
}
/// updating dates - shift may be negative too
if ($data->timeshift) {
shift_course_mod_dates('chat', array('chattime'), $data->timeshift, $data->courseid);
$status[] = array('component'=>$componentstr, 'item'=>get_string('datechanged'), 'error'=>false);
}
return $status;
}
?>

View File

@ -668,4 +668,52 @@ function choice_get_post_actions() {
return array('choose','choose again');
}
/**
* Implementation of the function for printing the form elements that control
* whether the course reset functionality affects the choice.
* @param $mform form passed by reference
*/
function choice_reset_course_form_definition(&$mform) {
$mform->addElement('header', 'choiceheader', get_string('modulenameplural', 'choice'));
$mform->addElement('advcheckbox', 'reset_choice', get_string('removeresponses','choice'));
}
/**
* Course reset form defaults.
*/
function choice_reset_course_form_defaults($course) {
return array('reset_choice'=>1);
}
/**
* Actual implementation of the rest coures functionality, delete all the
* choice responses for course $data->courseid.
* @param $data the data submitted from the reset course.
* @return array status array
*/
function choice_reset_userdata($data) {
global $CFG;
$componentstr = get_string('modulenameplural', 'choice');
$status = array();
if (!empty($data->reset_choice)) {
$choicessql = "SELECT ch.id
FROM {$CFG->prefix}choice ch
WHERE ch.course={$data->courseid}";
delete_records_select('choice_answers', "choiceid IN ($choicessql)");
$status[] = array('component'=>$componentstr, 'item'=>get_string('removeresponses', 'choice'), 'error'=>false);
}
/// updating dates - shift may be negative too
if ($data->timeshift) {
shift_course_mod_dates('choice', array('timeopen', 'timeclose'), $data->timeshift, $data->courseid);
$status[] = array('component'=>$componentstr, 'item'=>get_string('datechanged'), 'error'=>false);
}
return $status;
}
?>

View File

@ -796,9 +796,10 @@ function data_update_grades($data=null, $userid=0, $nullifnone=true) {
* Update/create grade item for given data
*
* @param object $data object with extra cmidnumber
* @param mixed optional array/object of grade(s); 'reset' means reset grades in gradebook
* @return object grade_item
*/
function data_grade_item_update($data) {
function data_grade_item_update($data, $grades=NULL) {
global $CFG;
if (!function_exists('grade_update')) { //workaround for buggy PHP versions
require_once($CFG->libdir.'/gradelib.php');
@ -819,7 +820,12 @@ function data_grade_item_update($data) {
$params['scaleid'] = -$data->scale;
}
return grade_update('mod/data', $data->course, 'mod', 'data', $data->id, 0, NULL, $params);
if ($grades === 'reset') {
$params['reset'] = true;
$grades = NULL;
}
return grade_update('mod/data', $data->course, 'mod', 'data', $data->id, 0, $grades, $params);
}
/**
@ -2092,4 +2098,156 @@ function data_preset_path($course, $userid, $shortname) {
return 'Does it disturb you that this code will never run?';
}
/**
* Implementation of the function for printing the form elements that control
* whether the course reset functionality affects the data.
* @param $mform form passed by reference
*/
function data_reset_course_form_definition(&$mform) {
$mform->addElement('header', 'dataheader', get_string('modulenameplural', 'data'));
$mform->addElement('checkbox', 'reset_data', get_string('deleteallentries','data'));
$mform->addElement('checkbox', 'reset_data_notenrolled', get_string('deletenotenrolled', 'data'));
$mform->disabledIf('reset_data_notenrolled', 'reset_data', 'checked');
$mform->addElement('checkbox', 'reset_data_ratings', get_string('deleteallratings'));
$mform->disabledIf('reset_data_ratings', 'reset_data', 'checked');
$mform->addElement('checkbox', 'reset_data_comments', get_string('deleteallcomments'));
$mform->disabledIf('reset_data_comments', 'reset_data', 'checked');
}
/**
* Course reset form defaults.
*/
function data_reset_course_form_defaults($course) {
return array('reset_data'=>0, 'reset_data_ratings'=>1, 'reset_data_comments'=>1, 'reset_data_notenrolled'=>0);
}
/**
* Removes all grades from gradebook
* @param int $courseid
* @param string optional type
*/
function data_reset_gradebook($courseid, $type='') {
global $CFG;
$sql = "SELECT d.*, cm.idnumber as cmidnumber, d.course as courseid
FROM {$CFG->prefix}data d, {$CFG->prefix}course_modules cm, {$CFG->prefix}modules m
WHERE m.name='data' AND m.id=cm.module AND cm.instance=d.id AND d.course=$courseid";
if ($datas = get_records_sql($sql)) {
foreach ($datas as $data) {
data_grade_item_update($data, 'reset');
}
}
}
/**
* Actual implementation of the rest coures functionality, delete all the
* data responses for course $data->courseid.
* @param $data the data submitted from the reset course.
* @return array status array
*/
function data_reset_userdata($data) {
global $CFG;
require_once($CFG->libdir.'/filelib.php');
$componentstr = get_string('modulenameplural', 'data');
$status = array();
$allrecordssql = "SELECT r.id
FROM {$CFG->prefix}data_records r
INNER JOIN {$CFG->prefix}data d ON r.dataid = d.id
WHERE d.course = {$data->courseid}";
$alldatassql = "SELECT d.id
FROM {$CFG->prefix}data d
WHERE d.course={$data->courseid}";
// delete entries if requested
if (!empty($data->reset_data)) {
delete_records_select('data_ratings', "recordid IN ($allrecordssql)");
delete_records_select('data_comments', "recordid IN ($allrecordssql)");
delete_records_select('data_content', "recordid IN ($allrecordssql)");
delete_records_select('data_records', "dataid IN ($alldatassql)");
if ($datas = get_records_sql($alldatassql)) {
foreach ($datas as $dataid=>$unused) {
fulldelete("$CFG->dataroot/$data->courseid/moddata/data/$dataid");
}
}
if (empty($data->reset_gradebook_grades)) {
// remove all grades from gradebook
data_reset_gradebook($data->courseid);
}
$status[] = array('component'=>$componentstr, 'item'=>get_string('deleteallentries', 'data'), 'error'=>false);
}
// remove entries by users not enrolled into course
if (!empty($data->reset_data_notenrolled)) {
$recordssql = "SELECT r.id, r.userid, r.dataid, u.id AS userexists, u.deleted AS userdeleted
FROM {$CFG->prefix}data_records r
INNER JOIN {$CFG->prefix}data d ON r.dataid = d.id
LEFT OUTER JOIN {$CFG->prefix}user u ON r.userid = u.id
WHERE d.course = {$data->courseid} AND r.userid > 0";
$course_context = get_context_instance(CONTEXT_COURSE, $data->courseid);
$notenrolled = array();
$fields = array();
if ($rs = get_recordset_sql($recordssql)) {
while ($record = rs_fetch_next_record($rs)) {
if (array_key_exists($record->userid, $notenrolled) or !$record->userexists or $record->userdeleted
or !has_capability('moodle/course:view', $course_context , $record->userid)) {
delete_records('data_ratings', 'recordid', $record->id);
delete_records('data_comments', 'recordid', $record->id);
delete_records('data_content', 'recordid', $record->id);
delete_records('data_records', 'id', $record->id);
// HACK: this is ugly - the recordid should be before the fieldid!
if (!array_key_exists($record->dataid, $fields)) {
if ($fs = get_records('data_fields', 'dataid', $record->dataid)) {
$fields[$record->dataid] = array_keys($fs);
} else {
$fields[$record->dataid] = array();
}
}
foreach($fields[$record->dataid] as $fieldid) {
fulldelete("$CFG->dataroot/$data->courseid/moddata/data/$record->dataid/$fieldid/$record->id");
}
$notenrolled[$record->userid] = true;
}
}
rs_close($rs);
$status[] = array('component'=>$componentstr, 'item'=>get_string('deletenotenrolled', 'data'), 'error'=>false);
}
}
// remove all ratings
if (!empty($data->reset_data_ratings)) {
delete_records_select('data_ratings', "recordid IN ($allrecordssql)");
if (empty($data->reset_gradebook_grades)) {
// remove all grades from gradebook
data_reset_gradebook($data->courseid);
}
$status[] = array('component'=>$componentstr, 'item'=>get_string('deleteallratings'), 'error'=>false);
}
// remove all comments
if (!empty($data->reset_data_comments)) {
delete_records_select('data_comments', "recordid IN ($allrecordssql)");
$status[] = array('component'=>$componentstr, 'item'=>get_string('deleteallcomments'), 'error'=>false);
}
/// updating dates - shift may be negative too
if ($data->timeshift) {
shift_course_mod_dates('data', array('timeavailablefrom', 'timeavailableto', 'timeviewfrom', 'timeviewto'), $data->timeshift, $data->courseid);
$status[] = array('component'=>$componentstr, 'item'=>get_string('datechanged'), 'error'=>false);
}
return $status;
}
?>

View File

@ -19,6 +19,9 @@ define('FORUM_TRACKING_ON', 2);
define('FORUM_UNSET_POST_RATING', -999);
// this file may be included from some functions, we must define these as global explicitly
global $FORUM_LAYOUT_MODES, $FORUM_TYPES, $FORUM_TYPES_ALL, $FORUM_OPEN_MODES;
$FORUM_LAYOUT_MODES = array ( FORUM_MODE_FLATOLDEST => get_string('modeflatoldestfirst', 'forum'),
FORUM_MODE_FLATNEWEST => get_string('modeflatnewestfirst', 'forum'),
FORUM_MODE_THREADED => get_string('modethreaded', 'forum'),
@ -28,8 +31,15 @@ $FORUM_LAYOUT_MODES = array ( FORUM_MODE_FLATOLDEST => get_string('modeflatoldes
$FORUM_TYPES = array ('general' => get_string('generalforum', 'forum'),
'eachuser' => get_string('eachuserforum', 'forum'),
'single' => get_string('singleforum', 'forum'),
'qanda' => get_string('qandaforum', 'forum')
);
'qanda' => get_string('qandaforum', 'forum'));
$FORUM_TYPES_ALL = array ('news' => get_string('namenews','forum'),
'social' => get_string('namesocial','forum'),
'general' => get_string('generalforum', 'forum'),
'eachuser' => get_string('eachuserforum', 'forum'),
'single' => get_string('singleforum', 'forum'),
'qanda' => get_string('qandaforum', 'forum'));
$FORUM_OPEN_MODES = array ('2' => get_string('openmode2', 'forum'),
'1' => get_string('openmode1', 'forum'),
@ -905,6 +915,7 @@ function forum_make_mail_html($course, $forum, $discussion, $post, $userfrom, $u
function forum_user_outline($course, $user, $mod, $forum) {
if ($posts = forum_get_user_posts($forum->id, $user->id)) {
$result = new object();
$result->info = get_string("numposts", "forum", count($posts));
$lastpost = array_pop($posts);
@ -1189,9 +1200,10 @@ function forum_update_grades($forum=null, $userid=0, $nullifnone=true) {
* Create/update grade item for given forum
*
* @param object $forum object with extra cmidnumber
* @param mixed optional array/object of grade(s); 'reset' means reset grades in gradebook
* @return int 0 if ok
*/
function forum_grade_item_update($forum) {
function forum_grade_item_update($forum, $grades=NULL) {
global $CFG;
if (!function_exists('grade_update')) { //workaround for buggy PHP versions
require_once($CFG->libdir.'/gradelib.php');
@ -1212,7 +1224,12 @@ function forum_grade_item_update($forum) {
$params['scaleid'] = -$forum->scale;
}
return grade_update('mod/forum', $forum->course, 'mod', 'forum', $forum->id, 0, NULL, $params);
if ($grades === 'reset') {
$params['reset'] = true;
$grades = NULL;
}
return grade_update('mod/forum', $forum->course, 'mod', 'forum', $forum->id, 0, $grades, $params);
}
/**
@ -2023,6 +2040,7 @@ function forum_get_course_forum($courseid, $type) {
notify("Could not find forum module!!");
return false;
}
$mod = new object();
$mod->course = $courseid;
$mod->module = $module->id;
$mod->instance = $forum->id;
@ -2276,6 +2294,7 @@ function forum_print_post(&$post, $courseid, $ownpost=false, $reply=false, $link
echo '<div class="author">';
$fullname = fullname($post, has_capability('moodle/site:viewfullnames', $post->modcontext));
$by = new object();
$by->name = '<a href="'.$CFG->wwwroot.'/user/view.php?id='.
$post->userid.'&amp;course='.$courseid.'">'.$fullname.'</a>';
$by->date = userdate($post->modified);
@ -2577,6 +2596,7 @@ function forum_print_discussion_header(&$post, $forum, $group=-1, $datestring=""
echo '<td class="lastpost">';
$usedate = (empty($post->timemodified)) ? $post->modified : $post->timemodified; // Just in case
$parenturl = (empty($post->lastpostid)) ? '' : '&amp;parent='.$post->lastpostid;
$usermodified = new object();
$usermodified->id = $post->usermodified;
$usermodified->firstname = $post->umfirstname;
$usermodified->lastname = $post->umlastname;
@ -3082,6 +3102,7 @@ function forum_add_discussion($discussion,&$message) {
// The first post is stored as a real post, and linked
// to from the discuss entry.
$post = new object();
$post->discussion = 0;
$post->parent = 0;
$post->userid = $USER->id;
@ -3254,6 +3275,7 @@ function forum_subscribe($userid, $forumid) {
return true;
}
$sub = new object();
$sub->userid = $userid;
$sub->forum = $forumid;
@ -3285,6 +3307,7 @@ function forum_post_subscription($post) {
return "";
}
$info = new object();
$info->name = fullname($USER);
$info->forum = $forum->name;
@ -4070,6 +4093,7 @@ function forum_print_posts_threaded($parent, $courseid, $depth, $ratings, $reply
if (!forum_user_can_see_post($post->forum,$post->discussion,$post)) {
continue;
}
$by = new object();
$by->name = fullname($post, $canviewfullnames);
$by->date = userdate($post->modified);
@ -4313,7 +4337,7 @@ function forum_role_assign($userid, $context, $roleid) {
}
/*
/**
* This function gets run whenever a role is assigned to a user in a context
*
* @param integer $userid
@ -4321,7 +4345,14 @@ function forum_role_assign($userid, $context, $roleid) {
* @return bool
*/
function forum_role_unassign($userid, $context) {
return forum_remove_user_subscriptions($userid, $context);
if (empty($context->contextlevel)) {
return false;
}
forum_remove_user_subscriptions($userid, $context);
forum_remove_user_tracking($userid, $context);
return true;
}
@ -4400,9 +4431,9 @@ function forum_add_user_default_subscriptions($userid, $context) {
* Remove subscriptions for a user in a context
*/
function forum_remove_user_subscriptions($userid, $context) {
global $CFG;
if (empty($context->contextlevel)) {
return false;
}
@ -4412,14 +4443,12 @@ function forum_remove_user_subscriptions($userid, $context) {
case CONTEXT_SYSTEM: // For the whole site
//if ($courses = get_my_courses($userid)) {
// find all courses in which this user has a forum subscription
if ($courses = get_records_sql("SELECT c.*
FROM {$CFG->prefix}course c,
{$CFG->prefix}forum_subscriptions fs,
{$CFG->prefix}forum f
WHERE c.id = f.course
AND f.id = fs.forum
AND fs.userid = $userid")) {
if ($courses = get_records_sql("SELECT c.id
FROM {$CFG->prefix}course c,
{$CFG->prefix}forum_subscriptions fs,
{$CFG->prefix}forum f
WHERE c.id = f.course AND f.id = fs.forum AND fs.userid = $userid")) {
foreach ($courses as $course) {
$subcontext = get_context_instance(CONTEXT_COURSE, $course->id);
forum_remove_user_subscriptions($userid, $subcontext);
@ -4428,13 +4457,13 @@ function forum_remove_user_subscriptions($userid, $context) {
break;
case CONTEXT_COURSECAT: // For a whole category
if ($courses = get_records('course', 'category', $context->instanceid)) {
if ($courses = get_records('course', 'category', $context->instanceid, '', 'id')) {
foreach ($courses as $course) {
$subcontext = get_context_instance(CONTEXT_COURSE, $course->id);
forum_remove_user_subscriptions($userid, $subcontext);
}
}
if ($categories = get_records('course_categories', 'parent', $context->instanceid)) {
if ($categories = get_records('course_categories', 'parent', $context->instanceid, '', 'id')) {
foreach ($categories as $category) {
$subcontext = get_context_instance(CONTEXT_COURSECAT, $category->id);
forum_remove_user_subscriptions($userid, $subcontext);
@ -4443,21 +4472,17 @@ function forum_remove_user_subscriptions($userid, $context) {
break;
case CONTEXT_COURSE: // For a whole course
if ($course = get_record('course', 'id', $context->instanceid)) {
if ($course = get_record('course', 'id', $context->instanceid, '', '', '', '', 'id')) {
// find all forums in which this user has a subscription, and its coursemodule id
if ($forums = get_records_sql("SELECT f.id, cm.id as coursemodule
FROM {$CFG->prefix}forum f,
{$CFG->prefix}modules m,
{$CFG->prefix}course_modules cm,
{$CFG->prefix}forum_subscriptions fs
WHERE fs.userid = $userid
AND fs.forum = f.id
AND f.course = $context->instanceid
AND cm.instance = f.id
AND cm.module = m.id
AND m.name = 'forum'")) {
//if ($forums = get_all_instances_in_course('forum', $course, $userid, true)) {
FROM {$CFG->prefix}forum f,
{$CFG->prefix}modules m,
{$CFG->prefix}course_modules cm,
{$CFG->prefix}forum_subscriptions fs
WHERE fs.userid = $userid AND f.course = $context->instanceid
AND fs.forum = f.id AND cm.instance = f.id
AND cm.module = m.id AND m.name = 'forum'")) {
foreach ($forums as $forum) {
if ($modcontext = get_context_instance(CONTEXT_MODULE, $forum->coursemodule)) {
if (!has_capability('mod/forum:viewdiscussion', $modcontext, $userid)) {
@ -4484,45 +4509,139 @@ function forum_remove_user_subscriptions($userid, $context) {
}
// Functions to do with read tracking.
/**
*
* Remove post tracking for a user in a context
*/
function forum_tp_add_read_record($userid, $postid, $discussionid=-1, $forumid=-1) {
if (($readrecord = forum_tp_get_read_records($userid, $postid)) === false) {
function forum_remove_user_tracking($userid, $context) {
global $CFG;
if (empty($context->contextlevel)) {
return false;
}
switch ($context->contextlevel) {
case CONTEXT_SYSTEM: // For the whole site
// find all courses in which this user has tracking info
$allcourses = array();
if ($courses = get_records_sql("SELECT c.id
FROM {$CFG->prefix}course c,
{$CFG->prefix}forum_read fr,
{$CFG->prefix}forum f
WHERE c.id = f.course AND f.id = fr.forumid AND fr.userid = $userid")) {
$allcourses = $allcourses + $courses;
}
if ($courses = get_records_sql("SELECT c.id
FROM {$CFG->prefix}course c,
{$CFG->prefix}forum_track_prefs ft,
{$CFG->prefix}forum f
WHERE c.id = f.course AND f.id = ft.forumid AND ft.userid = $userid")) {
$allcourses = $allcourses + $courses;
}
foreach ($allcourses as $course) {
$subcontext = get_context_instance(CONTEXT_COURSE, $course->id);
forum_remove_user_tracking($userid, $subcontext);
}
break;
case CONTEXT_COURSECAT: // For a whole category
if ($courses = get_records('course', 'category', $context->instanceid, '', 'id')) {
foreach ($courses as $course) {
$subcontext = get_context_instance(CONTEXT_COURSE, $course->id);
forum_remove_user_tracking($userid, $subcontext);
}
}
if ($categories = get_records('course_categories', 'parent', $context->instanceid, '', 'id')) {
foreach ($categories as $category) {
$subcontext = get_context_instance(CONTEXT_COURSECAT, $category->id);
forum_remove_user_tracking($userid, $subcontext);
}
}
break;
case CONTEXT_COURSE: // For a whole course
if ($course = get_record('course', 'id', $context->instanceid, '', '', '', '', 'id')) {
// find all forums in which this user has reading tracked
if ($forums = get_records_sql("SELECT f.id, cm.id as coursemodule
FROM {$CFG->prefix}forum f,
{$CFG->prefix}modules m,
{$CFG->prefix}course_modules cm,
{$CFG->prefix}forum_read fr
WHERE fr.userid = $userid AND f.course = $context->instanceid
AND fr.forumid = f.id AND cm.instance = f.id
AND cm.module = m.id AND m.name = 'forum'")) {
foreach ($forums as $forum) {
if ($modcontext = get_context_instance(CONTEXT_MODULE, $forum->coursemodule)) {
if (!has_capability('mod/forum:viewdiscussion', $modcontext, $userid)) {
forum_tp_delete_read_records($userid, -1, -1, $forum->id);
}
}
}
}
// find all forums in which this user has a disabled tracking
if ($forums = get_records_sql("SELECT f.id, cm.id as coursemodule
FROM {$CFG->prefix}forum f,
{$CFG->prefix}modules m,
{$CFG->prefix}course_modules cm,
{$CFG->prefix}forum_track_prefs ft
WHERE ft.userid = $userid AND f.course = $context->instanceid
AND ft.forumid = f.id AND cm.instance = f.id
AND cm.module = m.id AND m.name = 'forum'")) {
foreach ($forums as $forum) {
if ($modcontext = get_context_instance(CONTEXT_MODULE, $forum->coursemodule)) {
if (!has_capability('mod/forum:viewdiscussion', $modcontext, $userid)) {
delete_records('forum_track_prefs', 'userid', $userid, 'forumid', $forum->id);
}
}
}
}
}
break;
case CONTEXT_MODULE: // Just one forum
if ($cm = get_coursemodule_from_id('forum', $context->instanceid)) {
if ($forum = get_record('forum', 'id', $cm->instance)) {
if (!has_capability('mod/forum:viewdiscussion', $context, $userid)) {
delete_records('forum_track_prefs', 'userid', $userid, 'forumid', $forum->id);
forum_tp_delete_read_records($userid, -1, -1, $forum->id);
}
}
}
break;
}
return true;
}
/**
*
*/
function forum_tp_add_read_record($userid, $postid, $discussionid, $forumid) {
if (!$readrecords = forum_tp_get_read_records($userid, $postid)) {
// New read record
unset($readrecord);
$readrecord->userid = $userid;
$readrecord->postid = $postid;
$readrecord = new object();
$readrecord->userid = $userid;
$readrecord->postid = $postid;
$readrecord->discussionid = $discussionid;
$readrecord->forumid = $forumid;
$readrecord->firstread = time();
$readrecord->lastread = $readrecord->firstread;
$readrecord->forumid = $forumid;
$readrecord->firstread = time();
$readrecord->lastread = $readrecord->firstread;
return insert_record('forum_read', $readrecord, true);
} else {
// Update read record
$readrecord = reset($readrecord);
$readrecord->lastread = time();
$update = NULL;
$update->id = $readrecord->id;
$update->lastread = $readrecord->lastread;
// This shouldn't happen, but just in case...
if (!$readrecord->firstread) {
// Update the 'firstread' field.
$update->firstread = $readrecord->lastread;
}
if ($discussionid > -1) {
// Update the 'discussionid' field.
$update->discussionid = $discussionid;
}
if ($forumid > -1) {
// Update the 'forumid' field.
$update->forumid = $forumid;
}
return update_record('forum_read', $update);
$readrecord = reset($readrecords);
$readrecord->lastread = time();
$readrecord->discussionid = $discussionid;
$readrecord->forumid = $forumid;
return update_record('forum_read', $readrecord);
}
}
@ -5042,6 +5161,7 @@ function forum_check_throttling($forum) {
.' ON p.discussion = d.id WHERE d.forum = '.$forum->id
.' AND p.userid = '.$USER->id.' AND p.created > '.$timeafter);
$a = new object();
$a->blockafter = $forum->blockafter;
$a->numposts = $numposts;
$a->blockperiod = get_string('secondstotime'.$forum->blockperiod);
@ -5058,106 +5178,180 @@ function forum_check_throttling($forum) {
/**
* This function is used by the remove_course_userdata function in moodlelib.
* If this function exists, remove_course_userdata will execute it.
* This function will remove all posts from the specified forum.
* Removes all grades from gradebook
* @param int $courseid
* @param string optional type
*/
function forum_delete_userdata($data, $showfeedback=true) {
function forum_reset_gradebook($courseid, $type='') {
global $CFG;
$sql = "DELETE FROM {$CFG->prefix}forum_posts
WHERE discussion IN (
SELECT fd.id FROM {$CFG->prefix}forum_discussions fd, {$CFG->prefix}forum f
WHERE f.course={$data->courseid} AND f.id=fd.forum "; // closing ) added bellow
$strreset = get_string('reset');
$attforumtype = '';
$postsarr = array();
if (!empty($data->reset_forum_news)) {
$select = "$sql AND f.type = 'news' )";
$postsarr = forum_get_posts_with_attachments($data->courseid," 'news' ",$postsarr);//select posts from news forum with attachments
if (execute_sql($select, false) and $showfeedback) {
notify($strreset.': '.get_string('namenews','forum'), 'notifysuccess');
}
}
if (!empty($data->reset_forum_single)) {
$select = "$sql AND f.type = 'single' ) AND parent <> 0 ";
$postsarr = forum_get_posts_with_attachments($data->courseid," 'single' AND fp.parent<>0 ",$postsarr);
if (execute_sql($select, false) and $showfeedback) {
notify($strreset.': '.get_string('singleforum','forum'), 'notifysuccess');
}
}
if (!empty($data->reset_forum_eachuser)) {
$select = "$sql AND f.type = 'eachuser' )";
$postsarr = forum_get_posts_with_attachments($data->courseid," 'eachuser' ",$postsarr);
if (execute_sql($select, false) and $showfeedback) {
notify($strreset.': '.get_string('eachuserforum','forum'), 'notifysuccess');
}
}
if (!empty($data->reset_forum_general)) {
$select = "$sql AND f.type = 'general' )";
$postsarr = forum_get_posts_with_attachments($data->courseid," 'general' ",$postsarr);
if (execute_sql($select, false) and $showfeedback) {
notify($strreset.': '.get_string('generalforum','forum'), 'notifysuccess');
}
}
//selected posts with attachments to delete attachments files
foreach($postsarr as $post){
forum_delete_old_attachments($post);
}
if (!empty($data->reset_forum_subscriptions)) {
$subscripsql = "DELETE FROM {$CFG->prefix}forum_subscriptions
WHERE forum IN (
SELECT id FROM {$CFG->prefix}forum
WHERE course = {$data->courseid} )";
$type = $type ? "AND f.type='$type'" : '';
if (execute_sql($subscripsql, false) and $showfeedback) {
notify($strreset.': '.get_string('resetsubscriptions','forum'), 'notifysuccess');
$sql = "SELECT f.*, cm.idnumber as cmidnumber, f.course as courseid
FROM {$CFG->prefix}forum f, {$CFG->prefix}course_modules cm, {$CFG->prefix}modules m
WHERE m.name='forum' AND m.id=cm.module AND cm.instance=f.id AND f.course=$courseid $type";
if ($forums = get_records_sql($sql)) {
foreach ($forums as $forum) {
forum_grade_item_update($forum, 'reset');
}
}
}
/*
* Gets posts from selected course and forum type with attachments to delete this attachements files
*
* @param int $courseid course id
* @param string $ftype type of forum
* @param array $postsarr array of selected posts, we are adding to this array new posts
*
* @return mixed an array of objects, or false if no records were found or an error occured.
*/
function forum_get_posts_with_attachments($courseid,$ftype,$postsarr){
global $CFG;
$attquery = "SELECT fp.*,fd.course,fd.forum
FROM {$CFG->prefix}forum_discussions fd,{$CFG->prefix}forum_posts fp,{$CFG->prefix}forum f
WHERE fd.course = $courseid
AND fd.id = fp.discussion
AND fp.attachment <>''
AND f.id = fd.forum
AND f.type = $ftype ";
if ($records = get_records_sql($attquery)){
return array_merge((array)$postsarr,$records);
/**
* This function is used by the reset_course_userdata function in moodlelib.
* This function will remove all posts from the specified forum
* and clean up any related data.
* @param $data the data submitted from the reset course.
* @return array status array
*/
function forum_reset_userdata($data) {
global $CFG, $FORUM_TYPES_ALL;
require_once($CFG->libdir.'/filelib.php');
$componentstr = get_string('modulenameplural', 'forum');
$status = array();
$removeposts = false;
if (!empty($data->reset_forum_all)) {
$removeposts = true;
$typesql = "";
$typesstr = get_string('resetforumsall', 'forum');
$types = array();
} else if (!empty($data->reset_forum_types)){
$removeposts = true;
$typesql = "";
$types = array();
foreach ($data->reset_forum_types as $type) {
if (!array_key_exists($type, $FORUM_TYPES_ALL)) {
continue;
}
$typesql .= " AND f.type='$type'";
$types[] = $FORUM_TYPES_ALL[$type];
}
$typesstr = get_string('resetforums', 'forum').': '.implode(', ', $types);
}
return $postsarr;
$alldiscussionssql = "SELECT fd.id
FROM {$CFG->prefix}forum_discussions fd, {$CFG->prefix}forum f
WHERE f.course={$data->courseid} AND f.id=fd.forum";
$allforumssql = "SELECT f.id
FROM {$CFG->prefix}forum f
WHERE f.course={$data->courseid}";
$allpostssql = "SELECT fp.id
FROM {$CFG->prefix}forum_posts fp, {$CFG->prefix}forum_discussions fd, {$CFG->prefix}forum f
WHERE f.course={$data->courseid} AND f.id=fd.forum AND fd.id=fp.discussion";
if ($removeposts) {
$discussionssql = "$alldiscussionssql $typesql";
$forumssql = "$allforumssql $typesql";
$postssql = "$allpostssql $typesql";
// first delete all read flags
delete_records_select('forum_read', "forumid IN ($forumssql)");
// remove tracking prefs
delete_records_select('forum_track_prefs', "forumid IN ($forumssql)");
// remove posts from queue
delete_records_select('forum_queue', "discussionid IN ($discussionssql)");
// remove ratings
delete_records_select('forum_ratings', "post IN ($postssql)");
// all posts
delete_records_select('forum_posts', "discussion IN ($discussionssql)");
// finally all discussions
delete_records_select('forum_discussions', "forum IN ($forumssql)");
// now get rid of all attachments
if ($forums = get_records_sql($forumssql)) {
foreach ($forums as $forumid=>$unused) {
fulldelete($CFG->dataroot.'/'.$data->courseid.'/moddata/forum/'.$forumid);
}
}
// remove all grades from gradebook
if (empty($data->reset_gradebook_grades)) {
if (empty($types)) {
forum_reset_gradebook($data->courseid);
} else {
foreach ($types as $type) {
forum_reset_gradebook($data->courseid, $type);
}
}
}
$status[] = array('component'=>$componentstr, 'item'=>$typesstr, 'error'=>false);
}
// remove all ratings
if (!empty($data->reset_forum_ratings)) {
delete_records_select('forum_ratings', "post IN ($allpostssql)");
// remove all grades from gradebook
if (empty($data->reset_gradebook_grades)) {
forum_reset_gradebook($data->courseid);
}
}
// remove all subscriptions unconditionally - even for users still enrolled in course
if (!empty($data->reset_forum_subscriptions)) {
delete_records_select('forum_subscriptions', "forum IN ($allforumssql)");
$status[] = array('component'=>$componentstr, 'item'=>get_string('resetsubscriptions','forum'), 'error'=>false);
}
// remove all tracking prefs unconditionally - even for users still enrolled in course
if (!empty($data->reset_forum_track_prefs)) {
delete_records_select('forum_track_prefs', "forumid IN ($allforumssql)");
$status[] = array('component'=>$componentstr, 'item'=>get_string('resettrackprefs','forum'), 'error'=>false);
}
/// updating dates - shift may be negative too
if ($data->timeshift) {
shift_course_mod_dates('forum', array('assesstimestart', 'assesstimefinish'), $data->timeshift, $data->courseid);
$status[] = array('component'=>$componentstr, 'item'=>get_string('datechanged'), 'error'=>false);
}
return $status;
}
/**
* Called by course/reset.php
* @param $mform form passed by reference
*/
function forum_reset_course_form($course) {
echo get_string('resetforums', 'forum'); echo ':<br />';
print_checkbox('reset_forum_news', 1, true, get_string('namenews','forum'), '', ''); echo '<br />';
print_checkbox('reset_forum_single', 1, true, get_string('singleforum','forum'), '', ''); echo '<br />';
print_checkbox('reset_forum_eachuser', 1, true, get_string('eachuserforum','forum'), '', ''); echo '<br />';
print_checkbox('reset_forum_general', 1, true, get_string('generalforum','forum'), '', ''); echo '<br />';
echo '<p>';
print_checkbox('reset_forum_subscriptions', 1, true, get_string('resetsubscriptions','forum'), '', '');
echo '</p>';
function forum_reset_course_form_definition(&$mform) {
global $FORUM_TYPES_ALL;
$mform->addElement('header', 'forumheader', get_string('modulenameplural', 'forum'));
$mform->addElement('checkbox', 'reset_forum_all', get_string('resetforumsall','forum'));
$mform->addElement('select', 'reset_forum_types', get_string('resetforums', 'forum'), $FORUM_TYPES_ALL, array('multiple' => 'multiple'));
$mform->setAdvanced('reset_forum_types');
$mform->disabledIf('reset_forum_types', 'reset_forum_all', 'checked');
$mform->addElement('checkbox', 'reset_forum_subscriptions', get_string('resetsubscriptions','forum'));
$mform->setAdvanced('reset_forum_subscriptions');
$mform->addElement('checkbox', 'reset_forum_track_prefs', get_string('resettrackprefs','forum'));
$mform->setAdvanced('reset_forum_track_prefs');
$mform->disabledIf('reset_forum_track_prefs', 'reset_forum_all', 'checked');
$mform->addElement('checkbox', 'reset_forum_ratings', get_string('deleteallratings'));
$mform->disabledIf('reset_forum_ratings', 'reset_forum_all', 'checked');
}
/**
* Course reset form defaults.
*/
function forum_reset_course_form_defaults($course) {
return array('reset_forum_all'=>1, 'reset_forum_subscriptions'=>0, 'reset_forum_track_prefs'=>0, 'reset_forum_ratings'=>1);
}
/**
* Converts a forum to use the Roles System

View File

@ -373,9 +373,10 @@ function glossary_update_grades($glossary=null, $userid=0, $nullifnone=true) {
* Create/update grade item for given glossary
*
* @param object $glossary object with extra cmidnumber
* @param mixed optional array/object of grade(s); 'reset' means reset grades in gradebook
* @return int, 0 if ok, error code otherwise
*/
function glossary_grade_item_update($glossary) {
function glossary_grade_item_update($glossary, $grades=NULL) {
global $CFG;
if (!function_exists('grade_update')) { //workaround for buggy PHP versions
require_once($CFG->libdir.'/gradelib.php');
@ -396,7 +397,12 @@ function glossary_grade_item_update($glossary) {
$params['scaleid'] = -$glossary->scale;
}
return grade_update('mod/glossary', $glossary->course, 'mod', 'glossary', $glossary->id, 0, NULL, $params);
if ($grades === 'reset') {
$params['reset'] = true;
$grades = NULL;
}
return grade_update('mod/glossary', $glossary->course, 'mod', 'glossary', $glossary->id, 0, $grades, $params);
}
/**
@ -2123,4 +2129,203 @@ function glossary_get_post_actions() {
return array('add category','add comment','add entry','approve entry','delete category','delete comment','delete entry','edit category','update comment','update entry');
}
/**
* Implementation of the function for printing the form elements that control
* whether the course reset functionality affects the glossary.
* @param $mform form passed by reference
*/
function glossary_reset_course_form_definition(&$mform) {
$mform->addElement('header', 'glossaryheader', get_string('modulenameplural', 'glossary'));
$mform->addElement('checkbox', 'reset_glossary_all', get_string('resetglossariesall','glossary'));
$mform->addElement('select', 'reset_glossary_types', get_string('resetglossaries', 'glossary'),
array('main'=>get_string('mainglossary', 'glossary'), 'secondary'=>get_string('secondaryglossary', 'glossary')), array('multiple' => 'multiple'));
$mform->setAdvanced('reset_glossary_types');
$mform->disabledIf('reset_glossary_types', 'reset_glossary_all', 'checked');
$mform->addElement('checkbox', 'reset_glossary_notenrolled', get_string('deletenotenrolled', 'glossary'));
$mform->disabledIf('reset_glossary_notenrolled', 'reset_glossary_all', 'checked');
$mform->addElement('checkbox', 'reset_glossary_ratings', get_string('deleteallratings'));
$mform->disabledIf('reset_glossary_ratings', 'reset_glossary_all', 'checked');
$mform->addElement('checkbox', 'reset_glossary_comments', get_string('deleteallcomments'));
$mform->disabledIf('reset_glossary_comments', 'reset_glossary_all', 'checked');
}
/**
* Course reset form defaults.
*/
function glossary_reset_course_form_defaults($course) {
return array('reset_glossary_all'=>0, 'reset_glossary_ratings'=>1, 'reset_glossary_comments'=>1, 'reset_glossary_notenrolled'=>0);
}
/**
* Removes all grades from gradebook
* @param int $courseid
* @param string optional type
*/
function glossary_reset_gradebook($courseid, $type='') {
global $CFG;
switch ($type) {
case 'main' : $type = "AND g.mainglossary=1"; break;
case 'secondary' : $type = "AND g.mainglossary=0"; break;
default : $type = ""; //all
}
$sql = "SELECT g.*, cm.idnumber as cmidnumber, g.course as courseid
FROM {$CFG->prefix}glossary g, {$CFG->prefix}course_modules cm, {$CFG->prefix}modules m
WHERE m.name='glossary' AND m.id=cm.module AND cm.instance=g.id AND g.course=$courseid $type";
if ($glossarys = get_records_sql($sql)) {
foreach ($glossarys as $glossary) {
glossary_grade_item_update($glossary, 'reset');
}
}
}
/**
* Actual implementation of the rest coures functionality, delete all the
* glossary responses for course $data->courseid.
* @param $data the data submitted from the reset course.
* @return array status array
*/
function glossary_reset_userdata($data) {
global $CFG;
require_once($CFG->libdir.'/filelib.php');
$componentstr = get_string('modulenameplural', 'glossary');
$status = array();
$allentriessql = "SELECT e.id
FROM {$CFG->prefix}glossary_entries e
INNER JOIN {$CFG->prefix}glossary g ON e.glossaryid = g.id
WHERE g.course = {$data->courseid}";
$allglossariessql = "SELECT g.id
FROM {$CFG->prefix}glossary g
WHERE g.course={$data->courseid}";
// delete entries if requested
if (!empty($data->reset_glossary_all)
or (!empty($data->reset_glossary_types) and in_array('main', $data->reset_glossary_types) and in_array('secondary', $data->reset_glossary_types))) {
delete_records_select('glossary_ratings', "entryid IN ($allentriessql)");
delete_records_select('glossary_comments', "entryid IN ($allentriessql)");
delete_records_select('glossary_entries', "glossaryid IN ($allglossariessql)");
if ($glossaries = get_records_sql($allglossariessql)) {
foreach ($glossaries as $glossaryid=>$unused) {
fulldelete($CFG->dataroot."/$data->courseid/moddata/glossary/$glossaryid");
}
}
// remove all grades from gradebook
if (empty($data->reset_gradebook_grades)) {
glossary_reset_gradebook($data->courseid);
}
$status[] = array('component'=>$componentstr, 'item'=>get_string('resetglossariesall', 'glossary'), 'error'=>false);
} else if (!empty($data->reset_glossary_types)) {
$mainentriessql = "$allentries AND g.mainglossary=1";
$secondaryentriessql = "$allentries AND g.mainglossary=0";
$mainglossariessql = "$allglossariessql AND g.mainglossary=1";
$secondaryglossariessql = "$allglossariessql AND g.mainglossary=0";
if (in_array('main', $data->reset_glossary_types)) {
delete_records_select('glossary_ratings', "entryid IN ($mainentriessql)");
delete_records_select('glossary_comments', "entryid IN ($mainentriessql)");
delete_records_select('glossary_entries', "glossaryid IN ($mainglossariessql)");
if ($glossaries = get_records_sql($mainglossariessql)) {
foreach ($glossaries as $glossaryid=>$unused) {
fulldelete("$CFG->dataroot/$data->courseid/moddata/glossary/$glossaryid");
}
}
// remove all grades from gradebook
if (empty($data->reset_gradebook_grades)) {
glossary_reset_gradebook($data->courseid, 'main');
}
$status[] = array('component'=>$componentstr, 'item'=>get_string('resetglossaries', 'glossary'), 'error'=>false);
} else if (in_array('secondary', $data->reset_glossary_types)) {
delete_records_select('glossary_ratings', "entryid IN ($secondaryentriessql)");
delete_records_select('glossary_comments', "entryid IN ($secondaryentriessql)");
delete_records_select('glossary_entries', "glossaryid IN ($secondaryglossariessql)");
// remove exported source flag from entries in main glossary
execute_sql("UPDATE {$CFG->prefix}glossary_entries
SET sourceglossaryid=0
WHERE glossaryid IN ($mainglossariessql)", false);
if ($glossaries = get_records_sql($secondaryglossariessql)) {
foreach ($glossaries as $glossaryid=>$unused) {
fulldelete("$CFG->dataroot/$data->courseid/moddata/glossary/$glossaryid");
}
}
// remove all grades from gradebook
if (empty($data->reset_gradebook_grades)) {
glossary_reset_gradebook($data->courseid, 'secondary');
}
$status[] = array('component'=>$componentstr, 'item'=>get_string('resetglossaries', 'glossary').': '.get_string('secondaryglossary', 'glossary'), 'error'=>false);
}
}
// remove entries by users not enrolled into course
if (!empty($data->reset_glossary_notenrolled)) {
$entriessql = "SELECT e.id, e.userid, e.glossaryid, u.id AS userexists, u.deleted AS userdeleted
FROM {$CFG->prefix}glossary_entries e
INNER JOIN {$CFG->prefix}glossary g ON e.glossaryid = g.id
LEFT OUTER JOIN {$CFG->prefix}user u ON e.userid = u.id
WHERE g.course = {$data->courseid} AND e.userid > 0";
$course_context = get_context_instance(CONTEXT_COURSE, $data->courseid);
$notenrolled = array();
if ($rs = get_recordset_sql($entriessql)) {
while ($entry = rs_fetch_next_record($rs)) {
if (array_key_exists($entry->userid, $notenrolled) or !$entry->userexists or $entry->userdeleted
or !has_capability('moodle/course:view', $course_context , $entry->userid)) {
delete_records('glossary_ratings', 'entryid', $entry->id);
delete_records('glossary_comments', 'entryid', $entry->id);
delete_records('glossary_entries', 'id', $entry->id);
fulldelete("$CFG->dataroot/$data->courseid/moddata/glossary/$entry->glossaryid");
$notenrolled[$entry->userid] = true;
}
}
rs_close($rs);
$status[] = array('component'=>$componentstr, 'item'=>get_string('deletenotenrolled', 'glossary'), 'error'=>false);
}
}
// remove all ratings
if (!empty($data->reset_glossary_ratings)) {
delete_records_select('glossary_ratings', "entryid IN ($allentriessql)");
// remove all grades from gradebook
if (empty($data->reset_gradebook_grades)) {
glossary_reset_gradebook($data->courseid);
}
$status[] = array('component'=>$componentstr, 'item'=>get_string('deleteallratings'), 'error'=>false);
}
// remove all comments
if (!empty($data->reset_glossary_comments)) {
delete_records_select('glossary_comments', "entryid IN ($allentriessql)");
$status[] = array('component'=>$componentstr, 'item'=>get_string('deleteallcomments'), 'error'=>false);
}
/// updating dates - shift may be negative too
if ($data->timeshift) {
shift_course_mod_dates('glossary', array('assesstimestart', 'assesstimefinish'), $data->timeshift, $data->courseid);
$status[] = array('component'=>$componentstr, 'item'=>get_string('datechanged'), 'error'=>false);
}
return $status;
}
?>

View File

@ -99,4 +99,14 @@ function label_get_types() {
return $types;
}
/**
* This function is used by the reset_course_userdata function in moodlelib.
* @param $data the data submitted from the reset course.
* @return array status array
*/
function label_reset_userdata($data) {
return array();
}
?>

View File

@ -407,9 +407,10 @@ function lesson_update_grades($lesson=null, $userid=0, $nullifnone=true) {
* Create grade item for given lesson
*
* @param object $lesson object with extra cmidnumber
* @param mixed optional array/object of grade(s); 'reset' means reset grades in gradebook
* @return int 0 if ok, error code otherwise
*/
function lesson_grade_item_update($lesson) {
function lesson_grade_item_update($lesson, $grades=NULL) {
global $CFG;
if (!function_exists('grade_update')) { //workaround for buggy PHP versions
require_once($CFG->libdir.'/gradelib.php');
@ -432,7 +433,12 @@ function lesson_grade_item_update($lesson) {
$params['multfactor'] = 1.0;
}
return grade_update('mod/lesson', $lesson->course, 'mod', 'lesson', $lesson->id, 0, NULL, $params);
if ($grades === 'reset') {
$params['reset'] = true;
$grades = NULL;
}
return grade_update('mod/lesson', $lesson->course, 'mod', 'lesson', $lesson->id, 0, $grades, $params);
}
/**
@ -580,4 +586,81 @@ function lesson_process_post_save(&$lesson) {
}
}
/**
* Implementation of the function for printing the form elements that control
* whether the course reset functionality affects the lesson.
* @param $mform form passed by reference
*/
function lesson_reset_course_form_definition(&$mform) {
$mform->addElement('header', 'lessonheader', get_string('modulenameplural', 'lesson'));
$mform->addElement('advcheckbox', 'reset_lesson', get_string('deleteallattempts','lesson'));
}
/**
* Course reset form defaults.
*/
function lesson_reset_course_form_defaults($course) {
return array('reset_lesson'=>1);
}
/**
* Removes all grades from gradebook
* @param int $courseid
* @param string optional type
*/
function lesson_reset_gradebook($courseid, $type='') {
global $CFG;
$sql = "SELECT l.*, cm.idnumber as cmidnumber, l.course as courseid
FROM {$CFG->prefix}lesson l, {$CFG->prefix}course_modules cm, {$CFG->prefix}modules m
WHERE m.name='lesson' AND m.id=cm.module AND cm.instance=l.id AND l.course=$courseid";
if ($lessons = get_records_sql($sql)) {
foreach ($lessons as $lesson) {
lesson_grade_item_update($lesson, 'reset');
}
}
}
/**
* Actual implementation of the rest coures functionality, delete all the
* lesson attempts for course $data->courseid.
* @param $data the data submitted from the reset course.
* @return array status array
*/
function lesson_reset_userdata($data) {
global $CFG;
$componentstr = get_string('modulenameplural', 'lesson');
$status = array();
if (!empty($data->reset_lesson)) {
$lessonssql = "SELECT l.id
FROM {$CFG->prefix}lesson l
WHERE l.course={$data->courseid}";
delete_records_select('lesson_timer', "lessonid IN ($lessonssql)");
delete_records_select('lesson_high_scores', "lessonid IN ($lessonssql)");
delete_records_select('lesson_grades', "lessonid IN ($lessonssql)");
delete_records_select('lesson_attempts', "lessonid IN ($lessonssql)");
// remove all grades from gradebook
if (empty($data->reset_gradebook_grades)) {
lesson_reset_gradebook($data->courseid);
}
$status[] = array('component'=>$componentstr, 'item'=>get_string('deleteallattempts', 'lesson'), 'error'=>false);
}
/// updating dates - shift may be negative too
if ($data->timeshift) {
shift_course_mod_dates('lesson', array('available', 'deadline'), $data->timeshift, $data->courseid);
$status[] = array('component'=>$componentstr, 'item'=>get_string('datechanged'), 'error'=>false);
}
return $status;
}
?>

View File

@ -322,7 +322,7 @@ function quiz_update_grades($quiz=null, $userid=0, $nullifnone=true) {
* Create grade item for given quiz
*
* @param object $quiz object with extra cmidnumber
* @param mixed optional array/object of grade(s)
* @param mixed optional array/object of grade(s); 'reset' means reset grades in gradebook
* @return int 0 if ok, error code otherwise
*/
function quiz_grade_item_update($quiz, $grades=NULL) {
@ -370,6 +370,11 @@ function quiz_grade_item_update($quiz, $grades=NULL) {
$params['hidden'] = 0;
}
if ($grades === 'reset') {
$params['reset'] = true;
$grades = NULL;
}
return grade_update('mod/quiz', $quiz->course, 'mod', 'quiz', $quiz->id, 0, $grades, $params);
}
@ -896,12 +901,37 @@ function quiz_question_list_instances($questionid) {
/**
* Implementation of the function for printing the form elements that control
* whether the course reset functionality affects the quiz.
* @param $course The course id of the course the user is thinking of resetting.
* @param $mform form passed by reference
*/
function quiz_reset_course_form($course) {
echo '<p>';
print_checkbox('reset_quiz_attempts', 1, true, get_string('removeallquizattempts','quiz'));
echo '</p>';
function quiz_reset_course_form_definition(&$mform) {
$mform->addElement('header', 'forumheader', get_string('modulenameplural', 'quiz'));
$mform->addElement('advcheckbox', 'reset_quiz_attempts', get_string('removeallquizattempts','quiz'));
}
/**
* Course reset form defaults.
*/
function quiz_reset_course_form_defaults($course) {
return array('reset_quiz_attempts'=>1);
}
/**
* Removes all grades from gradebook
* @param int $courseid
* @param string optional type
*/
function quiz_reset_gradebook($courseid, $type='') {
global $CFG;
$sql = "SELECT q.*, cm.idnumber as cmidnumber, q.course as courseid
FROM {$CFG->prefix}quiz q, {$CFG->prefix}course_modules cm, {$CFG->prefix}modules m
WHERE m.name='quiz' AND m.id=cm.module AND cm.instance=q.id AND q.course=$courseid";
if ($quizs = get_records_sql($sql)) {
foreach ($quizs as $quiz) {
quiz_grade_item_update($quiz, 'reset');
}
}
}
/**
@ -910,73 +940,63 @@ function quiz_reset_course_form($course) {
* set and true.
*
* Also, move the quiz open and close dates, if the course start date is changing.
*
* @param $data the data submitted from the reset course forum.
* @param $showfeedback whether to output progress information as the reset
* progresses.
* @param $data the data submitted from the reset course.
* @return array status array
*/
function quiz_delete_userdata($data, $showfeedback=true) {
global $CFG;
function quiz_reset_userdata($data) {
global $CFG, $QTYPES;
$componentstr = get_string('modulenameplural', 'quiz');
$status = array();
/// Delete attempts.
if (!empty($data->reset_quiz_attempts)) {
$conditiononquizids = 'quiz IN (SELECT id FROM ' .
$CFG->prefix . 'quiz q WHERE q.course = ' . $data->courseid . ')';
$attemptids = get_records_select('quiz_attempts', $conditiononquizids, '', 'id, uniqueid');
if ($attemptids) {
if ($showfeedback) {
echo '<div class="notifysuccess">', get_string('deletingquestionattempts', 'quiz');
$divider = ': ';
}
foreach ($attemptids as $attemptid) {
delete_attempt($attemptid->uniqueid);
if ($showfeedback) {
echo $divider, $attemptid->uniqueid;
$divider = ', ';
}
}
if ($showfeedback) {
echo "</div><br />\n";
$stateslistsql = "SELECT s.id
FROM {$CFG->prefix}question_states s
INNER JOIN {$CFG->prefix}quiz_attempts qza ON s.attempt=qza.uniqueid
INNER JOIN {$CFG->prefix}quiz q ON qza.quiz=q.id
WHERE q.course={$data->courseid}";
$attemptssql = "SELECT a.uniqueid
FROM {$CFG->prefix}quiz_attempts a, {$CFG->prefix}quiz q
WHERE q.course={$data->courseid} AND a.quiz=q.id";
$quizessql = "SELECT q.id
FROM {$CFG->prefix}quiz q
WHERE q.course={$data->courseid}";
if ($states = get_records_sql($stateslistsql)) {
//TODO: not sure if this works
$stateslist = implode(',', array_keys($states));
foreach ($QTYPES as $qtype) {
$qtype->delete_states($stateslist);
}
}
if (delete_records_select('quiz_grades', $conditiononquizids) && $showfeedback) {
notify(get_string('gradesdeleted','quiz'), 'notifysuccess');
}
if (delete_records_select('quiz_attempts', $conditiononquizids) && $showfeedback) {
notify(get_string('attemptsdeleted','quiz'), 'notifysuccess');
delete_records_select('question_states', "attempt IN ($attemptssql)");
delete_records_select('question_sessions', "attemptid IN ($attemptssql)");
delete_records_select('question_attempts', "id IN ($attemptssql)");
// remove all grades from gradebook
if (empty($data->reset_gradebook_grades)) {
quiz_reset_gradebook($data->courseid);
}
delete_records_select('quiz_grades', "quiz IN ($quizessql)");
$status[] = array('component'=>$componentstr, 'item'=>get_string('gradesdeleted','quiz'), 'error'=>false);
delete_records_select('quiz_attempts', "quiz IN ($quizessql)");
$status[] = array('component'=>$componentstr, 'item'=>get_string('attemptsdeleted','quiz'), 'error'=>false);
}
/// Update open and close dates
if (!empty($data->reset_start_date)) {
/// Work out offset.
$olddate = get_field('course', 'startdate', 'id', $data->courseid);
$olddate = usergetmidnight($olddate); // time part of $olddate should be zero
$newdate = make_timestamp($data->startyear, $data->startmonth, $data->startday);
$interval = $newdate - $olddate;
/// Apply it to quizzes with an open or close date.
$success = true;
begin_sql();
$success = $success && execute_sql(
"UPDATE {$CFG->prefix}quiz
SET timeopen = timeopen + $interval
WHERE course = {$data->courseid} AND timeopen <> 0", false);
$success = $success && execute_sql(
"UPDATE {$CFG->prefix}quiz
SET timeclose = timeclose + $interval
WHERE course = {$data->courseid} AND timeclose <> 0", false);
if ($success) {
commit_sql();
if ($showfeedback) {
notify(get_string('openclosedatesupdated', 'quiz'), 'notifysuccess');
}
} else {
rollback_sql();
}
/// updating dates - shift may be negative too
if ($data->timeshift) {
shift_course_mod_dates('quiz', array('timeopen', 'timeclose'), $data->timeshift, $data->courseid);
$status[] = array('component'=>$componentstr, 'item'=>get_string('openclosedatesupdated', 'quiz'), 'error'=>false);
}
return $status;
}
/**

View File

@ -667,4 +667,12 @@ function resource_delete_warning($course, $files) {
}
}
/**
* This function is used by the reset_course_userdata function in moodlelib.
* @param $data the data submitted from the reset course.
* @return array status array
*/
function resource_reset_userdata($data) {
return array();
}
?>

View File

@ -488,9 +488,10 @@ function scorm_update_grades($scorm=null, $userid=0, $nullifnone=true) {
* Update/create grade item for given scorm
*
* @param object $scorm object with extra cmidnumber
* @param mixed optional array/object of grade(s); 'reset' means reset grades in gradebook
* @return object grade_item
*/
function scorm_grade_item_update($scorm) {
function scorm_grade_item_update($scorm, $grades=NULL) {
global $CFG;
if (!function_exists('grade_update')) { //workaround for buggy PHP versions
require_once($CFG->libdir.'/gradelib.php');
@ -512,7 +513,12 @@ function scorm_grade_item_update($scorm) {
$params['grademin'] = 0;
}
return grade_update('mod/scorm', $scorm->course, 'mod', 'scorm', $scorm->id, 0, NULL, $params);
if ($grades === 'reset') {
$params['reset'] = true;
$grades = NULL;
}
return grade_update('mod/scorm', $scorm->course, 'mod', 'scorm', $scorm->id, 0, $grades, $params);
}
/**
@ -559,4 +565,72 @@ function scorm_option2text($scorm) {
return $scorm;
}
/**
* Implementation of the function for printing the form elements that control
* whether the course reset functionality affects the scorm.
* @param $mform form passed by reference
*/
function scorm_reset_course_form_definition(&$mform) {
$mform->addElement('header', 'scormheader', get_string('modulenameplural', 'scorm'));
$mform->addElement('advcheckbox', 'reset_scorm', get_string('deleteallattempts','scorm'));
}
/**
* Course reset form defaults.
*/
function scorm_reset_course_form_defaults($course) {
return array('reset_scorm'=>1);
}
/**
* Removes all grades from gradebook
* @param int $courseid
* @param string optional type
*/
function scorm_reset_gradebook($courseid, $type='') {
global $CFG;
$sql = "SELECT s.*, cm.idnumber as cmidnumber, s.course as courseid
FROM {$CFG->prefix}scorm s, {$CFG->prefix}course_modules cm, {$CFG->prefix}modules m
WHERE m.name='scorm' AND m.id=cm.module AND cm.instance=s.id AND s.course=$courseid";
if ($scorms = get_records_sql($sql)) {
foreach ($scorms as $scorm) {
scorm_grade_item_update($scorm, 'reset');
}
}
}
/**
* Actual implementation of the rest coures functionality, delete all the
* scorm attempts for course $data->courseid.
* @param $data the data submitted from the reset course.
* @return array status array
*/
function scorm_reset_userdata($data) {
global $CFG;
$componentstr = get_string('modulenameplural', 'scorm');
$status = array();
if (!empty($data->reset_scorm)) {
$scormssql = "SELECT s.id
FROM {$CFG->prefix}scorm s
WHERE s.course={$data->courseid}";
delete_records_select('scorm_scoes_track', "scormid IN ($scormssql)");
// remove all grades from gradebook
if (empty($data->reset_gradebook_grades)) {
scorm_reset_gradebook($data->courseid);
}
$status[] = array('component'=>$componentstr, 'item'=>get_string('deleteallattempts', 'scorm'), 'error'=>false);
}
// no dates to shift here
return $status;
}
?>

View File

@ -510,4 +510,55 @@ function survey_get_post_actions() {
return array('submit');
}
/**
* Implementation of the function for printing the form elements that control
* whether the course reset functionality affects the survey.
* @param $mform form passed by reference
*/
function survey_reset_course_form_definition(&$mform) {
$mform->addElement('header', 'surveyheader', get_string('modulenameplural', 'survey'));
$mform->addElement('checkbox', 'reset_survey_answers', get_string('deleteallanswers','survey'));
$mform->addElement('checkbox', 'reset_survey_analysis', get_string('deleteanalysis','survey'));
$mform->disabledIf('reset_survey_analysis', 'reset_survey_answers', 'checked');
}
/**
* Course reset form defaults.
*/
function survey_reset_course_form_defaults($course) {
return array('reset_survey_answers'=>1, 'reset_survey_analysis'=>1);
}
/**
* Actual implementation of the rest coures functionality, delete all the
* survey responses for course $data->courseid.
* @param $data the data submitted from the reset course.
* @return array status array
*/
function survey_reset_userdata($data) {
global $CFG;
$componentstr = get_string('modulenameplural', 'survey');
$status = array();
$surveyssql = "SELECT ch.id
FROM {$CFG->prefix}survey ch
WHERE ch.course={$data->courseid}";
if (!empty($data->reset_survey_answers)) {
delete_records_select('survey_answers', "survey IN ($surveyssql)");
delete_records_select('survey_analysis', "survey IN ($surveyssql)");
$status[] = array('component'=>$componentstr, 'item'=>get_string('deleteallanswers', 'survey'), 'error'=>false);
}
if (!empty($data->reset_survey_analysis)) {
delete_records_select('survey_analysis', "survey IN ($surveyssql)");
$status[] = array('component'=>$componentstr, 'item'=>get_string('deleteallanswers', 'survey'), 'error'=>false);
}
// no date shifting
return $status;
}
?>

View File

@ -254,4 +254,12 @@ function note_print_notes($header, $addcourseid = 0, $viewnotes = true, $coursei
}
}
/**
* Delete all notes about users in course-
* @param int $courseid
* @return bool success
*/
function note_delete_all($courseid) {
return delete_records('post', 'module', 'notes', 'courseid', $courseid);
}
?>