From bce6b3c70a44b6f6118c7987d077e39e0e8522a2 Mon Sep 17 00:00:00 2001 From: Tony Levi Date: Thu, 16 Jun 2011 12:47:17 +0930 Subject: [PATCH 01/21] MDL-24577: Fix mark all posts in this discussion read doesn't work completely correct --- mod/forum/lib.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mod/forum/lib.php b/mod/forum/lib.php index cc5ef170ef7..1cc0b02edb3 100644 --- a/mod/forum/lib.php +++ b/mod/forum/lib.php @@ -6226,8 +6226,9 @@ function forum_tp_mark_posts_read($user, $postids) { if ($new) { list($usql, $new_params) = $DB->get_in_or_equal($new); - $params = array($user->id, $now, $now, $user->id, $cutoffdate); + $params = array($user->id, $now, $now, $user->id); $params = array_merge($params, $new_params); + $params[] = $cutoffdate; $sql = "INSERT INTO {forum_read} (userid, postid, discussionid, forumid, firstread, lastread) From cb1564b1ce5eeb793b8be81020f3190489ec306f Mon Sep 17 00:00:00 2001 From: Tim Hunt Date: Wed, 9 Nov 2011 11:45:02 +0000 Subject: [PATCH 02/21] MDL-29743 quiz: Finish attempt link didn't save responses in some brosers. Thanks to Brandon Browning for identifying the problem. It is quite subtle why this typo would have this effect. You need to look at the implementation of the preventDefault method in lib/yui/3.4.1/build/event-base/event-base.js. --- mod/quiz/module.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mod/quiz/module.js b/mod/quiz/module.js index ec37234f43f..d9d217f685c 100644 --- a/mod/quiz/module.js +++ b/mod/quiz/module.js @@ -170,7 +170,7 @@ M.mod_quiz.nav.init = function(Y) { if (Y.one('a.endtestlink')) { Y.on('click', function(e) { - e.preventDefault(e); + e.preventDefault(); Y.one('#followingpage').set('value', -1); Y.one('#responseform').submit(); }, 'a.endtestlink'); From 6336bd914a7adb446dc48b88a0f58bbcec795a17 Mon Sep 17 00:00:00 2001 From: Henning Bostelmann Date: Tue, 13 Sep 2011 01:11:19 +0100 Subject: [PATCH 03/21] MDL-29350 Prevent duplication of groupings when copying activities This patch also includes a database upgrade to correct data produced as a result of this bug. --- backup/moodle2/restore_stepslib.php | 9 ++++++++- lib/db/upgrade.php | 15 +++++++++++++++ version.php | 2 +- 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/backup/moodle2/restore_stepslib.php b/backup/moodle2/restore_stepslib.php index 3044c7ff808..c9705a98b33 100644 --- a/backup/moodle2/restore_stepslib.php +++ b/backup/moodle2/restore_stepslib.php @@ -802,7 +802,14 @@ class restore_groups_structure_step extends restore_structure_step { $data->groupingid = $this->get_new_parentid('grouping'); // Use new parentid $data->groupid = $this->get_mappingid('group', $data->groupid); // Get from mappings - $DB->insert_record('groupings_groups', $data); // No need to set this mapping (no child info nor files) + + $params = array(); + $params['groupingid'] = $data->groupingid; + $params['groupid'] = $data->groupid; + + if (!$DB->record_exists('groupings_groups', $params)) { + $DB->insert_record('groupings_groups', $data); // No need to set this mapping (no child info nor files) + } } protected function after_execute() { diff --git a/lib/db/upgrade.php b/lib/db/upgrade.php index 83adec74439..097cfb10066 100644 --- a/lib/db/upgrade.php +++ b/lib/db/upgrade.php @@ -6916,6 +6916,21 @@ FROM upgrade_main_savepoint(true, 2011110200.02); } + if ($oldversion < 2011111500.01) { + // Remove duplicate entries from groupings_groups table + $sql = 'SELECT MIN(id) AS firstid, groupingid, groupid FROM {groupings_groups} '. + 'GROUP BY groupingid, groupid HAVING COUNT(id)>1'; + $badrecs = $DB->get_records_sql($sql); + foreach ($badrecs as $badrec) { + $where = 'groupingid = ? and groupid = ? and id > ?'; + $params = array($badrec->groupingid, $badrec->groupid, $badrec->firstid); + $DB->delete_records_select('groupings_groups', $where, $params); + } + + // Main savepoint reached + upgrade_main_savepoint(true, 2011111500.01); + } + return true; } diff --git a/version.php b/version.php index eb0a3297af2..19816d1a81f 100644 --- a/version.php +++ b/version.php @@ -30,7 +30,7 @@ defined('MOODLE_INTERNAL') || die(); -$version = 2011111500.00; // YYYYMMDD = weekly release date of this DEV branch +$version = 2011111500.01; // YYYYMMDD = weekly release date of this DEV branch // RR = release increments - 00 in DEV branches // .XX = incremental changes From 5cc021a00b43722379a10fb6905314defeff016e Mon Sep 17 00:00:00 2001 From: Tim Hunt Date: Tue, 8 Nov 2011 15:12:58 +0000 Subject: [PATCH 04/21] MDL-30069 Question type icons missing in lots of places. --- lib/questionlib.php | 12 ++--------- mod/quiz/editlib.php | 8 +++---- question/editlib.php | 2 +- question/renderer.php | 49 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 56 insertions(+), 15 deletions(-) create mode 100644 question/renderer.php diff --git a/lib/questionlib.php b/lib/questionlib.php index 1bfe045e44f..081a0e67cd0 100644 --- a/lib/questionlib.php +++ b/lib/questionlib.php @@ -825,16 +825,8 @@ function get_question_options(&$questions, $loadtags = false) { * @return string the HTML for the img tag. */ function print_question_icon($question) { - global $OUTPUT; - - $qtype = question_bank::get_qtype($question->qtype, false); - $namestr = $qtype->menu_name(); - - // TODO convert to return a moodle_icon object, or whatever the class is. - $html = '' .
-            $namestr . ''; - - return $html; + global $PAGE; + return $PAGE->get_renderer('question', 'bank')->qtype_icon($question->qtype); } /** diff --git a/mod/quiz/editlib.php b/mod/quiz/editlib.php index 6b5ddf9f74a..0097787deb5 100644 --- a/mod/quiz/editlib.php +++ b/mod/quiz/editlib.php @@ -781,7 +781,7 @@ function quiz_print_singlequestion($question, $returnurl, $quiz) { echo quiz_question_edit_button($quiz->cmid, $question, $returnurl, quiz_question_tostring($question) . ' '); echo ''; - print_question_icon($question); + echo print_question_icon($question); echo ' ' . question_bank::get_qtype_name($question->qtype) . ''; echo '' . quiz_question_preview_button($quiz, $question, true) . ''; @@ -807,7 +807,7 @@ function quiz_print_randomquestion(&$question, &$pageurl, &$quiz, $quiz_qbanktoo } echo '
'; - print_question_icon($question); + echo print_question_icon($question); print_random_option_icon($question); echo ' ' . get_string('randomfromcategory', 'quiz') . '
'; @@ -886,7 +886,7 @@ function quiz_print_randomquestion(&$question, &$pageurl, &$quiz, $quiz_qbanktoo function quiz_print_singlequestion_reordertool($question, $returnurl, $quiz) { echo '
'; echo ''; echo '' . @@ -920,7 +920,7 @@ function quiz_print_randomquestion_reordertool(&$question, &$pageurl, &$quiz) { echo '
'; echo '
'; echo $reordercheckboxlabel; - print_question_icon($question); + echo print_question_icon($question); print_random_option_icon($question); if ($questioncount == 0) { diff --git a/question/editlib.php b/question/editlib.php index 8bc1c2c80c1..4079d48488b 100644 --- a/question/editlib.php +++ b/question/editlib.php @@ -1793,7 +1793,7 @@ function print_qtype_to_add_option($qtype) { echo ''; $fakequestion = new stdClass(); $fakequestion->qtype = $qtype->name(); - print_question_icon($fakequestion); + echo print_question_icon($fakequestion); echo $qtype->menu_name() . '' . $summary; echo "\n"; echo "
\n"; diff --git a/question/renderer.php b/question/renderer.php new file mode 100644 index 00000000000..f8f667b5981 --- /dev/null +++ b/question/renderer.php @@ -0,0 +1,49 @@ +. + +/** + * Renderers for outputting parts of the question bank. + * + * @package moodlecore + * @subpackage questionbank + * @copyright 2011 The Open University + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + + +defined('MOODLE_INTERNAL') || die(); + + +/** + * This renderer outputs parts of the question bank. + * + * @copyright 2011 The Open University + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class core_question_bank_renderer extends plugin_renderer_base { + + /** + * Output the icon for a question type + * @param string $qtype the question type. + * @return string HTML fragment. + */ + public function qtype_icon($qtype) { + $qtype = question_bank::get_qtype($qtype, false); + $namestr = $qtype->local_name(); + + return $this->pix_icon('icon', $namestr, $qtype->plugin_name(), array('title' => $namestr)); + } +} From 94c0ec215925dd52a5c8ea8ba59e62ef7c236c5d Mon Sep 17 00:00:00 2001 From: Tim Hunt Date: Tue, 8 Nov 2011 16:53:15 +0000 Subject: [PATCH 05/21] MDL-30185 question engine reporting: add redundant where to query for perf. Without this, MySQL fails to cope. --- mod/quiz/report/attemptsreport.php | 10 ++++- question/engine/datalib.php | 61 +++++++++++++++++------------- 2 files changed, 44 insertions(+), 27 deletions(-) diff --git a/mod/quiz/report/attemptsreport.php b/mod/quiz/report/attemptsreport.php index 89bfefc1fc5..f26b2ec7071 100644 --- a/mod/quiz/report/attemptsreport.php +++ b/mod/quiz/report/attemptsreport.php @@ -621,13 +621,21 @@ abstract class quiz_attempt_report_table extends table_sql { return; } + // This condition roughly filters the list of attempts to be considered. + // It is only used in a subselect to help crappy databases (see MDL-30122) + // therefore, it is better to use a very simple join, which may include + // too many records, than to do a super-accurate join. + $qubaids = new qubaid_join("{quiz_attempts} {$alias}quiza", "{$alias}quiza.uniqueid", + "{$alias}quiza.quiz = :{$alias}quizid", array("{$alias}quizid" => $this->sql->params['quizid'])); + $dm = new question_engine_data_mapper(); - $inlineview = $dm->question_attempt_latest_state_view($alias); + list($inlineview, $viewparams) = $dm->question_attempt_latest_state_view($alias, $qubaids); $this->sql->fields .= ",\n$fields"; $this->sql->from .= "\nLEFT JOIN $inlineview ON " . "$alias.questionusageid = quiza.uniqueid AND $alias.slot = :{$alias}slot"; $this->sql->params[$alias . 'slot'] = $slot; + $this->sql->params = array_merge($this->sql->params, $viewparams); } /** diff --git a/question/engine/datalib.php b/question/engine/datalib.php index cdcaf8f07da..2f41b12d7ff 100644 --- a/question/engine/datalib.php +++ b/question/engine/datalib.php @@ -865,33 +865,42 @@ ORDER BY END) = 0"; } - public function question_attempt_latest_state_view($alias) { - return "( - SELECT - {$alias}qa.id AS questionattemptid, - {$alias}qa.questionusageid, - {$alias}qa.slot, - {$alias}qa.behaviour, - {$alias}qa.questionid, - {$alias}qa.variant, - {$alias}qa.maxmark, - {$alias}qa.minfraction, - {$alias}qa.flagged, - {$alias}qa.questionsummary, - {$alias}qa.rightanswer, - {$alias}qa.responsesummary, - {$alias}qa.timemodified, - {$alias}qas.id AS attemptstepid, - {$alias}qas.sequencenumber, - {$alias}qas.state, - {$alias}qas.fraction, - {$alias}qas.timecreated, - {$alias}qas.userid + /** + * Get a subquery that returns the latest step of every qa in some qubas. + * Currently, this is only used by the quiz reports. See + * {@link quiz_attempt_report_table::add_latest_state_join()}. + * @param string $alias alias to use for this inline-view. + * @param qubaid_condition $qubaids restriction on which question_usages we + * are interested in. This is important for performance. + * @return array with two elements, the SQL fragment and any params requried. + */ + public function question_attempt_latest_state_view($alias, qubaid_condition $qubaids) { + return array("( + SELECT {$alias}qa.id AS questionattemptid, + {$alias}qa.questionusageid, + {$alias}qa.slot, + {$alias}qa.behaviour, + {$alias}qa.questionid, + {$alias}qa.variant, + {$alias}qa.maxmark, + {$alias}qa.minfraction, + {$alias}qa.flagged, + {$alias}qa.questionsummary, + {$alias}qa.rightanswer, + {$alias}qa.responsesummary, + {$alias}qa.timemodified, + {$alias}qas.id AS attemptstepid, + {$alias}qas.sequencenumber, + {$alias}qas.state, + {$alias}qas.fraction, + {$alias}qas.timecreated, + {$alias}qas.userid - FROM {question_attempts} {$alias}qa - JOIN {question_attempt_steps} {$alias}qas ON - {$alias}qas.id = {$this->latest_step_for_qa_subquery($alias . 'qa.id')} - ) $alias"; + FROM {$qubaids->from_question_attempts($alias . 'qa')} + JOIN {question_attempt_steps} {$alias}qas ON + {$alias}qas.id = {$this->latest_step_for_qa_subquery($alias . 'qa.id')} + WHERE {$qubaids->where()} + ) $alias", $qubaids->from_where_params()); } protected function latest_step_for_qa_subquery($questionattemptid = 'qa.id') { From 6c314a368113c07a8d7da0aeac04771520413132 Mon Sep 17 00:00:00 2001 From: Tim Hunt Date: Mon, 7 Nov 2011 12:36:19 +0000 Subject: [PATCH 06/21] MDL-30167 qtype_numerical: notice when required unit is not in the answer. --- question/type/numerical/questiontype.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/question/type/numerical/questiontype.php b/question/type/numerical/questiontype.php index 5090b00206a..07433189c02 100644 --- a/question/type/numerical/questiontype.php +++ b/question/type/numerical/questiontype.php @@ -641,16 +641,17 @@ class qtype_numerical_answer_processor { $numberstring = $matches[0]; if ($this->unitsbefore) { - $unit = substr($response, 0, -strlen($numberstring)); + // substr returns false when it means '', so cast back to string. + $unit = (string) substr($response, 0, -strlen($numberstring)); } else { - $unit = substr($response, strlen($numberstring)); + $unit = (string) substr($response, strlen($numberstring)); } if (!is_null($separateunit)) { $unit = $separateunit; } - if ($unit && $this->is_known_unit($unit)) { + if ($this->is_known_unit($unit)) { $multiplier = 1 / $this->units[$unit]; } else { $multiplier = null; From f7094147b14befe00600eae4eb10c4bd8535e1a0 Mon Sep 17 00:00:00 2001 From: Tim Hunt Date: Tue, 8 Nov 2011 15:57:18 +0000 Subject: [PATCH 07/21] MDL-30186 qtype editing forms should use advcheckbox. --- question/type/edit_question_form.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/question/type/edit_question_form.php b/question/type/edit_question_form.php index 34f52a80df9..e7505f35edc 100644 --- a/question/type/edit_question_form.php +++ b/question/type/edit_question_form.php @@ -344,7 +344,7 @@ abstract class question_edit_form extends moodleform { $mform->setType($feedbackname, PARAM_RAW); if ($withshownumpartscorrect && $feedbackname == 'partiallycorrectfeedback') { - $mform->addElement('checkbox', 'shownumcorrect', + $mform->addElement('advcheckbox', 'shownumcorrect', get_string('options', 'question'), get_string('shownumpartscorrect', 'question')); } @@ -361,11 +361,11 @@ abstract class question_edit_form extends moodleform { $repeatedoptions['hint']['type'] = PARAM_RAW; if ($withclearwrong) { - $repeated[] = $mform->createElement('checkbox', 'hintclearwrong', + $repeated[] = $mform->createElement('advcheckbox', 'hintclearwrong', get_string('options', 'question'), get_string('clearwrongparts', 'question')); } if ($withshownumpartscorrect) { - $repeated[] = $mform->createElement('checkbox', 'hintshownumcorrect', '', + $repeated[] = $mform->createElement('advcheckbox', 'hintshownumcorrect', '', get_string('shownumpartscorrect', 'question')); } From 0f7477c07f7b69189e7477c00e44a6cab1cd91a6 Mon Sep 17 00:00:00 2001 From: Tim Hunt Date: Wed, 9 Nov 2011 12:51:01 +0000 Subject: [PATCH 08/21] MDL-30199 qtype numerical etc. Don't require tolerance for answer *. --- question/type/numerical/edit_numerical_form.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/question/type/numerical/edit_numerical_form.php b/question/type/numerical/edit_numerical_form.php index 512f6949581..2775ef0b8d5 100644 --- a/question/type/numerical/edit_numerical_form.php +++ b/question/type/numerical/edit_numerical_form.php @@ -264,7 +264,7 @@ class qtype_numerical_edit_form extends question_edit_form { if ($data['fraction'][$key] == 1) { $maxgrade = true; } - if (!is_numeric($data['tolerance'][$key])) { + if ($answer !== '*' && !is_numeric($data['tolerance'][$key])) { $errors['tolerance['.$key.']'] = get_string('mustbenumeric', 'qtype_calculated'); } From 7238cd2ef0f51fe39478fe5dd7493cc675a50711 Mon Sep 17 00:00:00 2001 From: Tim Hunt Date: Thu, 10 Nov 2011 12:51:24 +0000 Subject: [PATCH 09/21] MDL-30209 quiz refers to wrong rendere method in two places. Thanks to Dan Marsden for working out the fix. --- mod/quiz/startattempt.php | 2 +- mod/quiz/summary.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mod/quiz/startattempt.php b/mod/quiz/startattempt.php index c660df32e93..c3e31d855cd 100644 --- a/mod/quiz/startattempt.php +++ b/mod/quiz/startattempt.php @@ -101,7 +101,7 @@ if ($lastattempt && !$lastattempt->timefinish) { $output = $PAGE->get_renderer('mod_quiz'); if (!$quizobj->is_preview_user() && $messages) { print_error('attempterror', 'quiz', $quizobj->view_url(), - $output->print_messages($messages)); + $output->access_messages($messages)); } if ($accessmanager->is_preflight_check_required($currentattemptid)) { diff --git a/mod/quiz/summary.php b/mod/quiz/summary.php index 065bb8cccb3..869b4b1d75e 100644 --- a/mod/quiz/summary.php +++ b/mod/quiz/summary.php @@ -61,7 +61,7 @@ $messages = $accessmanager->prevent_access(); $output = $PAGE->get_renderer('mod_quiz'); if (!$attemptobj->is_preview_user() && $messages) { print_error('attempterror', 'quiz', $attemptobj->view_url(), - $output->print_messages($messages)); + $output->access_messages($messages)); } if ($accessmanager->is_preflight_check_required($attemptobj->get_attemptid())) { redirect($attemptobj->start_attempt_url(null, $page)); From 08502b574dae47e00b02ab6ef538303d626fd2b9 Mon Sep 17 00:00:00 2001 From: Tim Hunt Date: Wed, 9 Nov 2011 13:56:03 +0000 Subject: [PATCH 10/21] MDL-30182 quiz grade.php should support userid param. --- mod/quiz/attemptlib.php | 9 +++++- mod/quiz/grade.php | 72 ++++++++++++++++++++++++++++++++--------- 2 files changed, 64 insertions(+), 17 deletions(-) diff --git a/mod/quiz/attemptlib.php b/mod/quiz/attemptlib.php index 22dba91fac0..385832d3d3d 100644 --- a/mod/quiz/attemptlib.php +++ b/mod/quiz/attemptlib.php @@ -418,10 +418,17 @@ class quiz_attempt { * @param object $quiz the quiz object for this attempt and user. * @param object $cm the course_module object for this quiz. * @param object $course the row from the course table for the course we belong to. + * @param bool $loadquestions (optional) if true, the default, load all the details + * of the state of each question. Else just set up the basic details of the attempt. */ - public function __construct($attempt, $quiz, $cm, $course) { + public function __construct($attempt, $quiz, $cm, $course, $loadquestions = true) { $this->attempt = $attempt; $this->quizobj = new quiz($quiz, $cm, $course); + + if (!$loadquestions) { + return; + } + $this->quba = question_engine::load_questions_usage_by_activity($this->attempt->uniqueid); $this->determine_layout(); $this->number_questions(); diff --git a/mod/quiz/grade.php b/mod/quiz/grade.php index dd2b22cbebc..9334731706f 100644 --- a/mod/quiz/grade.php +++ b/mod/quiz/grade.php @@ -30,23 +30,63 @@ require_once($CFG->dirroot . '/mod/quiz/report/reportlib.php'); $id = required_param('id', PARAM_INT); +$userid = optional_param('userid', 0, PARAM_INT); -if (!$cm = get_coursemodule_from_id('quiz', $id)) { - print_error('invalidcoursemodule'); -} -if (!$quiz = $DB->get_record('quiz', array('id' => $cm->instance))) { - print_error('invalidquizid'); -} -if (!$course = $DB->get_record('course', array('id' => $quiz->course))) { - print_error('coursemisconf'); -} - +$cm = get_coursemodule_from_id('quiz', $id, 0, false, MUST_EXIST); +$course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST); +$quiz = $DB->get_record('quiz', array('id' => $cm->instance), '*', MUST_EXIST); require_login($course, false, $cm); -$reportlist = quiz_report_list(get_context_instance(CONTEXT_MODULE, $cm->id)); -if (!empty($reportlist)) { - redirect(new moodle_url('/mod/quiz/report.php', array( - 'id' => $cm->id, 'mode' => reset($reportlist)))); -} else { - redirect(new moodle_url('/mod/quiz/view.php', array('id' => $cm->id))); +$reportlist = quiz_report_list(context_module::instance($cm->id)); +if (empty($reportlist) || $userid == $USER->id) { + // If the user cannot see reports, or can see reports but is looking + // at their own grades, redirect them to the view.php page. + // (The looking at their own grades case is unlikely, since users who + // appear in the gradebook are unlikely to be able to see quiz reports, + // but it is possible.) + redirect(new moodle_url('/mod/quiz/view.php', array('id' => $cm->id))); } + +// Now we know the user is interested in reports. If they are interested in a +// specific other user, try to send them to the most appropriate attempt review page. +if ($userid) { + + // Work out which attempt is most significant from a grading point of view. + $attempts = quiz_get_user_attempts($quiz->id, $userid, 'finished'); + $attempt = null; + switch ($quiz->grademethod) { + case QUIZ_ATTEMPTFIRST: + $attempt = reset($attempts); + break; + + case QUIZ_ATTEMPTLAST: + case QUIZ_GRADEAVERAGE: + $attempt = end($attempts); + break; + + case QUIZ_GRADEHIGHEST: + $maxmark = 0; + foreach ($attempts as $at) { + // >=, since we want to most recent relevant attempt. + if ((float) $at->sumgrades >= $maxmark) { + $maxmark = $at->sumgrades; + $attempt = $at; + } + } + break; + } + + // If the user can review the relevant attempt, redirect to it. + if ($attempt) { + $attemptobj = new quiz_attempt($attempt, $quiz, $cm, $course, false); + if ($attemptobj->is_review_allowed()) { + redirect($attemptobj->review_url()); + } + } + + // Otherwise, fall thorugh to the generic case. +} + +// Send the user to the first report they can see. +redirect(new moodle_url('/mod/quiz/report.php', array( + 'id' => $cm->id, 'mode' => reset($reportlist)))); From 0c9cb1bc1997730bfcc48bd689c15fc9e0bbb7d6 Mon Sep 17 00:00:00 2001 From: sam marshall Date: Tue, 15 Nov 2011 10:27:10 +0000 Subject: [PATCH 11/21] MDL-30266 completionlib fix unit test breakage (regression) --- lib/simpletest/testcompletionlib.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/simpletest/testcompletionlib.php b/lib/simpletest/testcompletionlib.php index f4288fd9eb0..c78063be010 100644 --- a/lib/simpletest/testcompletionlib.php +++ b/lib/simpletest/testcompletionlib.php @@ -527,7 +527,7 @@ WHERE $c->__construct((object)array('id'=>42)); // 1) Basic usage - $c->expectAt(0,'get_tracked_users',array(false, array(), 0, '', '', '')); + $c->expectAt(0,'get_tracked_users',array(false, array(), 0, '', '', '', null)); $c->setReturnValueAt(0,'get_tracked_users',array( (object)array('id'=>100,'firstname'=>'Woot','lastname'=>'Plugh'), (object)array('id'=>201,'firstname'=>'Vroom','lastname'=>'Xyzzy'), @@ -556,7 +556,7 @@ WHERE ),$c->get_progress_all(false)); // 2) With more than 1,000 results - $c->expectAt(1,'get_tracked_users',array(true, 3, 0, '', '', '')); + $c->expectAt(1,'get_tracked_users',array(true, 3, 0, '', '', '', null)); $tracked=array(); $ids=array(); From 4a645a682120adbec21a597abecf786cf25cbb83 Mon Sep 17 00:00:00 2001 From: Andrew Robert Nicols Date: Tue, 15 Nov 2011 15:16:47 +0000 Subject: [PATCH 12/21] MDL-30274 Correct typo of loginpage variable --- theme/mymobile/renderers.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/theme/mymobile/renderers.php b/theme/mymobile/renderers.php index f7c253c5275..3007930d3c9 100644 --- a/theme/mymobile/renderers.php +++ b/theme/mymobile/renderers.php @@ -380,7 +380,7 @@ class theme_mymobile_core_renderer extends core_renderer { return ''; } - $loginapge = ((string)$this->page->url === get_login_url()); + $loginpage = ((string)$this->page->url === get_login_url()); $course = $this->page->course; if (session_is_loggedinas()) { @@ -407,7 +407,7 @@ class theme_mymobile_core_renderer extends core_renderer { } if (isguestuser()) { $loggedinas = $realuserinfo.get_string('loggedinasguest'); - if (!$loginapge) { + if (!$loginpage) { $loggedinas .= " (".get_string('login').')'; } } else if (is_role_switched($course->id)) { // Has switched roles @@ -421,7 +421,7 @@ class theme_mymobile_core_renderer extends core_renderer { } } else { $loggedinas = get_string('loggedinnot', 'moodle'); - if (!$loginapge) { + if (!$loginpage) { $loggedinas .= " (".get_string('login').')'; } } From 24ad1d1feb8ecf173bf036671644b10691080bae Mon Sep 17 00:00:00 2001 From: sam marshall Date: Tue, 15 Nov 2011 15:24:08 +0000 Subject: [PATCH 13/21] MDL-30275 Assignment activity description not displayed on course page --- mod/assignment/lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mod/assignment/lib.php b/mod/assignment/lib.php index 5d4d5fb3ded..0be90a6d383 100644 --- a/mod/assignment/lib.php +++ b/mod/assignment/lib.php @@ -3540,7 +3540,7 @@ function assignment_get_coursemodule_info($coursemodule) { } if ($coursemodule->showdescription) { // Convert intro to html. Do not filter cached version, filters run at display time. - $info->content = format_module_intro('assignment', $assignment, $coursemodule->id, false); + $result->content = format_module_intro('assignment', $assignment, $coursemodule->id, false); } return $result; } else { From 63a1625d788745aa7bce67bcb944f968ce0b7082 Mon Sep 17 00:00:00 2001 From: Ankit Kumar Agarwal Date: Wed, 16 Nov 2011 09:47:00 +0530 Subject: [PATCH 14/21] MDL-30279 SCORM Fixing sql errors during cron --- mod/scorm/lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mod/scorm/lib.php b/mod/scorm/lib.php index b4c84a94fa4..50906fbd4d9 100644 --- a/mod/scorm/lib.php +++ b/mod/scorm/lib.php @@ -510,7 +510,7 @@ function scorm_cron () { $cfg_scorm = get_config('scorm'); if (!empty($cfg_scorm->allowaicchacp)) { $expiretime = time() - ($cfg_scorm->aicchacpkeepsessiondata*24*60*60); - $DB->delete_records_select('scorm_aicc_session', 'WHERE timemodified < ?', array($expiretime)); + $DB->delete_records_select('scorm_aicc_session', 'timemodified < ?', array($expiretime)); } } From e079e82c087becf06d902089d14f3f76686bde19 Mon Sep 17 00:00:00 2001 From: Ankit Kumar Agarwal Date: Thu, 10 Nov 2011 13:46:43 +0530 Subject: [PATCH 15/21] MDL-29893 Fixing issues with password generation function --- lib/moodlelib.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/moodlelib.php b/lib/moodlelib.php index fee53244e8f..b5ea4586750 100644 --- a/lib/moodlelib.php +++ b/lib/moodlelib.php @@ -8725,12 +8725,17 @@ function generate_password($maxlen=10) { $filler1 = $fillers[rand(0, strlen($fillers) - 1)]; $password = $word1 . $filler1 . $word2; } else { - $maxlen = !empty($CFG->minpasswordlength) ? $CFG->minpasswordlength : 0; + $minlen = !empty($CFG->minpasswordlength) ? $CFG->minpasswordlength : 0; $digits = $CFG->minpassworddigits; $lower = $CFG->minpasswordlower; $upper = $CFG->minpasswordupper; $nonalphanum = $CFG->minpasswordnonalphanum; - $additional = $maxlen - ($lower + $upper + $digits + $nonalphanum); + $total = $lower + $upper + $digits + $nonalphanum; + // minlength should be the greater one of the two ( $minlen and $total ) + $minlen = $minlen < $total ? $total : $minlen; + // maxlen can never be smaller than minlen + $maxlen = $minlen > $maxlen ? $minlen : $maxlen; + $additional = $maxlen - $total; // Make sure we have enough characters to fulfill // complexity requirements From 15d660a8fd44249c9237630edfd6ccf399f5a7f1 Mon Sep 17 00:00:00 2001 From: Tim Hunt Date: Wed, 16 Nov 2011 10:52:19 +0000 Subject: [PATCH 16/21] MDL-30300 question behaviours: improve q compatibility API. --- question/behaviour/behaviourbase.php | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/question/behaviour/behaviourbase.php b/question/behaviour/behaviourbase.php index 95c0e2a4dfe..a5f5575dc46 100644 --- a/question/behaviour/behaviourbase.php +++ b/question/behaviour/behaviourbase.php @@ -70,13 +70,22 @@ abstract class question_behaviour { public function __construct(question_attempt $qa, $preferredbehaviour) { $this->qa = $qa; $this->question = $qa->get_question(); - $requiredclass = $this->required_question_definition_type(); - if (!$this->question instanceof $requiredclass) { + if (!$this->is_compatible_question($this->question)) { throw new coding_exception('This behaviour (' . $this->get_name() . ') cannot work with this question (' . get_class($this->question) . ')'); } } + /** + * Some behaviours can only work with certing types of question. This method + * allows the behaviour to verify that a question is compatible. + * @param question_definition $question the question. + */ + public function is_compatible_question(question_definition $question) { + $requiredclass = $this->required_question_definition_type(); + return $this->question instanceof $requiredclass; + } + /** * Most behaviours can only work with {@link question_definition}s * of a particular subtype, or that implement a particular interface. @@ -84,7 +93,9 @@ abstract class question_behaviour { * question passed to the constructor is then checked against this type. * @return string class/interface name. */ - public abstract function required_question_definition_type(); + protected function required_question_definition_type() { + return 'question_definition'; + } /** * @return string the name of this behaviour. For example the name of From 3d17cd3f1ca118ac681074252485aee7ad70b1d8 Mon Sep 17 00:00:00 2001 From: Tim Hunt Date: Wed, 16 Nov 2011 11:07:35 +0000 Subject: [PATCH 17/21] MDL-30300 qbehaviours: convert to the new is_compatible_question API. --- question/behaviour/adaptive/behaviour.php | 4 ++-- question/behaviour/behaviourbase.php | 7 +++++++ question/behaviour/deferredfeedback/behaviour.php | 4 ++-- question/behaviour/immediatefeedback/behaviour.php | 4 ++-- question/behaviour/informationitem/behaviour.php | 4 ++-- question/behaviour/interactive/behaviour.php | 4 ++-- question/behaviour/interactivecountback/behaviour.php | 4 ++-- question/behaviour/missing/behaviour.php | 5 +++-- question/behaviour/upgrade.txt | 7 ++++++- 9 files changed, 28 insertions(+), 15 deletions(-) diff --git a/question/behaviour/adaptive/behaviour.php b/question/behaviour/adaptive/behaviour.php index c663b522268..9144296f543 100644 --- a/question/behaviour/adaptive/behaviour.php +++ b/question/behaviour/adaptive/behaviour.php @@ -38,8 +38,8 @@ defined('MOODLE_INTERNAL') || die(); class qbehaviour_adaptive extends question_behaviour_with_save { const IS_ARCHETYPAL = true; - public function required_question_definition_type() { - return 'question_automatically_gradable'; + public function is_compatible_question(question_definition $question) { + return $question instanceof question_automatically_gradable; } public function get_expected_data() { diff --git a/question/behaviour/behaviourbase.php b/question/behaviour/behaviourbase.php index a5f5575dc46..ca09117def6 100644 --- a/question/behaviour/behaviourbase.php +++ b/question/behaviour/behaviourbase.php @@ -79,6 +79,10 @@ abstract class question_behaviour { /** * Some behaviours can only work with certing types of question. This method * allows the behaviour to verify that a question is compatible. + * + * This implementation is only provided for backwards-compatibility. You should + * override this method if you are implementing a behaviour. + * * @param question_definition $question the question. */ public function is_compatible_question(question_definition $question) { @@ -91,6 +95,9 @@ abstract class question_behaviour { * of a particular subtype, or that implement a particular interface. * This method lets the behaviour document that. The type of * question passed to the constructor is then checked against this type. + * + * @deprecated since 2.2. Please use/override {@link is_compatible_question()} instead. + * * @return string class/interface name. */ protected function required_question_definition_type() { diff --git a/question/behaviour/deferredfeedback/behaviour.php b/question/behaviour/deferredfeedback/behaviour.php index 8bc59fc7a70..5c5de7a31ee 100644 --- a/question/behaviour/deferredfeedback/behaviour.php +++ b/question/behaviour/deferredfeedback/behaviour.php @@ -40,8 +40,8 @@ defined('MOODLE_INTERNAL') || die(); class qbehaviour_deferredfeedback extends question_behaviour_with_save { const IS_ARCHETYPAL = true; - public function required_question_definition_type() { - return 'question_automatically_gradable'; + public function is_compatible_question(question_definition $question) { + return $question instanceof question_automatically_gradable; } public static function get_unused_display_options() { diff --git a/question/behaviour/immediatefeedback/behaviour.php b/question/behaviour/immediatefeedback/behaviour.php index 2e7bbe02655..f12db5d90f4 100644 --- a/question/behaviour/immediatefeedback/behaviour.php +++ b/question/behaviour/immediatefeedback/behaviour.php @@ -42,8 +42,8 @@ defined('MOODLE_INTERNAL') || die(); class qbehaviour_immediatefeedback extends question_behaviour_with_save { const IS_ARCHETYPAL = true; - public function required_question_definition_type() { - return 'question_automatically_gradable'; + public function is_compatible_question(question_definition $question) { + return $question instanceof question_automatically_gradable; } public function get_min_fraction() { diff --git a/question/behaviour/informationitem/behaviour.php b/question/behaviour/informationitem/behaviour.php index 8c2cefed705..472a6e258c4 100644 --- a/question/behaviour/informationitem/behaviour.php +++ b/question/behaviour/informationitem/behaviour.php @@ -39,8 +39,8 @@ defined('MOODLE_INTERNAL') || die(); */ class qbehaviour_informationitem extends question_behaviour { - public function required_question_definition_type() { - return 'question_definition'; + public function is_compatible_question(question_definition $question) { + return true; } public function get_expected_data() { diff --git a/question/behaviour/interactive/behaviour.php b/question/behaviour/interactive/behaviour.php index 976bb08e95f..27e0b303ba4 100644 --- a/question/behaviour/interactive/behaviour.php +++ b/question/behaviour/interactive/behaviour.php @@ -52,8 +52,8 @@ class qbehaviour_interactive extends question_behaviour_with_save { */ const READONLY_EXCEPT_TRY_AGAIN = 23485299; - public function required_question_definition_type() { - return 'question_automatically_gradable'; + public function is_compatible_question(question_definition $question) { + return $question instanceof question_automatically_gradable; } public function get_right_answer_summary() { diff --git a/question/behaviour/interactivecountback/behaviour.php b/question/behaviour/interactivecountback/behaviour.php index 5b3e7f44164..8a14cb76818 100644 --- a/question/behaviour/interactivecountback/behaviour.php +++ b/question/behaviour/interactivecountback/behaviour.php @@ -64,8 +64,8 @@ require_once(dirname(__FILE__) . '/../interactive/behaviour.php'); class qbehaviour_interactivecountback extends qbehaviour_interactive { const IS_ARCHETYPAL = false; - public function required_question_definition_type() { - return 'question_automatically_gradable_with_countback'; + public function is_compatible_question(question_definition $question) { + return $question instanceof question_automatically_gradable_with_countback; } protected function adjust_fraction($fraction, question_attempt_pending_step $pendingstep) { diff --git a/question/behaviour/missing/behaviour.php b/question/behaviour/missing/behaviour.php index 1726e011166..3475040a767 100644 --- a/question/behaviour/missing/behaviour.php +++ b/question/behaviour/missing/behaviour.php @@ -45,8 +45,9 @@ defined('MOODLE_INTERNAL') || die(); * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class qbehaviour_missing extends question_behaviour { - public function required_question_definition_type() { - return 'question_definition'; + + public function is_compatible_question(question_definition $question) { + return true; } public function summarise_action(question_attempt_step $step) { diff --git a/question/behaviour/upgrade.txt b/question/behaviour/upgrade.txt index db780e8dbcd..63b941ee3de 100644 --- a/question/behaviour/upgrade.txt +++ b/question/behaviour/upgrade.txt @@ -2,10 +2,15 @@ This files describes API changes for question behaviour plugins. === 2.2 === -* The old +1) The old public static function get_required_behaviours() method is no more. Instead use the ->dependencies facility in version.php. E.g. $plugin->dependencies = array( 'qbehaviour_immediatefeedback' => 2011102700, 'qbehaviour_deferredcbm' => 2011102700 ); + +2) The old required_question_definition_type method has been replaced by a new +is_compatible_question method. You should change your behaviour to override the +new method, not the old one. This change has been implemented in a +backwards-compatible way, so behaviours will not break. From 7a25d39873fefe768f795a9a29b46d0ff74b79d4 Mon Sep 17 00:00:00 2001 From: Nadav Kavalerchik Date: Thu, 17 Nov 2011 11:28:07 +1300 Subject: [PATCH 18/21] MDL-27516 Several CSS fixes for right to left languages --- mod/quiz/styles.css | 9 ++++- mod/wiki/styles.css | 4 ++ theme/base/style/core.css | 69 +++++++++++++++++++++++++++++++++++ theme/base/style/course.css | 2 +- theme/standard/style/core.css | 2 + webservice/renderer.php | 13 ++++++- 6 files changed, 95 insertions(+), 4 deletions(-) diff --git a/mod/quiz/styles.css b/mod/quiz/styles.css index 60d83d46150..f96340959e2 100644 --- a/mod/quiz/styles.css +++ b/mod/quiz/styles.css @@ -96,6 +96,13 @@ div.editq div.question div.content .singlequestion a .questiontext{text-decorati #page-mod-quiz-mod #reviewoptionshdr fieldset.fgroup span label, #adminquizreviewoptions span label {margin-left: 0.4em;} +#page-mod-quiz-mod.dir-rtl #reviewoptionshdr .fitem, +#adminquizreviewoptions .group {float: right; width: 24%;} +#page-mod-quiz-mod.dir-rtl #reviewoptionshdr fieldset.fgroup span, +#adminquizreviewoptions span {float: right; clear: right;} +#page-mod-quiz-mod.dir-rtl #reviewoptionshdr .fitemtitle, +#adminquizreviewoptions .fitemtitle {text-align: right;} + /** Mod quiz view **/ #page-mod-quiz-view .quizinfo, #page-mod-quiz-view #page .quizgradefeedback, @@ -377,4 +384,4 @@ bank window's title is prominent enough*/ .qnum label {padding-right: 0.25em;} /** settings.php */ -#adminquizreviewoptions {margin-bottom: 0.5em;} +#adminquizreviewoptions {margin-bottom: 0.5em;} \ No newline at end of file diff --git a/mod/wiki/styles.css b/mod/wiki/styles.css index 18e0391422e..dcfd4804bbd 100644 --- a/mod/wiki/styles.css +++ b/mod/wiki/styles.css @@ -171,6 +171,10 @@ float: right; } +.dir-rtl .wiki_diffuserleft { + float: left; +} + .wiki_diffuserright { float: left; } diff --git a/theme/base/style/core.css b/theme/base/style/core.css index 4976044d817..3abeb99b9cf 100644 --- a/theme/base/style/core.css +++ b/theme/base/style/core.css @@ -218,6 +218,8 @@ a.skip:active {position: static;display: block;} .mform .ftags label.accesshide {display: block;position: static;} .mform .ftags select {margin-bottom: 0.7em;min-width: 22em;} +input#id_externalurl {direction:ltr;} + /** Browser corrections for mforms **/ .ie .mform .fitem .felement {margin-left:0;text-align:left;float:left;} /** Fix IE double margin + float bugs **/ @@ -720,6 +722,23 @@ body.tag .managelink {padding: 5px;} .mod-indent-15, .mod-indent-huge {margin-left:300px;} +.dir-rtl .mod-indent-1 {margin-right:20px;margin-left:0;} +.dir-rtl .mod-indent-2 {margin-right:40px;margin-left:0;} +.dir-rtl .mod-indent-3 {margin-right:60px;margin-left:0;} +.dir-rtl .mod-indent-4 {margin-right:80px;margin-left:0;} +.dir-rtl .mod-indent-5 {margin-right:100px;margin-left:0;} +.dir-rtl .mod-indent-6 {margin-right:120px;margin-left:0;} +.dir-rtl .mod-indent-7 {margin-right:140px;margin-left:0;} +.dir-rtl .mod-indent-8 {margin-right:160px;margin-left:0;} +.dir-rtl .mod-indent-9 {margin-right:180px;margin-left:0;} +.dir-rtl .mod-indent-10 {margin-right:200px;margin-left:0;} +.dir-rtl .mod-indent-11 {margin-right:220px;margin-left:0;} +.dir-rtl .mod-indent-12 {margin-right:240px;margin-left:0;} +.dir-rtl .mod-indent-13 {margin-right:260px;margin-left:0;} +.dir-rtl .mod-indent-14 {margin-right:280px;margin-left:0;} +.dir-rtl .mod-indent-15, +.dir-rtl .mod-indent-huge {margin-right:300px;margin-left:0;} + .dir-rtl .felement.feditor select {margin-right:18.75%;} /* Resourcelib mp3 player size: only width could be changed here, height hardcoded in JS */ @@ -804,3 +823,53 @@ ul li, ol li, .course-content ul.weeks .content .summary ol li, .course-content ul.topics .content .summary ol li {list-style: decimal outside none;} + +.dir-rtl #adminsettings #id_s__pathtodu, +.dir-rtl #adminsettings #id_s__aspellpath, +.dir-rtl #adminsettings #id_s__pathtodot, +.dir-rtl #adminsettings #id_s__supportemail, +.dir-rtl #adminsettings #id_s__supportpage, +.dir-rtl #adminsettings #id_s__sessioncookie, +.dir-rtl #adminsettings #id_s__sessioncookiepath, +.dir-rtl #adminsettings #id_s__sessioncookiedomain, +.dir-rtl #adminsettings #id_s__proxyhost, +.dir-rtl #adminsettings #id_s__proxyuser, +.dir-rtl #adminsettings #id_s__proxypassword, +.dir-rtl #adminsettings #id_s__proxybypass, +.dir-rtl #adminsettings #id_s__jabberhost, +.dir-rtl #adminsettings #id_s__jabberserver, +.dir-rtl #adminsettings #id_s__jabberusername, +.dir-rtl #adminsettings #id_s__jabberpassword, +.dir-rtl #adminsettings #id_s__additionalhtmlhead, +.dir-rtl #adminsettings #id_s__additionalhtmltopofbody, +.dir-rtl #adminsettings #id_s__additionalhtmlfooter, +.dir-rtl #adminsettings #id_s__docroot, +.dir-rtl #adminsettings #id_s__filter_tex_latexpreamble, +.dir-rtl #adminsettings #id_s__filter_tex_latexbackground, +.dir-rtl #adminsettings #id_s__filter_tex_pathlatex, +.dir-rtl #adminsettings #id_s__filter_tex_pathdvips, +.dir-rtl #adminsettings #id_s__filter_tex_pathconvert, +.dir-rtl #adminsettings #id_s__blockedip, +.dir-rtl #adminsettings #id_s__pathtoclam, +.dir-rtl #adminsettings #id_s__quarantinedir, +.dir-rtl #adminsettings #id_s__sitepolicy, +.dir-rtl #adminsettings #id_s__sitepolicyguest, +.dir-rtl #adminsettings #id_s__cronremotepassword, +.dir-rtl #adminsettings #id_s__allowedip, +.dir-rtl #adminsettings #id_s__blockedip, +.dir-rtl #adminsettings #id_s_enrol_meta_nosyncroleids, +.dir-rtl #adminsettings #id_s_enrol_ldap_host_url, +.dir-rtl #adminsettings #id_s_enrol_ldap_ldapencoding, +.dir-rtl #adminsettings #id_s_enrol_ldap_bind_dn, +.dir-rtl #adminsettings #id_s_enrol_ldap_bind_pw, +.dir-rtl #adminsettings #admin-emoticons .form-text, +.dir-rtl #adminsettings #admin-role_mapping input[type=text], +.dir-rtl #adminsettings #id_s_enrol_paypal_paypalbusiness, +.dir-rtl #adminsettings #id_s_enrol_flatfile_location, +#page-admin-setting-enrolsettingsflatfile.dir-rtl input[type=text], +#page-admin-setting-enrolsettingsdatabase.dir-rtl input[type=text], +#page-admin-auth-db.dir-rtl input[type=text] {direction: ltr;} + +#page-admin-setting-enrolsettingsflatfile.dir-rtl .informationbox {direction: ltr;text-align: left;} + +#page-admin-grade-edit-scale-edit.dir-rtl .error input#id_name {margin-right: 170px;} \ No newline at end of file diff --git a/theme/base/style/course.css b/theme/base/style/course.css index 3062ac629a0..37f9792bf87 100644 --- a/theme/base/style/course.css +++ b/theme/base/style/course.css @@ -27,7 +27,7 @@ .path-course-view li.activity form.togglecompletion .ajaxworking {position:absolute;top:0; left:20px;width: 20px; height: 20px;background: url([[pix:i/ajaxloader]]) no-repeat;} .dir-rtl.path-course-view li.activity {margin-right:0px;margin-left:20px;} .dir-rtl.path-course-view li.activity form.togglecompletion, -.dir-rtl.path-course-view li.activity span.autocompletion {right:auto;left:-20px;} +.dir-rtl.path-course-view li.activity span.autocompletion {right:auto;right:-20px;} .section img.movetarget {height:16px;width:80px;} diff --git a/theme/standard/style/core.css b/theme/standard/style/core.css index 12cf9d88514..4b69618ca9f 100644 --- a/theme/standard/style/core.css +++ b/theme/standard/style/core.css @@ -277,6 +277,8 @@ h2.tag-heading {text-align:center;margin-left:auto;margin-right:auto;width:95%;} #tags-management-links, .tag .managelink {text-align:right;} table#tag-management-list {margin: 10px auto;width: 80%;} +#page-tag-index.dir-rtl .relatedpages {text-align:center;} +#page-tag-index.dir-rtl .user-box {float:right;} /** * Overriding base diff --git a/webservice/renderer.php b/webservice/renderer.php index 37b993561ff..75668fd6a8a 100644 --- a/webservice/renderer.php +++ b/webservice/renderer.php @@ -46,15 +46,24 @@ class core_webservice_renderer extends plugin_renderer_base { $table->cellspacing = 0; $table->cellpadding = 0; + // LTR/RTL support, for drawing button arrows in the right direction + if (right_to_left()) { + $addarrow = '▶'; + $removearrow = '◀'; + } else { + $addarrow = '◀'; + $removearrow = '▶'; + } + //create the add and remove button $addinput = html_writer::empty_tag('input', array('name' => 'add', 'id' => 'add', 'type' => 'submit', - 'value' => '◀' . ' ' . get_string('add'), + 'value' => $addarrow . ' ' . get_string('add'), 'title' => get_string('add'))); $addbutton = html_writer::tag('div', $addinput, array('id' => 'addcontrols')); $removeinput = html_writer::empty_tag('input', array('name' => 'remove', 'id' => 'remove', 'type' => 'submit', - 'value' => '▶' . ' ' . get_string('remove'), + 'value' => $removearrow . ' ' . get_string('remove'), 'title' => get_string('remove'))); $removebutton = html_writer::tag('div', $removeinput, array('id' => 'removecontrols')); From 0850e6301a7abb9b9f2a72cffdb9cc39eeb0e8b6 Mon Sep 17 00:00:00 2001 From: Tim Hunt Date: Thu, 17 Nov 2011 08:02:20 +0000 Subject: [PATCH 19/21] MDL-30182 fix missing include. Sorry. --- mod/quiz/grade.php | 1 + 1 file changed, 1 insertion(+) diff --git a/mod/quiz/grade.php b/mod/quiz/grade.php index 9334731706f..ddc8c07ef91 100644 --- a/mod/quiz/grade.php +++ b/mod/quiz/grade.php @@ -26,6 +26,7 @@ require_once(dirname(__FILE__) . '/../../config.php'); +require_once($CFG->dirroot . '/mod/quiz/locallib.php'); require_once($CFG->dirroot . '/mod/quiz/report/reportlib.php'); From 8a9426bc17e4cd38bddafc5870f2a9c631c50cc7 Mon Sep 17 00:00:00 2001 From: "Eloy Lafuente (stronk7)" Date: Thu, 17 Nov 2011 20:10:02 +0100 Subject: [PATCH 20/21] MDL-29350 Prevent memory/time problems if there are zillions of combinations --- lib/db/upgrade.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/db/upgrade.php b/lib/db/upgrade.php index 097cfb10066..75e30882706 100644 --- a/lib/db/upgrade.php +++ b/lib/db/upgrade.php @@ -6917,15 +6917,17 @@ FROM } if ($oldversion < 2011111500.01) { + upgrade_set_timeout(60*20); // this may take a while // Remove duplicate entries from groupings_groups table $sql = 'SELECT MIN(id) AS firstid, groupingid, groupid FROM {groupings_groups} '. 'GROUP BY groupingid, groupid HAVING COUNT(id)>1'; - $badrecs = $DB->get_records_sql($sql); - foreach ($badrecs as $badrec) { + $badrs = $DB->get_recordset_sql($sql); + foreach ($badrs as $badrec) { $where = 'groupingid = ? and groupid = ? and id > ?'; $params = array($badrec->groupingid, $badrec->groupid, $badrec->firstid); $DB->delete_records_select('groupings_groups', $where, $params); } + $badrs->close(); // Main savepoint reached upgrade_main_savepoint(true, 2011111500.01); From fe41ba7489f5a44e7325d20442e01751c7736d0a Mon Sep 17 00:00:00 2001 From: "Eloy Lafuente (stronk7)" Date: Fri, 18 Nov 2011 01:20:35 +0100 Subject: [PATCH 21/21] on-demand release 2.2beta --- version.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/version.php b/version.php index 19816d1a81f..9642f623bed 100644 --- a/version.php +++ b/version.php @@ -30,10 +30,10 @@ defined('MOODLE_INTERNAL') || die(); -$version = 2011111500.01; // YYYYMMDD = weekly release date of this DEV branch +$version = 2011111800.00; // YYYYMMDD = weekly release date of this DEV branch // RR = release increments - 00 in DEV branches // .XX = incremental changes -$release = '2.2beta (Build: 20111115)';// Human-friendly version name +$release = '2.2beta (Build: 20111118)';// Human-friendly version name $maturity = MATURITY_BETA; // this version's maturity level