';
echo '
';
echo $reordercheckboxlabel;
- print_question_icon($question);
+ echo print_question_icon($question);
print_random_option_icon($question);
if ($questioncount == 0) {
diff --git a/mod/quiz/grade.php b/mod/quiz/grade.php
index dd2b22cbebc..ddc8c07ef91 100644
--- a/mod/quiz/grade.php
+++ b/mod/quiz/grade.php
@@ -26,27 +26,68 @@
require_once(dirname(__FILE__) . '/../../config.php');
+require_once($CFG->dirroot . '/mod/quiz/locallib.php');
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))));
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');
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/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/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/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));
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));
}
}
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/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 95c0e2a4dfe..ca09117def6 100644
--- a/question/behaviour/behaviourbase.php
+++ b/question/behaviour/behaviourbase.php
@@ -70,21 +70,39 @@ 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.
+ *
+ * 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) {
+ $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.
* 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.
*/
- 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
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.
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/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') {
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));
+ }
+}
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'));
}
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');
}
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;
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/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').')';
}
}
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/version.php b/version.php
index eb0a3297af2..9642f623bed 100644
--- a/version.php
+++ b/version.php
@@ -30,10 +30,10 @@
defined('MOODLE_INTERNAL') || die();
-$version = 2011111500.00; // 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
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'));