From 84a8492a02e4ad14a85a0ce9298e3c107d49486d Mon Sep 17 00:00:00 2001 From: Matt Switlik Date: Wed, 1 Aug 2012 16:40:34 -0400 Subject: [PATCH 01/95] MDL-34691 assign: Time remaining "Assignment is overdue" was incorrectly being displayed when a student viewed a submitted assignment after the due date. --- mod/assign/renderer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mod/assign/renderer.php b/mod/assign/renderer.php index 8ffe18f27e4..3ca0232f515 100644 --- a/mod/assign/renderer.php +++ b/mod/assign/renderer.php @@ -420,7 +420,7 @@ class mod_assign_renderer extends plugin_renderer_base { $row = new html_table_row(); $cell1 = new html_table_cell(get_string('timeremaining', 'assign')); if ($duedate - $time <= 0) { - if (!$status->submission || $status->submission != ASSIGN_SUBMISSION_STATUS_SUBMITTED) { + if (!$status->submission || $status->submission->status != ASSIGN_SUBMISSION_STATUS_SUBMITTED) { if ($status->submissionsenabled) { $cell2 = new html_table_cell(get_string('overdue', 'assign', format_time($time - $duedate))); $cell2->attributes = array('class'=>'overdue'); From 66b23db417f5d8d52c3af9f2952ecbcd64f57a35 Mon Sep 17 00:00:00 2001 From: Aaron Barnes Date: Fri, 10 Aug 2012 16:05:35 +1200 Subject: [PATCH 02/95] MDL-34795 completion: Add course_completed event --- completion/completion_completion.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/completion/completion_completion.php b/completion/completion_completion.php index e8e80197bdf..dab34d8b453 100644 --- a/completion/completion_completion.php +++ b/completion/completion_completion.php @@ -158,7 +158,11 @@ class completion_completion extends data_object { $this->timecompleted = $timecomplete; // Save record - return $this->_save(); + if ($result = $this->_save()) { + events_trigger('course_completed', $this->get_record_data()); + } + + return $result; } /** From 79e250dbdcc2ddebdf7c2816f10494ae277ff3de Mon Sep 17 00:00:00 2001 From: Rex Lorenzo Date: Mon, 13 Aug 2012 16:24:12 -0700 Subject: [PATCH 03/95] MDL-34866 - Make "course display" default a site configurable option --- admin/settings/courses.php | 5 +++++ course/edit_form.php | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/admin/settings/courses.php b/admin/settings/courses.php index 92722eb082f..277501fa0a0 100644 --- a/admin/settings/courses.php +++ b/admin/settings/courses.php @@ -47,6 +47,11 @@ if ($hassiteconfig $temp->add(new admin_setting_configselect('moodlecourse/legacyfiles', new lang_string('courselegacyfiles'), new lang_string('courselegacyfiles_help'), key($choices), $choices)); } + $choices = array(); + $choices[0] = new lang_string('coursedisplay_single'); + $choices[1] = new lang_string('coursedisplay_multi'); + $temp->add(new admin_setting_configselect('moodlecourse/coursedisplay', new lang_string('coursedisplay'), new lang_string('coursedisplay_help'), 0, $choices)); + $temp->add(new admin_setting_heading('groups', new lang_string('groups', 'group'), '')); $choices = array(); $choices[NOGROUPS] = new lang_string('groupsnone', 'group'); diff --git a/course/edit_form.php b/course/edit_form.php index be69a6ff377..355e790efa6 100644 --- a/course/edit_form.php +++ b/course/edit_form.php @@ -124,7 +124,7 @@ class course_edit_form extends moodleform { array(COURSE_DISPLAY_SINGLEPAGE => get_string('coursedisplay_single'), COURSE_DISPLAY_MULTIPAGE => get_string('coursedisplay_multi'))); $mform->addHelpButton('coursedisplay', 'coursedisplay'); - $mform->setDefault('coursedisplay', COURSE_DISPLAY_SINGLEPAGE); + $mform->setDefault('coursedisplay', $courseconfig->coursedisplay); for ($i = 0; $i <= $courseconfig->maxsections; $i++) { $sectionmenu[$i] = "$i"; From daaf84ec44687ac94a30b69ef0357527679b8a49 Mon Sep 17 00:00:00 2001 From: Rajesh Taneja Date: Tue, 31 Jul 2012 11:46:53 +0800 Subject: [PATCH 04/95] MDL-32759 Assignment 2.2: Changing grade for existing assignments will show warning that grades will not be scaled --- mod/assignment/assignment.js | 12 ++++++++++++ mod/assignment/lang/en/assignment.php | 1 + mod/assignment/mod_form.php | 17 ++++++++++++++++- 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/mod/assignment/assignment.js b/mod/assignment/assignment.js index 8615c4bd466..8a5844087d5 100644 --- a/mod/assignment/assignment.js +++ b/mod/assignment/assignment.js @@ -35,3 +35,15 @@ M.mod_assignment.init_tree = function(Y, expand_all, htmlid) { tree.render(); }); }; + +M.mod_assignment.init_grade_change = function(Y) { + var gradenode = Y.one('#id_grade'); + if (gradenode) { + var originalvalue = gradenode.get('value'); + gradenode.on('change', function() { + if (gradenode.get('value') != originalvalue) { + alert(M.str.mod_assignment.changegradewarning); + } + }); + } +}; \ No newline at end of file diff --git a/mod/assignment/lang/en/assignment.php b/mod/assignment/lang/en/assignment.php index 98ec8f4ec09..7aef1ae676d 100644 --- a/mod/assignment/lang/en/assignment.php +++ b/mod/assignment/lang/en/assignment.php @@ -57,6 +57,7 @@ $string['assignment:view'] = 'View assignment'; $string['availabledate'] = 'Available from'; $string['cannotdeletefiles'] = 'An error occurred and files could not be deleted'; $string['cannotviewassignment'] = 'You can not view this assignment'; +$string['changegradewarning'] = 'This assignment has graded submissions and changing the grade will not automatically re-calculate existing submission grades. You must re-grade all existing submissions, if you wish to change the grade.'; $string['comment'] = 'Comment'; $string['commentinline'] = 'Comment inline'; $string['commentinline_help'] = 'If enabled, the submission text will be copied into the feedback comment field during grading, making it easier to comment inline (using a different colour, perhaps) or to edit the original text.'; diff --git a/mod/assignment/mod_form.php b/mod/assignment/mod_form.php index 85c84238a1f..56b407d6ea6 100644 --- a/mod/assignment/mod_form.php +++ b/mod/assignment/mod_form.php @@ -9,7 +9,7 @@ class mod_assignment_mod_form extends moodleform_mod { protected $_assignmentinstance = null; function definition() { - global $CFG, $DB; + global $CFG, $DB, $PAGE; $mform =& $this->_form; // this hack is needed for different settings of each subtype @@ -76,6 +76,21 @@ class mod_assignment_mod_form extends moodleform_mod { $this->standard_coursemodule_elements(); $this->add_action_buttons(); + + // Add warning popup/noscript tag, if grades are changed by user. + if ($mform->elementExists('grade') && !empty($this->_instance) && $DB->record_exists_select('assignment_submissions', 'assignment = ? AND grade <> -1', array($this->_instance))) { + $module = array( + 'name' => 'mod_assignment', + 'fullpath' => '/mod/assignment/assignment.js', + 'requires' => array('node', 'event'), + 'strings' => array(array('changegradewarning', 'mod_assignment')) + ); + $PAGE->requires->js_init_call('M.mod_assignment.init_grade_change', null, false, $module); + + // Add noscript tag in case + $noscriptwarning = $mform->createElement('static', 'warning', null, html_writer::tag('noscript', get_string('changegradewarning', 'mod_assignment'))); + $mform->insertElementBefore($noscriptwarning, 'grade'); + } } // Needed by plugin assignment types if they include a filemanager element in the settings form From dea75f643d797bed90d43fff91e49bb839502648 Mon Sep 17 00:00:00 2001 From: Rajesh Taneja Date: Tue, 31 Jul 2012 12:04:37 +0800 Subject: [PATCH 05/95] MDL-32759 Assignment: Grades will not be scaled for new assignment module, and added warning message for user --- lib/grade/grade_item.php | 3 ++- mod/assign/lang/en/assign.php | 1 + mod/assign/mod_form.php | 17 ++++++++++++++++- mod/assign/module.js | 12 ++++++++++++ 4 files changed, 31 insertions(+), 2 deletions(-) diff --git a/lib/grade/grade_item.php b/lib/grade/grade_item.php index 8b1d3122f08..12afe84e393 100644 --- a/lib/grade/grade_item.php +++ b/lib/grade/grade_item.php @@ -742,7 +742,8 @@ class grade_item extends grade_object { // Standardise score to the new grade range // NOTE: this is not compatible with current assignment grading - if ($this->itemmodule != 'assignment' and ($rawmin != $this->grademin or $rawmax != $this->grademax)) { + $isassignmentmodule = ($this->itemmodule == 'assignment') || ($this->itemmodule == 'assign'); + if (!$isassignmentmodule && ($rawmin != $this->grademin or $rawmax != $this->grademax)) { $rawgrade = grade_grade::standardise_score($rawgrade, $rawmin, $rawmax, $this->grademin, $this->grademax); } diff --git a/mod/assign/lang/en/assign.php b/mod/assign/lang/en/assign.php index 9ab4132b561..5550348b17f 100644 --- a/mod/assign/lang/en/assign.php +++ b/mod/assign/lang/en/assign.php @@ -65,6 +65,7 @@ $string['batchoperationconfirmreverttodraft'] = 'Revert selected submissions to $string['batchoperationlock'] = 'lock submissions'; $string['batchoperationunlock'] = 'unlock submissions'; $string['batchoperationreverttodraft'] = 'revert submissions to draft'; +$string['changegradewarning'] = 'This assignment has graded submissions and changing the grade will not automatically re-calculate existing submission grades. You must re-grade all existing submissions, if you wish to change the grade.'; $string['comment'] = 'Comment'; $string['conversionexception'] = 'Could not convert assignment. Exception was: {$a}.'; $string['configshowrecentsubmissions'] = 'Everyone can see notifications of submissions in recent activity reports.'; diff --git a/mod/assign/mod_form.php b/mod/assign/mod_form.php index afc94848644..16a20b87be9 100644 --- a/mod/assign/mod_form.php +++ b/mod/assign/mod_form.php @@ -45,7 +45,7 @@ class mod_assign_mod_form extends moodleform_mod { * @return void */ function definition() { - global $CFG, $DB; + global $CFG, $DB, $PAGE; $mform = $this->_form; $mform->addElement('header', 'general', get_string('general', 'form')); @@ -120,6 +120,21 @@ class mod_assign_mod_form extends moodleform_mod { $this->standard_coursemodule_elements(); $this->add_action_buttons(); + + // Add warning popup/noscript tag, if grades are changed by user. + if ($mform->elementExists('grade') && !empty($this->_instance) && $DB->record_exists_select('assign_grades', 'assignment = ? AND grade <> -1', array($this->_instance))) { + $module = array( + 'name' => 'mod_assign', + 'fullpath' => '/mod/assign/module.js', + 'requires' => array('node', 'event'), + 'strings' => array(array('changegradewarning', 'mod_assign')) + ); + $PAGE->requires->js_init_call('M.mod_assign.init_grade_change', null, false, $module); + + // Add noscript tag in case + $noscriptwarning = $mform->createElement('static', 'warning', null, html_writer::tag('noscript', get_string('changegradewarning', 'mod_assign'))); + $mform->insertElementBefore($noscriptwarning, 'grade'); + } } /** diff --git a/mod/assign/module.js b/mod/assign/module.js index d01c9b30318..a1cbe079237 100644 --- a/mod/assign/module.js +++ b/mod/assign/module.js @@ -127,4 +127,16 @@ M.mod_assign.init_grading_options = function(Y) { }); } }); +}; + +M.mod_assign.init_grade_change = function(Y) { + var gradenode = Y.one('#id_grade'); + if (gradenode) { + var originalvalue = gradenode.get('value'); + gradenode.on('change', function() { + if (gradenode.get('value') != originalvalue) { + alert(M.str.mod_assign.changegradewarning); + } + }); + } }; \ No newline at end of file From 238a7b3ae07e7ccecdad9958851e5ec0639be397 Mon Sep 17 00:00:00 2001 From: Adam Olley Date: Tue, 14 Aug 2012 13:18:21 +0930 Subject: [PATCH 06/95] MDL-34870: Prevent cohort enrol sync when updating course record --- enrol/cohort/lib.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/enrol/cohort/lib.php b/enrol/cohort/lib.php index 9f986f9e238..c69f5e0d2ac 100644 --- a/enrol/cohort/lib.php +++ b/enrol/cohort/lib.php @@ -124,9 +124,7 @@ class enrol_cohort_plugin extends enrol_plugin { global $CFG; if (!$inserted) { - // sync cohort enrols - require_once("$CFG->dirroot/enrol/cohort/locallib.php"); - enrol_cohort_sync($course->id); + // Let's not sync cohorts anytime a course is updated... } else { // cohorts are never inserted automatically } From 194ab42205dd0850d0dd2c8cc71a2724460cbd2f Mon Sep 17 00:00:00 2001 From: Ankit Agarwal Date: Tue, 14 Aug 2012 14:41:00 +0800 Subject: [PATCH 07/95] MDL-34535 message: userto should use is_number instead of is_init --- lib/messagelib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/messagelib.php b/lib/messagelib.php index b184f0dafa0..140ae0e4f12 100644 --- a/lib/messagelib.php +++ b/lib/messagelib.php @@ -60,7 +60,7 @@ function message_send($eventdata) { //TODO: we need to solve problems with database transactions here somehow, for now we just prevent transactions - sorry $DB->transactions_forbidden(); - if (is_int($eventdata->userto)) { + if (is_number($eventdata->userto)) { $eventdata->userto = $DB->get_record('user', array('id' => $eventdata->userto)); } if (is_int($eventdata->userfrom)) { From 928928490db086a5b38c133f840e52a8c70470ac Mon Sep 17 00:00:00 2001 From: Frederic Massart Date: Tue, 14 Aug 2012 17:28:31 +0800 Subject: [PATCH 08/95] MDL-34872 Backup: Backup does not fail when a user is deleted --- backup/moodle2/backup_stepslib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backup/moodle2/backup_stepslib.php b/backup/moodle2/backup_stepslib.php index 24d7da9b77c..78c0a45122c 100644 --- a/backup/moodle2/backup_stepslib.php +++ b/backup/moodle2/backup_stepslib.php @@ -1835,7 +1835,7 @@ class backup_annotate_all_user_files extends backup_execution_step { 'backupid' => $this->get_backupid(), 'itemname' => 'userfinal')); foreach ($rs as $record) { $userid = $record->itemid; - $userctx = context_user::instance($userid); + $userctx = context_user::instance($userid, IGNORE_MISSING); if (!$userctx) { continue; // User has not context, sure it's a deleted user, so cannot have files } From 1f09018af7e287cbe7b55d4da435c1d4718bbaec Mon Sep 17 00:00:00 2001 From: Rex Lorenzo Date: Tue, 14 Aug 2012 12:12:14 -0700 Subject: [PATCH 09/95] MDL-34866 - Make "course display" default a site configurable option * Moved COURSE_DISPLAY_SINGLEPAGE and COURSE_DISPLAY_MULTIPAGE constants from courselib to moodlelib.php * Using course display constants in course default admin setting page --- admin/settings/courses.php | 6 +++--- course/lib.php | 3 --- lib/moodlelib.php | 6 ++++++ 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/admin/settings/courses.php b/admin/settings/courses.php index 277501fa0a0..01b37a26225 100644 --- a/admin/settings/courses.php +++ b/admin/settings/courses.php @@ -48,9 +48,9 @@ if ($hassiteconfig } $choices = array(); - $choices[0] = new lang_string('coursedisplay_single'); - $choices[1] = new lang_string('coursedisplay_multi'); - $temp->add(new admin_setting_configselect('moodlecourse/coursedisplay', new lang_string('coursedisplay'), new lang_string('coursedisplay_help'), 0, $choices)); + $choices[COURSE_DISPLAY_SINGLEPAGE] = new lang_string('coursedisplay_single'); + $choices[COURSE_DISPLAY_MULTIPAGE] = new lang_string('coursedisplay_multi'); + $temp->add(new admin_setting_configselect('moodlecourse/coursedisplay', new lang_string('coursedisplay'), new lang_string('coursedisplay_help'), COURSE_DISPLAY_SINGLEPAGE, $choices)); $temp->add(new admin_setting_heading('groups', new lang_string('groups', 'group'), '')); $choices = array(); diff --git a/course/lib.php b/course/lib.php index 06fb241774c..75cc734e453 100644 --- a/course/lib.php +++ b/course/lib.php @@ -47,9 +47,6 @@ define('FIRSTUSEDEXCELROW', 3); define('MOD_CLASS_ACTIVITY', 0); define('MOD_CLASS_RESOURCE', 1); -define('COURSE_DISPLAY_SINGLEPAGE', 0); // display all sections on one page -define('COURSE_DISPLAY_MULTIPAGE', 1); // split pages into a page per section - function make_log_url($module, $url) { switch ($module) { case 'course': diff --git a/lib/moodlelib.php b/lib/moodlelib.php index 313f92f35de..c23f89d3984 100644 --- a/lib/moodlelib.php +++ b/lib/moodlelib.php @@ -485,6 +485,12 @@ define('MOODLE_OFFICIAL_MOBILE_SERVICE', 'moodle_mobile_app'); */ define('USER_CAN_IGNORE_FILE_SIZE_LIMITS', -1); +/** + * Course display settings + */ +define('COURSE_DISPLAY_SINGLEPAGE', 0); // display all sections on one page +define('COURSE_DISPLAY_MULTIPAGE', 1); // split pages into a page per section + /// PARAMETER HANDLING //////////////////////////////////////////////////// /** From ce7382c959db554eccf7d00a8cbcbfdd2760cd49 Mon Sep 17 00:00:00 2001 From: David Monllao Date: Wed, 15 Aug 2012 16:56:06 +0800 Subject: [PATCH 10/95] MDL-30370 mod_forum - Removing duplicate seleted field in the DB query MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Credit to Iñigo Zendegi --- mod/forum/lib.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mod/forum/lib.php b/mod/forum/lib.php index 921465cd795..995226a2d22 100644 --- a/mod/forum/lib.php +++ b/mod/forum/lib.php @@ -2090,8 +2090,7 @@ function forum_search_posts($searchterms, $courseid=0, $limitfrom=0, $limitnum=5 u.lastname, u.email, u.picture, - u.imagealt, - u.email + u.imagealt FROM $fromsql WHERE $selectsql ORDER BY p.modified DESC"; From b2e7db07fc7a8a76de54c05c1afdc09c3191949b Mon Sep 17 00:00:00 2001 From: Jason Fowler Date: Thu, 16 Aug 2012 10:37:37 +0800 Subject: [PATCH 11/95] MDL-31810 - Fixing unclosed DIV tags throughout Moodle --- report/stats/locallib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/report/stats/locallib.php b/report/stats/locallib.php index d576fd71129..c144bbfcf83 100644 --- a/report/stats/locallib.php +++ b/report/stats/locallib.php @@ -197,7 +197,7 @@ function report_stats_report($course, $report, $mode, $user, $roleid, $time) { echo "(".get_string("gdneed").")"; } else { if ($mode == STATS_MODE_DETAILED) { - echo '
'.get_string('statisticsgraph').''.get_string('statisticsgraph').'
'; } else { echo '
'.get_string('statisticsgraph').'
'; } From 2609ae6f041ad22d6ebdccf84b4557367e199433 Mon Sep 17 00:00:00 2001 From: Ankit Agarwal Date: Thu, 16 Aug 2012 11:58:26 +0800 Subject: [PATCH 12/95] MDL-33362 book: Parse links to book modules from 1.9 backups --- mod/book/backup/moodle2/restore_book_activity_task.class.php | 3 +++ mod/book/version.php | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/mod/book/backup/moodle2/restore_book_activity_task.class.php b/mod/book/backup/moodle2/restore_book_activity_task.class.php index da1b75f94d4..d9ee50e1448 100644 --- a/mod/book/backup/moodle2/restore_book_activity_task.class.php +++ b/mod/book/backup/moodle2/restore_book_activity_task.class.php @@ -82,6 +82,9 @@ class restore_book_activity_task extends restore_activity_task { $rules[] = new restore_decode_rule('BOOKVIEWBYB', '/mod/book/view.php?b=$1', 'book'); $rules[] = new restore_decode_rule('BOOKVIEWBYBCH', '/mod/book/view.php?b=$1&chapterid=$2', array('book', 'book_chapter')); + // Convert old book links MDL-33362 + $rules[] = new restore_decode_rule('BOOKSTART', '/mod/book/view.php?id=$1', 'course_module'); + return $rules; } diff --git a/mod/book/version.php b/mod/book/version.php index cc4ad8f4acc..edbbd9dae23 100644 --- a/mod/book/version.php +++ b/mod/book/version.php @@ -25,6 +25,6 @@ defined('MOODLE_INTERNAL') || die; $module->component = 'mod_book'; // Full name of the plugin (used for diagnostics) -$module->version = 2012061700; // The current module version (Date: YYYYMMDDXX) +$module->version = 2012081600; // The current module version (Date: YYYYMMDDXX) $module->requires = 2012061700; // Requires this Moodle version $module->cron = 0; // Period for cron to check this module (secs) From 9da954c0b69d702d4f6fc9f831a6194e46879b2f Mon Sep 17 00:00:00 2001 From: Raymond Wijaya Date: Thu, 16 Aug 2012 14:31:39 +0800 Subject: [PATCH 13/95] MDL-34377: Fix: assignments overview page shows a unset due date as Epoch and counts draft submissions --- mod/assign/index.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/mod/assign/index.php b/mod/assign/index.php index cde25a421db..b90c8ac3018 100644 --- a/mod/assign/index.php +++ b/mod/assign/index.php @@ -56,8 +56,13 @@ foreach ($assignments as $assignment) { $cm = get_coursemodule_from_instance('assign', $assignment->id, 0, false, MUST_EXIST); $link = html_writer::link(new moodle_url('/mod/assign/view.php', array('id' => $cm->id)), $assignment->name); - $date = userdate($assignment->duedate); - $submissions = $DB->count_records('assign_submission', array('assignment'=>$cm->instance)); + $date = '-'; + if (!empty($assignment->duedate)) { + $date = userdate($assignment->duedate); + } + + $params = array('assignment'=>$cm->instance, 'status'=>ASSIGN_SUBMISSION_STATUS_SUBMITTED); + $submissions = $DB->count_records('assign_submission', $params); $row = array($link, $date, $submissions); $table->data[] = $row; From 2ec325c2520e77523241e52b0dc47ed085574a1d Mon Sep 17 00:00:00 2001 From: Tim Hunt Date: Mon, 13 Aug 2012 18:55:09 +0100 Subject: [PATCH 14/95] MDL-29847 question preview: garbage collect old preview data. This adds cron code which looks for question previews that have not been touched for more than 24 hours, and deletes them. We try to delete previews immediately. For example if the user clicks start again, then we immediately delete their previous preview. However, we can't do that if they just close the preview window. Hence we need some cron code to clean up old preview that have got left lying around. Normally, this code will not have much to do, so it will be very fast, so we can afford to run it every cron. This has been implemented in such a way that in future it will be easy to add other cron code to the question bank. Sadly, to make this work on MySQL, we require a horrible hack in the already hacky delete_usage_records_for_mysql function. --- lib/cronlib.php | 7 +++++++ question/engine/bank.php | 11 +++++++++++ question/engine/datalib.php | 10 +++++++++- question/previewlib.php | 27 +++++++++++++++++++++++++++ 4 files changed, 54 insertions(+), 1 deletion(-) diff --git a/lib/cronlib.php b/lib/cronlib.php index 7ec99e5c0f0..457336af0c9 100644 --- a/lib/cronlib.php +++ b/lib/cronlib.php @@ -373,6 +373,13 @@ function cron_run() { } + // Run question bank clean-up. + mtrace("Starting the question bank cron...", ''); + require_once($CFG->libdir . '/questionlib.php'); + question_bank::cron(); + mtrace('done.'); + + //Run registration updated cron mtrace(get_string('siteupdatesstart', 'hub')); require_once($CFG->dirroot . '/' . $CFG->admin . '/registration/lib.php'); diff --git a/question/engine/bank.php b/question/engine/bank.php index 2864f048af9..29277eedec9 100644 --- a/question/engine/bank.php +++ b/question/engine/bank.php @@ -398,6 +398,17 @@ abstract class question_bank { self::ensure_fraction_options_initialised(); return self::$fractionoptionsfull; } + + /** + * Perform scheduled maintenance tasks relating to the question bank. + */ + public static function cron() { + global $CFG; + + // Delete any old question preview that got left in the database. + require_once($CFG->dirroot . '/question/previewlib.php'); + question_preview_cron(); + } } diff --git a/question/engine/datalib.php b/question/engine/datalib.php index 667b78eb32f..b79fe5e45e8 100644 --- a/question/engine/datalib.php +++ b/question/engine/datalib.php @@ -758,6 +758,14 @@ ORDER BY * @param qubaid_condition $qubaids identifies which question useages to delete. */ protected function delete_usage_records_for_mysql(qubaid_condition $qubaids) { + $qubaidtest = $qubaids->usage_id_in(); + if (strpos($qubaidtest, 'question_usages') !== false && + strpos($qubaidtest, 'IN (SELECT') === 0) { + // This horrible hack is required by MDL-29847. It comes from + // http://www.xaprb.com/blog/2006/06/23/how-to-select-from-an-update-target-in-mysql/ + $qubaidtest = 'IN (SELECT * FROM ' . substr($qubaidtest, 3) . ' AS hack_subquery_alias)'; + } + // TODO once MDL-29589 is fixed, eliminate this method, and instead use the new $DB API. $this->db->execute(' DELETE qu, qa, qas, qasd @@ -765,7 +773,7 @@ ORDER BY JOIN {question_attempts} qa ON qa.questionusageid = qu.id LEFT JOIN {question_attempt_steps} qas ON qas.questionattemptid = qa.id LEFT JOIN {question_attempt_step_data} qasd ON qasd.attemptstepid = qas.id - WHERE qu.id ' . $qubaids->usage_id_in(), + WHERE qu.id ' . $qubaidtest, $qubaids->usage_id_in_params()); } diff --git a/question/previewlib.php b/question/previewlib.php index 9683cae73a7..6509d685cb3 100644 --- a/question/previewlib.php +++ b/question/previewlib.php @@ -316,3 +316,30 @@ function restart_preview($previewid, $questionid, $displayoptions, $context) { redirect(question_preview_url($questionid, $displayoptions->behaviour, $displayoptions->maxmark, $displayoptions, $displayoptions->variant, $context)); } + +/** + * Scheduled tasks relating to question preview. Specifically, delete any old + * previews that are left over in the database. + */ +function question_preview_cron() { + $maxage = 24*60*60; // We delete previews that have not been touched for 24 hours. + $lastmodifiedcutoff = time() - $maxage; + + mtrace("\n Cleaning up old question previews...", ''); + $oldpreviews = new qubaid_join('{question_usages} quba', 'quba.id', + 'quba.component = :qubacomponent + AND NOT EXISTS ( + SELECT 1 + FROM {question_attempts} qa + JOIN {question_attempt_steps} qas ON qas.questionattemptid = qa.id + WHERE qa.questionusageid = quba.id + AND (qa.timemodified > :qamodifiedcutoff + OR qas.timecreated > :stepcreatedcutoff) + ) + ', + array('qubacomponent' => 'core_question_preview', + 'qamodifiedcutoff' => $lastmodifiedcutoff, 'stepcreatedcutoff' => $lastmodifiedcutoff)); + + question_engine::delete_questions_usage_by_activities($oldpreviews); + mtrace('done.'); +} From f238bb73d1b1a0a69548eb8e1a5c7fec6f01bbf4 Mon Sep 17 00:00:00 2001 From: Tim Hunt Date: Tue, 31 Jul 2012 18:29:39 +0100 Subject: [PATCH 15/95] MDL-32705 backup ui: add select all/none JavaScript on schema screens --- backup/util/ui/base_moodleform.class.php | 3 + .../ui/yui/backupselectall/backupselectall.js | 80 +++++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100644 backup/util/ui/yui/backupselectall/backupselectall.js diff --git a/backup/util/ui/base_moodleform.class.php b/backup/util/ui/base_moodleform.class.php index 3a72edcad20..ce95e7a81d6 100644 --- a/backup/util/ui/base_moodleform.class.php +++ b/backup/util/ui/base_moodleform.class.php @@ -324,6 +324,9 @@ abstract class base_moodleform extends moodleform { $config->noLabel = get_string('confirmcancelno', 'backup'); $PAGE->requires->yui_module('moodle-backup-confirmcancel', 'M.core_backup.watch_cancel_buttons', array($config)); + $PAGE->requires->yui_module('moodle-backup-backupselectall', 'M.core_backup.select_all_init', + array(array('select' => get_string('select'), 'all' => get_string('all'), 'none' => get_string('none')))); + parent::display(); } diff --git a/backup/util/ui/yui/backupselectall/backupselectall.js b/backup/util/ui/yui/backupselectall/backupselectall.js new file mode 100644 index 00000000000..9f05b7f4272 --- /dev/null +++ b/backup/util/ui/yui/backupselectall/backupselectall.js @@ -0,0 +1,80 @@ +YUI.add('moodle-backup-backupselectall', function(Y) { + +// Namespace for the backup +M.core_backup = M.core_backup || {}; + +/** + * Adds select all/none links to the top of the backup/restore/import schema page. + */ +M.core_backup.select_all_init = function(str) { + var formid = null; + + var helper = function(e, check, type) { + e.preventDefault(); + + var len = type.length; + Y.all('input[type="checkbox"]').each(function(checkbox) { + var name = checkbox.get('name'); + if (name.substring(name.length - len) == type) { + checkbox.set('checked', check); + } + }); + + // At this point, we really need to persuade the form we are part of to + // update all of its disabledIf rules. However, as far as I can see, + // given the way that lib/form/form.js is written, that is impossible. + if (formid && M.form) { + M.form.updateFormState(formid); + } + }; + + var html_generator = function(classname, idtype) { + return '
' + + '
' + + '
' + str.select + '
' + + '
' + + '' + str.all + ' / ' + + '' + str.none + '' + + '
' + + '
' + + '
'; + }; + + var firstsection = Y.one('fieldset#coursesettings .fcontainer.clearfix .grouped_settings.section_level'); + if (!firstsection) { + // This is not a relevant page. + return; + } + if (!firstsection.one('.felement.fcheckbox')) { + // No checkboxes. + return; + } + + formid = firstsection.ancestor('form').getAttribute('id'); + + var withuserdata = false; + Y.all('input[type="checkbox"]').each(function(checkbox) { + var name = checkbox.get('name'); + if (name.substring(name.length - 9) == '_userdata') { + withuserdata = '_userdata'; + } else if (name.substring(name.length - 9) == '_userinfo') { + withuserdata = '_userinfo'; + } + }); + + var html = html_generator('include_setting section_level', 'included'); + if (withuserdata) { + html += html_generator('normal_setting', 'userdata'); + } + var links = Y.Node.create('
' + html + '
'); + firstsection.insert(links, 'before'); + + Y.one('#backup-all-included').on('click', function(e) { helper(e, true, '_included'); }); + Y.one('#backup-none-included').on('click', function(e) { helper(e, false, '_included'); }); + if (withuserdata) { + Y.one('#backup-all-userdata').on('click', function(e) { helper(e, true, withuserdata); }); + Y.one('#backup-none-userdata').on('click', function(e) { helper(e, false, withuserdata); }); + } +} + +}, '@VERSION@', {'requires':['base','node','event', 'node-event-simulate']}); From be77e9b6a8d3aea93598bf6224e287d4149fbdc5 Mon Sep 17 00:00:00 2001 From: Tim Hunt Date: Thu, 9 Aug 2012 15:40:08 +0100 Subject: [PATCH 16/95] MDL-34810 question bank: user prefs for some display options The options that are remembered persistently are * Also show questions from sub-categories * Also show old questions * Show question text in the question list * Number of questions per page --- question/editlib.php | 60 ++++++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 27 deletions(-) diff --git a/question/editlib.php b/question/editlib.php index b779de62458..f28b9c2fa60 100644 --- a/question/editlib.php +++ b/question/editlib.php @@ -1642,12 +1642,8 @@ function question_edit_setup($edittab, $baseurl, $requirecmid = false, $requirec $pagevars['qpage'] = 0; } - $pagevars['qperpage'] = optional_param('qperpage', -1, PARAM_INT); - if ($pagevars['qperpage'] > -1) { - $thispageurl->param('qperpage', $pagevars['qperpage']); - } else { - $pagevars['qperpage'] = DEFAULT_QUESTIONS_PER_PAGE; - } + $pagevars['qperpage'] = question_get_display_preference( + 'qperpage', DEFAULT_QUESTIONS_PER_PAGE, PARAM_INT, $thispageurl); for ($i = 1; $i <= question_bank_view::MAX_SORTS; $i++) { $param = 'qbs' . $i; @@ -1675,28 +1671,12 @@ function question_edit_setup($edittab, $baseurl, $requirecmid = false, $requirec $pagevars['cat'] = "$category->id,$category->contextid"; } - if(($recurse = optional_param('recurse', -1, PARAM_BOOL)) != -1) { - $pagevars['recurse'] = $recurse; - $thispageurl->param('recurse', $recurse); - } else { - $pagevars['recurse'] = 1; - } + // Display options. + $pagevars['recurse'] = question_get_display_preference('recurse', 1, PARAM_BOOL, $thispageurl); + $pagevars['showhidden'] = question_get_display_preference('showhidden', 0, PARAM_BOOL, $thispageurl); + $pagevars['qbshowtext'] = question_get_display_preference('qbshowtext', 0, PARAM_BOOL, $thispageurl); - if(($showhidden = optional_param('showhidden', -1, PARAM_BOOL)) != -1) { - $pagevars['showhidden'] = $showhidden; - $thispageurl->param('showhidden', $showhidden); - } else { - $pagevars['showhidden'] = 0; - } - - if(($showquestiontext = optional_param('qbshowtext', -1, PARAM_BOOL)) != -1) { - $pagevars['qbshowtext'] = $showquestiontext; - $thispageurl->param('qbshowtext', $showquestiontext); - } else { - $pagevars['qbshowtext'] = 0; - } - - //category list page + // Category list page. $pagevars['cpage'] = optional_param('cpage', 1, PARAM_INT); if ($pagevars['cpage'] != 1){ $thispageurl->param('cpage', $pagevars['cpage']); @@ -1705,6 +1685,32 @@ function question_edit_setup($edittab, $baseurl, $requirecmid = false, $requirec return array($thispageurl, $contexts, $cmid, $cm, $module, $pagevars); } +/** + * Get a particular question preference that is also stored as a user preference. + * If the the value is given in the GET/POST request, then that value is used, + * and the user preference is updated to that value. Otherwise, the last set + * value of the user preference is used, or if it has never been set the default + * passed to this function. + * + * @param string $param the param name. The URL parameter set, and the GET/POST + * parameter read. The user_preference name is 'question_bank_' . $param. + * @param mixed $default The default value to use, if not otherwise set. + * @param int $type one of the PARAM_... constants. + * @param moodle_url $thispageurl if the value has been explicitly set, we add + * it to this URL. + * @return mixed the parameter value to use. + */ +function question_get_display_preference($param, $default, $type, $thispageurl) { + $submittedvalue = optional_param($param, null, $type); + if (is_null($submittedvalue)) { + return get_user_preferences('question_bank_' . $param, $default); + } + + set_user_preference('question_bank_' . $param, $submittedvalue); + $thispageurl->param($param, $submittedvalue); + return $submittedvalue; +} + /** * Make sure user is logged in as required in this context. */ From 85b72a75114c30893dd7177cf5eb8c199f886538 Mon Sep 17 00:00:00 2001 From: Tim Hunt Date: Tue, 14 Aug 2012 15:25:03 +0100 Subject: [PATCH 17/95] MDL-34889 phpunit: progress output in util.php --drop. It is slow for me, and it is nice to know that something is going on. --- admin/tool/phpunit/cli/util.php | 2 +- lib/phpunit/classes/util.php | 27 +++++++++++++++++++++++++-- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/admin/tool/phpunit/cli/util.php b/admin/tool/phpunit/cli/util.php index 2986d6497ad..5afd3bacbe8 100644 --- a/admin/tool/phpunit/cli/util.php +++ b/admin/tool/phpunit/cli/util.php @@ -150,7 +150,7 @@ if ($diag) { } else if ($drop) { // make sure tests do not run in parallel phpunit_util::acquire_test_lock(); - phpunit_util::drop_site(); + phpunit_util::drop_site(true); // note: we must stop here because $CFG is messed up and we can not reinstall, sorry exit(0); diff --git a/lib/phpunit/classes/util.php b/lib/phpunit/classes/util.php index 33805494dfd..b580259da3e 100644 --- a/lib/phpunit/classes/util.php +++ b/lib/phpunit/classes/util.php @@ -762,16 +762,20 @@ class phpunit_util { * Note: To be used from CLI scripts only. * * @static + * @param bool $displayprogress if true, this method will echo progress information. * @return void may terminate execution with exit code */ - public static function drop_site() { + public static function drop_site($displayprogress = false) { global $DB, $CFG; if (!self::is_test_site()) { phpunit_bootstrap_error(PHPUNIT_EXITCODE_CONFIGERROR, 'Can not drop non-test site!!'); } - // purge dataroot + // Purge dataroot + if ($displayprogress) { + echo "Purging dataroot:\n"; + } self::reset_dataroot(); phpunit_bootstrap_initdataroot($CFG->dataroot); $keep = array('.', '..', 'lock', 'webrunner.xml'); @@ -795,9 +799,28 @@ class phpunit_util { unset($tables['config']); $tables['config'] = 'config'; } + + if ($displayprogress) { + echo "Dropping tables:\n"; + } + $dotsonline = 0; foreach ($tables as $tablename) { $table = new xmldb_table($tablename); $DB->get_manager()->drop_table($table); + + if ($dotsonline == 60) { + if ($displayprogress) { + echo "\n"; + } + $dotsonline = 0; + } + if ($displayprogress) { + echo '.'; + } + $dotsonline += 1; + } + if ($displayprogress) { + echo "\n"; } } From 6df46aea1d00fc42e92e54b3bb44757425b9d0d9 Mon Sep 17 00:00:00 2001 From: Tim Hunt Date: Thu, 16 Aug 2012 17:33:08 +0100 Subject: [PATCH 18/95] MDL-34702 quiz DB: questiondecimalpoints has wrong default. Thanks to the folks at UCL for tracking down this problem. It has only hidden for 2+ years! --- mod/quiz/backup/moodle1/lib.php | 2 +- mod/quiz/db/install.xml | 2 +- mod/quiz/db/upgrade.php | 19 +++++++++++++++++++ mod/quiz/version.php | 2 +- 4 files changed, 22 insertions(+), 3 deletions(-) diff --git a/mod/quiz/backup/moodle1/lib.php b/mod/quiz/backup/moodle1/lib.php index 2e25b40a77c..09efca0df64 100644 --- a/mod/quiz/backup/moodle1/lib.php +++ b/mod/quiz/backup/moodle1/lib.php @@ -56,7 +56,7 @@ class moodle1_mod_quiz_handler extends moodle1_mod_handler { array( 'newfields' => array( 'showuserpicture' => 0, - 'questiondecimalpoints' => -2, + 'questiondecimalpoints' => -1, 'introformat' => 0, 'showblocks' => 0, ) diff --git a/mod/quiz/db/install.xml b/mod/quiz/db/install.xml index fd12420079c..dede549feda 100644 --- a/mod/quiz/db/install.xml +++ b/mod/quiz/db/install.xml @@ -21,7 +21,7 @@ - + diff --git a/mod/quiz/db/upgrade.php b/mod/quiz/db/upgrade.php index 3bbbb6d4d83..cb8e76df0a9 100644 --- a/mod/quiz/db/upgrade.php +++ b/mod/quiz/db/upgrade.php @@ -341,6 +341,25 @@ function xmldb_quiz_upgrade($oldversion) { upgrade_mod_savepoint(true, 2012061702, 'quiz'); } + if ($oldversion < 2012061703) { + + // MDL-34702 the questiondecimalpoints column was created with default -2 + // when it should have been -1, and no-one has noticed in the last 2+ years! + + // Changing the default of field questiondecimalpoints on table quiz to -1. + $table = new xmldb_table('quiz'); + $field = new xmldb_field('questiondecimalpoints', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, '-1', 'decimalpoints'); + + // Launch change of default for field questiondecimalpoints. + $dbman->change_field_default($table, $field); + + // Correct any wrong values. + $DB->set_field('quiz', 'questiondecimalpoints', -1, array('questiondecimalpoints' => -2)); + + // Quiz savepoint reached. + upgrade_mod_savepoint(true, 2012061703, 'quiz'); + } + return true; } diff --git a/mod/quiz/version.php b/mod/quiz/version.php index 67ca371213d..59c7b3c332d 100644 --- a/mod/quiz/version.php +++ b/mod/quiz/version.php @@ -25,7 +25,7 @@ defined('MOODLE_INTERNAL') || die(); -$module->version = 2012061702; // The current module version (Date: YYYYMMDDXX). +$module->version = 2012061703; // The current module version (Date: YYYYMMDDXX). $module->requires = 2012061700; // Requires this Moodle version. $module->component = 'mod_quiz'; // Full name of the plugin (used for diagnostics). $module->cron = 60; From 1a33536c4d2a36696c2d0b6583b6acb0773584b4 Mon Sep 17 00:00:00 2001 From: "Eloy Lafuente (stronk7)" Date: Thu, 16 Aug 2012 20:43:24 +0200 Subject: [PATCH 19/95] MDL-34934 general: Delete unnecessary .gitignore --- lib/editor/tinymce/extra/tools/.gitignore | 1 - 1 file changed, 1 deletion(-) delete mode 100644 lib/editor/tinymce/extra/tools/.gitignore diff --git a/lib/editor/tinymce/extra/tools/.gitignore b/lib/editor/tinymce/extra/tools/.gitignore deleted file mode 100644 index 9c595a6fb76..00000000000 --- a/lib/editor/tinymce/extra/tools/.gitignore +++ /dev/null @@ -1 +0,0 @@ -temp From 698c42ee6129e97a89231fee26044f38a6937b4e Mon Sep 17 00:00:00 2001 From: Tim Hunt Date: Thu, 16 Aug 2012 21:34:17 +0100 Subject: [PATCH 20/95] MDL-34937 quiz responses reports: attempt grade not shown. --- mod/quiz/report/responses/responses_table.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mod/quiz/report/responses/responses_table.php b/mod/quiz/report/responses/responses_table.php index ed6ada43198..a5a0c094d83 100644 --- a/mod/quiz/report/responses/responses_table.php +++ b/mod/quiz/report/responses/responses_table.php @@ -63,7 +63,7 @@ class quiz_responses_table extends quiz_attempts_report_table { } public function col_sumgrades($attempt) { - if ($attempt->state == quiz_attempt::FINISHED) { + if ($attempt->state != quiz_attempt::FINISHED) { return '-'; } From 8256662754ecbba123f2709c2a4aa8b3f35f2919 Mon Sep 17 00:00:00 2001 From: AMOS bot Date: Fri, 17 Aug 2012 00:31:48 +0000 Subject: [PATCH 21/95] Automatically generated installer lang files --- install/lang/zh_cn/install.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/lang/zh_cn/install.php b/install/lang/zh_cn/install.php index c338c8b45b0..93647deac02 100644 --- a/install/lang/zh_cn/install.php +++ b/install/lang/zh_cn/install.php @@ -81,7 +81,7 @@ $string['phpversionhelp'] = '

Moodle需要PHP 4.3.0或5.1.0(5.0.x有若干 (如果正使用5.0.x,您也可以降级到4.4.x版)

'; $string['welcomep10'] = '{$a->installername} ({$a->installerversion})'; -$string['welcomep20'] = '您看到这个页面表明您已经成功地在您的计算机上安装了{$a->packname} {$a->packversion}。恭喜您!'; +$string['welcomep20'] = '您看到这个页面表明您已经成功地在您的计算机上安装并启用了{$a->packname} {$a->packversion}软件包。恭喜您!'; $string['welcomep30'] = '{$a->installername}的此发行版包含了可以创建Moodle运行环境的应用程序:'; $string['welcomep40'] = '这个软件包还包含了Moodle {$a->moodlerelease} ({$a->moodleversion})。'; $string['welcomep50'] = '使用本软件包中包含的应用程序时应遵循它们各自的授权协议。整个{$a->installername}软件包都是开源的,并且遵循GPL授权协议发布。'; From 79ed4d8475c79e8eefce33d114d4e27c6932efce Mon Sep 17 00:00:00 2001 From: Damyon Wiese Date: Thu, 16 Aug 2012 11:34:33 +0800 Subject: [PATCH 22/95] MDL-31341: Add custom completion rule to assignment: 'submit' --- .../backup/moodle2/backup_assign_stepslib.php | 3 ++- mod/assign/db/install.xml | 3 ++- mod/assign/db/upgrade.php | 14 ++++++++++ mod/assign/lang/en/assign.php | 1 + mod/assign/lib.php | 27 +++++++++++++++++++ mod/assign/locallib.php | 22 ++++++++++++++- mod/assign/mod_form.php | 10 +++++++ mod/assign/version.php | 2 +- 8 files changed, 78 insertions(+), 4 deletions(-) diff --git a/mod/assign/backup/moodle2/backup_assign_stepslib.php b/mod/assign/backup/moodle2/backup_assign_stepslib.php index fa972085109..06a8fdc4d9b 100644 --- a/mod/assign/backup/moodle2/backup_assign_stepslib.php +++ b/mod/assign/backup/moodle2/backup_assign_stepslib.php @@ -55,7 +55,8 @@ class backup_assign_activity_structure_step extends backup_activity_structure_st 'duedate', 'allowsubmissionsfromdate', 'grade', - 'timemodified')); + 'timemodified', + 'completionsubmit')); $submissions = new backup_nested_element('submissions'); diff --git a/mod/assign/db/install.xml b/mod/assign/db/install.xml index c075dbd9bb5..213a62b6655 100644 --- a/mod/assign/db/install.xml +++ b/mod/assign/db/install.xml @@ -21,7 +21,8 @@ - + + diff --git a/mod/assign/db/upgrade.php b/mod/assign/db/upgrade.php index e12e781d81f..d3c6c4eb802 100644 --- a/mod/assign/db/upgrade.php +++ b/mod/assign/db/upgrade.php @@ -64,6 +64,20 @@ function xmldb_assign_upgrade($oldversion) { // Assign savepoint reached. upgrade_mod_savepoint(true, 2012071800, 'assign'); } + if ($oldversion < 2012081600) { + + // Define field sendlatenotifications to be added to assign + $table = new xmldb_table('assign'); + $field = new xmldb_field('completionsubmit', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '0', 'timemodified'); + + // Conditionally launch add field sendlatenotifications + if (!$dbman->field_exists($table, $field)) { + $dbman->add_field($table, $field); + } + + // Assign savepoint reached. + upgrade_mod_savepoint(true, 2012081600, 'assign'); + } return true; } diff --git a/mod/assign/lang/en/assign.php b/mod/assign/lang/en/assign.php index 9ab4132b561..3b8a6f9417a 100644 --- a/mod/assign/lang/en/assign.php +++ b/mod/assign/lang/en/assign.php @@ -66,6 +66,7 @@ $string['batchoperationlock'] = 'lock submissions'; $string['batchoperationunlock'] = 'unlock submissions'; $string['batchoperationreverttodraft'] = 'revert submissions to draft'; $string['comment'] = 'Comment'; +$string['completionsubmit'] = 'Student must submit to this activity to complete it'; $string['conversionexception'] = 'Could not convert assignment. Exception was: {$a}.'; $string['configshowrecentsubmissions'] = 'Everyone can see notifications of submissions in recent activity reports.'; $string['confirmsubmission'] = 'Are you sure you want to submit your work for grading? You will not be able to make any more changes'; diff --git a/mod/assign/lib.php b/mod/assign/lib.php index f423fa3d733..c39c24f98e0 100644 --- a/mod/assign/lib.php +++ b/mod/assign/lib.php @@ -83,6 +83,7 @@ function assign_supports($feature) { case FEATURE_GROUPMEMBERSONLY: return true; case FEATURE_MOD_INTRO: return true; case FEATURE_COMPLETION_TRACKS_VIEWS: return true; + case FEATURE_COMPLETION_HAS_RULES: return true; case FEATURE_GRADE_HAS_GRADE: return true; case FEATURE_GRADE_OUTCOMES: return true; case FEATURE_BACKUP_MOODLE2: return true; @@ -936,3 +937,29 @@ function assign_user_outline($course, $user, $coursemodule, $assignment) { return $result; } + +/** + * Obtains the automatic completion state for this module based on any conditions + * in assign settings. + * + * @param object $course Course + * @param object $cm Course-module + * @param int $userid User ID + * @param bool $type Type of comparison (or/and; can be used as return value if no conditions) + * @return bool True if completed, false if not, $type if conditions not set. + */ +function assign_get_completion_state($course,$cm,$userid,$type) { + global $CFG,$DB; + require_once($CFG->dirroot . '/mod/assign/locallib.php'); + + $assign = new assign(null, $cm, $course); + + // If completion option is enabled, evaluate it and return true/false + if($assign->get_instance()->completionsubmit) { + $submission = $DB->get_record('assign_submission', array('assignment'=>$assign->get_instance()->id, 'userid'=>$userid), '*', IGNORE_MISSING); + return $submission && $submission->status == ASSIGN_SUBMISSION_STATUS_SUBMITTED; + } else { + // Completion option is not enabled so just return $type + return $type; + } +} diff --git a/mod/assign/locallib.php b/mod/assign/locallib.php index 94d18719593..60a3f9251c1 100644 --- a/mod/assign/locallib.php +++ b/mod/assign/locallib.php @@ -417,6 +417,7 @@ class assign { $update->duedate = $formdata->duedate; $update->allowsubmissionsfromdate = $formdata->allowsubmissionsfromdate; $update->grade = $formdata->grade; + $update->completionsubmit = $formdata->completionsubmit; $returnid = $DB->insert_record('assign', $update); $this->instance = $DB->get_record('assign', array('id'=>$returnid), '*', MUST_EXIST); // cache the course record @@ -636,6 +637,7 @@ class assign { $update->duedate = $formdata->duedate; $update->allowsubmissionsfromdate = $formdata->allowsubmissionsfromdate; $update->grade = $formdata->grade; + $update->completionsubmit = $formdata->completionsubmit; $result = $DB->update_record('assign', $update); $this->instance = $DB->get_record('assign', array('id'=>$update->id), '*', MUST_EXIST); @@ -2561,6 +2563,11 @@ class assign { $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED; $this->update_submission($submission); + $completion = new completion_info($this->get_course()); + if ($completion->is_enabled($this->get_course_module()) && $this->get_instance()->completionsubmit) { + $completion->update_state($this->get_course_module(), COMPLETION_COMPLETE, $USER->id); + } + if (isset($data->submissionstatement)) { $this->add_to_log('submission statement accepted', get_string('submissionstatementacceptedlog', 'mod_assign', fullname($USER))); } @@ -2838,6 +2845,15 @@ class assign { } $this->add_to_log('submit', $this->format_submission_for_log($submission)); + $complete = COMPLETION_INCOMPLETE; + if ($submission->status == ASSIGN_SUBMISSION_STATUS_SUBMITTED) { + $complete = COMPLETION_COMPLETE; + } + $completion = new completion_info($this->get_course()); + if ($completion->is_enabled($this->get_course_module()) && $this->get_instance()->completionsubmit) { + $completion->update_state($this->get_course_module(), $complete, $USER->id); + } + if (!$this->get_instance()->submissiondrafts) { $this->notify_student_submission_receipt($submission); $this->notify_graders($submission); @@ -3140,7 +3156,7 @@ class assign { * @return void */ private function process_revert_to_draft($userid = 0) { - global $USER, $DB; + global $DB; // Need grade permission require_capability('mod/assign:grade', $this->context); @@ -3163,6 +3179,10 @@ class assign { $user = $DB->get_record('user', array('id' => $userid), '*', MUST_EXIST); + $completion = new completion_info($this->get_course()); + if ($completion->is_enabled($this->get_course_module()) && $this->get_instance()->completionsubmit) { + $completion->update_state($this->get_course_module(), COMPLETION_INCOMPLETE, $userid); + } $this->add_to_log('revert submission to draft', get_string('reverttodraftforstudent', 'assign', array('id'=>$user->id, 'fullname'=>fullname($user)))); } diff --git a/mod/assign/mod_form.php b/mod/assign/mod_form.php index 89d0159631c..14650757413 100644 --- a/mod/assign/mod_form.php +++ b/mod/assign/mod_form.php @@ -161,5 +161,15 @@ class mod_assign_mod_form extends moodleform_mod { $assignment->plugin_data_preprocessing($defaultvalues); } + function add_completion_rules() { + $mform =& $this->_form; + + $mform->addElement('checkbox', 'completionsubmit', '', get_string('completionsubmit', 'assign')); + return array('completionsubmit'); + } + + function completion_rule_enabled($data) { + return !empty($data['completionsubmit']); + } } diff --git a/mod/assign/version.php b/mod/assign/version.php index 99ef6478807..b9a29a3d16c 100644 --- a/mod/assign/version.php +++ b/mod/assign/version.php @@ -25,7 +25,7 @@ defined('MOODLE_INTERNAL') || die(); $module->component = 'mod_assign'; // Full name of the plugin (used for diagnostics) -$module->version = 2012071800; // The current module version (Date: YYYYMMDDXX) +$module->version = 2012081600; // The current module version (Date: YYYYMMDDXX) $module->requires = 2012061700; // Requires this Moodle version $module->cron = 60; From f61b427ab631fe5542fb6cdb6f0c4751f039f02d Mon Sep 17 00:00:00 2001 From: Rossiani Wijaya Date: Tue, 14 Aug 2012 12:20:34 +0800 Subject: [PATCH 23/95] MDL-34569 accessibility compliance for wiki module: Add label for input text and select tag --- mod/wiki/editors/wikieditor.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mod/wiki/editors/wikieditor.php b/mod/wiki/editors/wikieditor.php index e8804936079..4865a7cb52d 100644 --- a/mod/wiki/editors/wikieditor.php +++ b/mod/wiki/editors/wikieditor.php @@ -120,7 +120,8 @@ class MoodleQuickForm_wikieditor extends MoodleQuickForm_textarea { $html .= html_writer::empty_tag('img', array('alt' => $button[1], 'src' => $CFG->wwwroot . '/mod/wiki/editors/wiki/images/' . $button[0])); $html .= ""; } - $html .= ""; $html .= "'; foreach ($this->files as $filename) { $html .= "