diff --git a/lang/en_utf8/question.php b/lang/en_utf8/question.php
index b7e08fce5e3..97c5c3bc73c 100644
--- a/lang/en_utf8/question.php
+++ b/lang/en_utf8/question.php
@@ -44,6 +44,8 @@ $string['categorycurrent'] = 'Current Category';
$string['categorycurrentuse'] = 'Use This Category';
$string['categorymoveto'] = 'Save in Category';
$string['changepublishstatuscat'] = 'caturl\">Category \"$a->name\" in course \"$a->coursename\" will have it\'s sharing status changed from $a->changefrom to $a->changeto.';
+$string['clicktoflag'] = 'Click to flag this question';
+$string['clicktounflag'] = 'Click to un-flag this question';
$string['cwrqpfs'] = 'Random questions selecting questions from sub categories.';
$string['cwrqpfsinfo'] = '
During the upgrade to Moodle 1.9 we will separate question categories into
different contexts. Some question categories and questions on your site will have to have their sharing
@@ -86,6 +88,8 @@ $string['exporterror'] = 'Errors occur during exporting!';
$string['filesareasite']= 'the site files area';
$string['filesareacourse']= 'the course files area';
$string['filestomove']= 'Move / copy files to $a?';
+$string['flagged'] = 'Flagged';
+$string['flagthisquestion'] = 'Flag this question';
$string['formquestionnotinids'] = 'Form contained question that is not in questionids';
$string['fractionsnomax'] = 'One of the answers should have a score of 100%% so it is possible to get full marks for this question.';
$string['getcategoryfromfile'] = 'Get category from file';
@@ -123,6 +127,7 @@ $string['nopermissionadd'] = 'You don\'t have permission to add questions here.'
$string['noprobs'] = 'No problems found in your question database.';
$string['notenoughdatatoeditaquestion'] = 'Neither a question id, nor a category id and question type, was specified.';
$string['notenoughdatatomovequestions'] = 'You need to provide the question ids of questions you want to move.';
+$string['notflagged'] = 'Not flagged';
$string['novirtualquestiontype'] = 'No virtual question type for question type $a';
$string['parenthesisinproperstart'] = 'Parenthesis before ** is not properly started in $a**';
$string['parenthesisinproperclose'] = 'Parenthesis before ** is not properly closed in $a**';
diff --git a/lang/en_utf8/role.php b/lang/en_utf8/role.php
index 2f6ba30357c..471ec5212b2 100644
--- a/lang/en_utf8/role.php
+++ b/lang/en_utf8/role.php
@@ -110,6 +110,7 @@ $string['question:add'] = 'Add new questions';
$string['question:config'] = 'Configure question types';
$string['question:editall'] = 'Edit all questions';
$string['question:editmine'] = 'Edit your own questions';
+$string['question:flag'] = 'Flag questions while attempting them';
$string['question:managecategory'] = 'Edit question categories';
$string['question:moveall'] = 'Move all questions';
$string['question:movemine'] = 'Move your own questions';
diff --git a/lib/db/access.php b/lib/db/access.php
index c4c5c938a54..5a9ccfc415a 100644
--- a/lib/db/access.php
+++ b/lib/db/access.php
@@ -1002,8 +1002,20 @@ $moodle_capabilities = array(
)
),
- 'moodle/site:doclinks' => array(
+ // While attempting questions, the ability to flag particular questions for later reference.
+ 'moodle/question:flag' => array(
+ 'captype' => 'write',
+ 'contextlevel' => CONTEXT_COURSE,
+ 'legacy' => array(
+ 'student' => CAP_ALLOW,
+ 'teacher' => CAP_ALLOW,
+ 'editingteacher' => CAP_ALLOW,
+ 'coursecreator' => CAP_ALLOW,
+ 'admin' => CAP_ALLOW
+ )
+ ),
+ 'moodle/site:doclinks' => array(
'captype' => 'read',
'contextlevel' => CONTEXT_SYSTEM,
'legacy' => array(
diff --git a/lib/db/install.xml b/lib/db/install.xml
index 707fa3318bb..dda246b2840 100644
--- a/lib/db/install.xml
+++ b/lib/db/install.xml
@@ -1043,7 +1043,8 @@
-
+
+
diff --git a/lib/db/upgrade.php b/lib/db/upgrade.php
index ff96c0a0111..00f20b31d34 100644
--- a/lib/db/upgrade.php
+++ b/lib/db/upgrade.php
@@ -721,6 +721,22 @@ function xmldb_main_upgrade($oldversion) {
upgrade_main_savepoint($result, 2008082602);
}
+ if ($result && $oldversion < 2008082700) {
+ /// Add a new column to the question sessions table to record whether a
+ /// question has been flagged.
+
+ /// Define field flagged to be added to question_sessions
+ $table = new xmldb_table('question_sessions');
+ $field = new xmldb_field('flagged', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, null, null, '0', 'manualcomment');
+
+ /// Conditionally launch add field flagged
+ if (!$dbman->field_exists($table, $field)) {
+ $dbman->add_field($table, $field);
+ }
+
+ /// Main savepoint reached
+ upgrade_main_savepoint($result, 2008082700);
+ }
return $result;
}
diff --git a/lib/questionlib.php b/lib/questionlib.php
index d5474a22c18..d157c36eb8a 100644
--- a/lib/questionlib.php
+++ b/lib/questionlib.php
@@ -94,17 +94,24 @@ define('QUESTION_PREVIEW_POPUP_OPTIONS', 'scrollbars=yes,resizable=yes,width=700
* is how question is Moodle always worked before version 1.5
*/
define('QUESTION_ADAPTIVE', 1);
+/**#@-*/
-/**
- * options used in forms that move files.
- *
+/**#@+
+ * Options used in forms that move files.
*/
define('QUESTION_FILENOTHINGSELECTED', 0);
define('QUESTION_FILEDONOTHING', 1);
define('QUESTION_FILECOPY', 2);
define('QUESTION_FILEMOVE', 3);
define('QUESTION_FILEMOVELINKSONLY', 4);
+/**#@-*/
+/**#@+
+ * Options for whether flags are shown/editable when rendering questions.
+ */
+define('QUESTION_FLAGSHIDDEN', 0);
+define('QUESTION_FLAGSSHOWN', 1);
+define('QUESTION_FLAGSEDITABLE', 2);
/**#@-*/
/// QTYPES INITIATION //////////////////
@@ -909,7 +916,7 @@ function get_question_states(&$questions, $cmoptions, $attempt, $lastattemptid =
// The question field must be listed first so that it is used as the
// array index in the array returned by $DB->get_records_sql
- $statefields = 'n.questionid as question, s.*, n.sumpenalty, n.manualcomment';
+ $statefields = 'n.questionid as question, s.*, n.sumpenalty, n.manualcomment, n.flagged, n.id as questionsessionid';
// Load the newest states for the questions
$sql = "SELECT $statefields
FROM {question_states} s, {question_sessions} n
@@ -1816,6 +1823,34 @@ function question_format_grade($cmoptions, $grade) {
return format_float($grade, $cmoptions->decimalpoints);
}
+/**
+ * @return string An inline script that creates a JavaScript object storing
+ * various strings and bits of configuration that the scripts in qengine.js need
+ * to get from PHP.
+ */
+function question_init_qenginejs_script() {
+ global $CFG;
+
+ // Get the properties we want into a PHP array first, becase that is easier
+ // to build.
+ $config = array(
+ 'pixpath' => $CFG->pixpath,
+ 'wwwroot' => $CFG->wwwroot,
+ 'flagtooltip' => get_string('clicktoflag', 'question'),
+ 'unflagtooltip' => get_string('clicktounflag', 'question'),
+ 'flaggedalt' => get_string('flagged', 'question'),
+ 'unflaggedalt' => get_string('notflagged', 'question'),
+ );
+
+ // Then generate the script tag.
+ $script = '\n";
+ return $script;
+}
+
/// FUNCTIONS THAT SIMPLY WRAP QUESTIONTYPE METHODS //////////////////////////////////
/**
* Get the HTML that needs to be included in the head tag when the
@@ -1830,15 +1865,23 @@ function question_format_grade($cmoptions, $grade) {
* @return string some HTML code that can go inside the head tag.
*/
function get_html_head_contributions($questionlist, &$questions, &$states) {
- global $QTYPES;
+ global $CFG, $QTYPES;
- $contributions = array();
+ // The question engine's own JavaScript.
+ require_js(array('yui_yahoo','yui_event', 'yui_connection'));
+ require_js($CFG->wwwroot . '/question/qengine.js');
+
+ // An inline script to record various lang strings, etc. that qengine.js needs.
+ $contributions = array(question_init_qenginejs_script());
+
+ // Anything that questions on this page need.
foreach ($questionlist as $questionid) {
$question = $questions[$questionid];
$contributions = array_merge($contributions,
$QTYPES[$question->qtype]->get_html_head_contributions(
$question, $states[$questionid]));
}
+
return implode("\n", array_unique($contributions));
}
@@ -2509,4 +2552,31 @@ function question_get_real_state($state){
}
}
+/**
+ * Update the flagged state of a particular question session.
+ *
+ * @param integer $sessionid question_session id.
+ * @param boolean $newstate the new state for the flag.
+ * @return boolean success or failure.
+ */
+function question_update_flag($sessionid, $newstate) {
+ global $DB;
+ return $DB->set_field('question_sessions', 'flagged', $newstate, array('id' => $sessionid));
+}
+
+/**
+ * @param integer $attemptid the question_attempt id.
+ * @param integer $questionid the question id.
+ * @param integer $sessionid the question_session id.
+ * @param object $user a user, or null to use $USER.
+ * @return string that needs to be sent to question/toggleflag.php for it to work.
+ */
+function question_get_toggleflag_checksum($attemptid, $questionid, $sessionid, $user = null) {
+ if (is_null($user)) {
+ global $USER;
+ $user = $USER;
+ }
+ return md5($attemptid . "_" . $user->secret . "_" . $questionid . "_" . $sessionid);
+}
+
?>
diff --git a/mod/quiz/attemptlib.php b/mod/quiz/attemptlib.php
index 7045b7fb838..53a9942c08c 100644
--- a/mod/quiz/attemptlib.php
+++ b/mod/quiz/attemptlib.php
@@ -497,7 +497,7 @@ class quiz_attempt extends quiz {
* @return object the render options for this user on this attempt.
*/
public function get_render_options($state) {
- return quiz_get_renderoptions($this->quiz->review, $state);
+ return quiz_get_renderoptions($this->quiz, $this->attempt, $this->context, $state);
}
/**
@@ -534,7 +534,7 @@ class quiz_attempt extends quiz {
case QUESTION_EVENTCLOSEANDGRADE:
case QUESTION_EVENTCLOSE:
case QUESTION_EVENTMANUALGRADE:
- $options = quiz_get_renderoptions($this->quiz->review, $this->states[$questionid]);
+ $options = $this->get_render_options($this->states[$questionid]);
if ($options->scores) {
return question_get_feedback_class($state->last_graded->raw_grade /
$this->questions[$questionid]->maxgrade);
@@ -551,6 +551,16 @@ class quiz_attempt extends quiz {
}
}
+ /**
+ * @param integer $questionid question id of a question that belongs to this quiz.
+ * @return boolean whether this question hss been flagged by the attempter.
+ */
+ public function is_question_flagged($questionid) {
+ $this->ensure_state_loaded($questionid);
+ $state = $this->states[$questionid];
+ return $state->flagged;
+ }
+
/**
* Return the grade obtained on a particular question, if the user is permitted to see it.
* You must previously have called load_question_states to load the state data about this question.
@@ -560,7 +570,7 @@ class quiz_attempt extends quiz {
*/
public function get_question_score($questionid) {
$this->ensure_state_loaded($questionid);
- $options = quiz_get_renderoptions($this->quiz->review, $this->states[$questionid]);
+ $options = $this->get_render_options($this->quiz->review, $this->states[$questionid]);
if ($options->scores) {
return quiz_format_grade($this->quiz, $this->states[$questionid]->last_graded->grade);
} else {
@@ -803,12 +813,20 @@ abstract class quiz_nav_panel_base {
abstract protected function get_end_bits();
- protected function get_question_state($question) {
- $state = 'todo'; // TODO MDL-15653
+ protected function get_question_state_classes($question) {
+ // The current status of the question.
+ $classes = $this->attemptobj->get_question_status($question->id);
+
+ // Plus a marker for the current page.
if ($question->_page == $this->page) {
- $state .= ' thispage';
+ $classes .= ' thispage';
}
- return $state;
+
+ // Plus a marker for flagged questions.
+ if ($this->attemptobj->is_question_flagged($question->id)) {
+ $classes .= ' flagged';
+ }
+ return $classes;
}
public function display() {
@@ -833,7 +851,7 @@ class quiz_attempt_nav_panel extends quiz_nav_panel_base {
}
return '';
+ $this->get_question_state_classes($question) . '"' . $onclick . '/>';
}
protected function get_end_bits() {
@@ -853,7 +871,7 @@ class quiz_review_nav_panel extends quiz_nav_panel_base {
protected function get_question_button($number, $question) {
return '' . $number . '';
}
diff --git a/mod/quiz/lib.php b/mod/quiz/lib.php
index 3d966e5ceaa..6d2c6a32afc 100644
--- a/mod/quiz/lib.php
+++ b/mod/quiz/lib.php
@@ -1257,6 +1257,7 @@ function quiz_get_extra_capabilities() {
'moodle/question:movemine',
'moodle/question:moveall',
'moodle/question:managecategory',
+ 'moodle/question:flag',
);
}
diff --git a/mod/quiz/locallib.php b/mod/quiz/locallib.php
index 61565909ed2..17dbc0dbd0a 100644
--- a/mod/quiz/locallib.php
+++ b/mod/quiz/locallib.php
@@ -752,15 +752,38 @@ function quiz_question_preview_button($quiz, $question) {
0, 0, $strpreview, QUESTION_PREVIEW_POPUP_OPTIONS, true);
}
+/**
+ * @param object $attempt the attempt.
+ * @param object $context the quiz context.
+ * @return integer whether flags should be shown/editable to the current user for this attempt.
+ */
+function quiz_get_flag_option($attempt, $context) {
+ global $USER;
+ static $flagmode = null;
+ if (is_null($flagmode)) {
+ if (!has_capability('moodle/question:flag', $context)) {
+ $flagmode = QUESTION_FLAGSHIDDEN;
+ } else if ($attempt->userid == $USER->id) {
+ $flagmode = QUESTION_FLAGSEDITABLE;
+ } else {
+ $flagmode = QUESTION_FLAGSSHOWN;
+ }
+ }
+ return $flagmode;
+}
+
/**
* Determine render options
*
* @param int $reviewoptions
* @param object $state
*/
-function quiz_get_renderoptions($reviewoptions, $state) {
+function quiz_get_renderoptions($quiz, $attempt, $context, $state) {
+ $reviewoptions = $quiz->review;
$options = new stdClass;
+ $options->flags = quiz_get_flag_option($attempt, $context);
+
// Show the question in readonly (review) mode if the question is in
// the closed state
$options->readonly = question_state_is_closed($state);
@@ -791,28 +814,31 @@ function quiz_get_renderoptions($reviewoptions, $state) {
*
* @param object $quiz the quiz instance.
* @param object $attempt the attempt in question.
- * @param $context the roles and permissions context,
- * normally the context for the quiz module instance.
+ * @param $context the quiz module context.
*
* @return object an object with boolean fields responses, scores, feedback,
* correct_responses, solutions and general feedback
*/
-function quiz_get_reviewoptions($quiz, $attempt, $context=null) {
+function quiz_get_reviewoptions($quiz, $attempt, $context) {
+ global $USER;
+
$options = new stdClass;
$options->readonly = true;
+ $options->flags = quiz_get_flag_option($attempt, $context);
+
// Provide the links to the question review and comment script
if (!empty($attempt->id)) {
$options->questionreviewlink = '/mod/quiz/reviewquestion.php?attempt=' . $attempt->id;
}
// Show a link to the comment box only for closed attempts
- if ($attempt->timefinish && !is_null($context) && has_capability('mod/quiz:grade', $context)) {
+ if ($attempt->timefinish && has_capability('mod/quiz:grade', $context)) {
$options->questioncommentlink = '/mod/quiz/comment.php';
}
// Whether to display a response history.
- $canviewreports = !is_null($context) && has_capability('mod/quiz:viewreports', $context);
+ $canviewreports = has_capability('mod/quiz:viewreports', $context);
$options->history = ($canviewreports && !$attempt->preview) ? 'all' : 'graded';
if ($canviewreports && has_capability('moodle/grade:viewhidden', $context) && !$attempt->preview) {
@@ -867,7 +893,7 @@ function quiz_get_reviewoptions($quiz, $attempt, $context=null) {
* at least one of the attempts, the other showing which options are true
* for all attempts.
*/
-function quiz_get_combined_reviewoptions($quiz, $attempts, $context=null) {
+function quiz_get_combined_reviewoptions($quiz, $attempts, $context) {
$fields = array('readonly', 'scores', 'feedback', 'correct_responses', 'solutions', 'generalfeedback', 'overallfeedback');
$someoptions = new stdClass;
$alloptions = new stdClass;
diff --git a/pix/i/flagged.png b/pix/i/flagged.png
new file mode 100644
index 00000000000..1e3bed1fea6
Binary files /dev/null and b/pix/i/flagged.png differ
diff --git a/pix/i/unflagged.png b/pix/i/unflagged.png
new file mode 100644
index 00000000000..16d9362bf96
Binary files /dev/null and b/pix/i/unflagged.png differ
diff --git a/question/preview.php b/question/preview.php
index 19779cb9e3b..1cbdf50ba77 100644
--- a/question/preview.php
+++ b/question/preview.php
@@ -68,10 +68,13 @@
$quiz->review = $CFG->quiz_review;
require_login($courseid, false);
$quiz->course = $courseid;
+ $context = get_context_instance(CONTEXT_COURSE, $courseid);
} else if (!$quiz = $DB->get_record('quiz', array('id' => $quizid))) {
print_error('invalidquizid', 'quiz', '', $quizid);
} else {
- require_login($quiz->course, false, get_coursemodule_from_instance('quiz', $quizid, $quiz->course));
+ $cm = get_coursemodule_from_instance('quiz', $quizid, $quiz->course);
+ require_login($quiz->course, false, $cm);
+ $context = get_context_instance(CONTEXT_MODULE, $cm->id);
}
@@ -187,7 +190,7 @@
}
// TODO: should not use quiz-specific function here
- $options = quiz_get_renderoptions($quiz->review, $curstate);
+ $options = quiz_get_renderoptions($quiz, $attempt, $context, $curstate);
// Fill in the correct responses (unless the question is in readonly mode)
if ($fillcorrect && !$options->readonly) {
diff --git a/question/qengine.js b/question/qengine.js
new file mode 100644
index 00000000000..a72804e40e1
--- /dev/null
+++ b/question/qengine.js
@@ -0,0 +1,38 @@
+// This script, and the YUI libraries that it needs, are inluded by
+// the require_js calls in get_html_head_contributions in lib/questionlib.php.
+
+question_flag_changer = {
+ init_flag: function(checkboxid, postdata) {
+ var checkbox = document.getElementById(checkboxid);
+ checkbox.ajaxpostdata = postdata;
+ checkbox.className += ' jsworking';
+ question_flag_changer.update_image(checkbox);
+ YAHOO.util.Event.addListener(checkbox, 'change', this.checkbox_state_change);
+ YAHOO.util.Event.addListener(checkbox, 'focus', 'blur()');
+ },
+
+ checkbox_state_change: function(e) {
+ var checkbox = e.target ? e.target : e.srcElement;
+ question_flag_changer.update_image(checkbox);
+ var postdata = checkbox.ajaxpostdata
+ if (checkbox.checked) {
+ postdata += '&newstate=1'
+ } else {
+ postdata += '&newstate=0'
+ }
+ YAHOO.util.Connect.asyncRequest('POST', qengine_config.wwwroot + '/question/toggleflag.php', null, postdata);
+ },
+
+ update_image: function(checkbox) {
+ var img = document.getElementById(checkbox.id + 'img');
+ if (checkbox.checked) {
+ img.src = qengine_config.pixpath + '/i/flagged.png';
+ img.alt = qengine_config.flaggedalt;
+ img.title = qengine_config.unflagtooltip;
+ } else {
+ img.src = qengine_config.pixpath + '/i/unflagged.png';
+ img.alt = qengine_config.unflaggedalt;
+ img.title = qengine_config.flagtooltip;
+ }
+ }
+};
diff --git a/question/toggleflag.php b/question/toggleflag.php
new file mode 100644
index 00000000000..d095674dbe6
--- /dev/null
+++ b/question/toggleflag.php
@@ -0,0 +1,48 @@
+libdir.'/questionlib.php');
+
+// Parameters
+$sessionid = required_param('qsid', PARAM_INT);
+$attemptid = required_param('aid', PARAM_INT);
+$questionid = required_param('qid', PARAM_INT);
+$newstate = required_param('newstate', PARAM_BOOL);
+$checksum = required_param('checksum', PARAM_ALPHANUM);
+
+// Check user is logged in.
+require_login();
+
+// Check the sesskey.
+if (!confirm_sesskey()) {
+ echo 'sesskey failure';
+}
+
+// Check the checksum - it is very hard to know who a question session belongs
+// to, so we require that checksum parameter is matches an md5 hash of the
+// three ids and the users username. Since we are only updating a flag, that
+// probably makes it sufficiently difficult for malicious users to toggle
+// other users flags.
+if ($checksum != md5($attemptid . "_" . $USER->secret . "_" . $questionid . "_" . $sessionid)) {
+ echo 'checksum failure';
+}
+
+// Check that the requested session really exists
+$questionsession = $DB->get_record('question_sessions', array('id' => $sessionid,
+ 'attemptid' => $attemptid, 'questionid' => $questionid));
+if (!$questionsession) {
+ echo 'invalid ids';
+}
+
+// Now change state
+if (!question_update_flag($sessionid, $newstate)) {
+ echo 'update failed';
+}
+
+echo 'OK';
+?>
\ No newline at end of file
diff --git a/question/type/question.html b/question/type/question.html
index 9a076528aef..12154dc84e5 100644
--- a/question/type/question.html
+++ b/question/type/question.html
@@ -13,7 +13,8 @@
print_question_formulation_and_controls($question, $state, $cmoptions, $options);
diff --git a/question/type/questiontype.php b/question/type/questiontype.php
index 9eda7b8f8a8..296b98fed1b 100644
--- a/question/type/questiontype.php
+++ b/question/type/questiontype.php
@@ -879,7 +879,69 @@ class default_questiontype {
include "$CFG->dirroot/question/type/question.html";
}
- /*
+ /**
+ * Render the question flag, assuming $flagsoption allows it. You will probably
+ * never need to override this method.
+ *
+ * @param object $question the question
+ * @param object $state its current state
+ * @param integer $flagsoption the option that says whether flags should be displayed.
+ */
+ protected function print_question_flag($question, $state, $flagsoption) {
+ global $CFG;
+ switch ($flagsoption) {
+ case QUESTION_FLAGSSHOWN:
+ $flagcontent = $this->get_question_flag_tag($state->flagged);
+ break;
+ case QUESTION_FLAGSEDITABLE:
+ $id = $question->name_prefix . '_flagged';
+ if ($state->flagged) {
+ $checked = 'checked="checked" ';
+ } else {
+ $checked = '';
+ }
+ $qsid = $state->questionsessionid;
+ $aid = $state->attempt;
+ $qid = $state->question;
+ $checksum = question_get_toggleflag_checksum($aid, $qid, $qsid);
+ $postdata = "qsid=$qsid&aid=$aid&qid=$qid&checksum=$checksum&sesskey=" . sesskey();
+ $flagcontent = '' .
+ '' .
+ "\n" . '";
+ break;
+ default:
+ $flagcontent = '';
+ }
+ if ($flagcontent) {
+ echo '
' . $flagcontent . "
\n";
+ }
+ }
+
+ /**
+ * Work out the actual img tag needed for the flag
+ *
+ * @param boolean $flagged whether the question is currently flagged.
+ * @param string $id an id to be added as an attribute to the img (optional).
+ * @return string the img tag.
+ */
+ protected function get_question_flag_tag($flagged, $id = '') {
+ global $CFG;
+ if ($id) {
+ $id = 'id="' . $id . '" ';
+ }
+ if ($flagged) {
+ $img = 'flagged.png';
+ } else {
+ $img = 'unflagged.png';
+ }
+ return 'pixpath . '/i/' . $img .
+ '" alt="' . get_string('flagthisquestion', 'question') . '" />';
+ }
+
+ /**
* Print history of responses
*
* Used by print_question()
diff --git a/theme/standard/styles_layout.css b/theme/standard/styles_layout.css
index 60ca5ec6db7..c29cf6c6d9d 100644
--- a/theme/standard/styles_layout.css
+++ b/theme/standard/styles_layout.css
@@ -2623,6 +2623,15 @@ body.notes .notesgroup {
.que .info div {
margin-left: 1em;
}
+.que .info .questionflag {
+ margin-top: 1em;
+ margin-right: 1em;
+ text-align: center;
+}
+.que .info .questionflag .jsworking {
+ position: absolute;
+ visibility: hidden;
+}
.que .content {
float: left;
margin: 0;
diff --git a/version.php b/version.php
index 3a91811a51b..581230faaa2 100644
--- a/version.php
+++ b/version.php
@@ -6,7 +6,7 @@
// This is compared against the values stored in the database to determine
// whether upgrades should be performed (see lib/db/*.php)
- $version = 2008082602; // YYYYMMDD = date of the last version bump
+ $version = 2008082702; // YYYYMMDD = date of the last version bump
// XX = daily increments
$release = '2.0 dev (Build: 20080829)'; // Human-friendly version name