Merge branch 'MDL-52037-32-fix' of https://github.com/andrewnicols/moodle into MOODLE_32_STABLE
This commit is contained in:
@@ -127,7 +127,7 @@ class api {
|
||||
'rememberusername' => $CFG->rememberusername,
|
||||
'authloginviaemail' => $CFG->authloginviaemail,
|
||||
'registerauth' => $CFG->registerauth,
|
||||
'forgottenpasswordurl' => $CFG->forgottenpasswordurl,
|
||||
'forgottenpasswordurl' => clean_param($CFG->forgottenpasswordurl, PARAM_URL), // We may expect a mailto: here.
|
||||
'authinstructions' => $authinstructions,
|
||||
'authnoneenabled' => (int) is_enabled_auth('none'),
|
||||
'enablewebservices' => $CFG->enablewebservices,
|
||||
@@ -204,6 +204,7 @@ class api {
|
||||
}
|
||||
|
||||
if (empty($section) or $section == 'sitepolicies') {
|
||||
$settings->sitepolicy = $CFG->sitepolicy;
|
||||
$settings->disableuserimages = $CFG->disableuserimages;
|
||||
}
|
||||
|
||||
|
||||
@@ -94,12 +94,14 @@ class tool_mobile_external_testcase extends externallib_advanced_testcase {
|
||||
set_config('typeoflogin', api::LOGIN_VIA_BROWSER, 'tool_mobile');
|
||||
set_config('logo', 'mock.png', 'core_admin');
|
||||
set_config('logocompact', 'mock.png', 'core_admin');
|
||||
set_config('forgottenpasswordurl', 'mailto:[email protected]'); // Test old hack.
|
||||
|
||||
list($authinstructions, $notusedformat) = external_format_text($authinstructions, FORMAT_MOODLE, $context->id);
|
||||
$expected['registerauth'] = 'email';
|
||||
$expected['authinstructions'] = $authinstructions;
|
||||
$expected['typeoflogin'] = api::LOGIN_VIA_BROWSER;
|
||||
$expected['launchurl'] = "$CFG->wwwroot/$CFG->admin/tool/mobile/launch.php";
|
||||
$expected['forgottenpasswordurl'] = ''; // Expect empty when it's not an URL.
|
||||
|
||||
if ($logourl = $OUTPUT->get_logo_url()) {
|
||||
$expected['logourl'] = $logourl->out(false);
|
||||
@@ -121,6 +123,10 @@ class tool_mobile_external_testcase extends externallib_advanced_testcase {
|
||||
require_once($CFG->dirroot . '/course/format/lib.php');
|
||||
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
$mysitepolicy = 'http://mysite.is/policy/';
|
||||
set_config('sitepolicy', $mysitepolicy);
|
||||
|
||||
$result = external::get_config();
|
||||
$result = external_api::clean_returnvalue(external::get_config_returns(), $result);
|
||||
|
||||
@@ -141,6 +147,7 @@ class tool_mobile_external_testcase extends externallib_advanced_testcase {
|
||||
array('name' => 'numsections', 'value' => course_get_format($SITE)->get_course()->numsections),
|
||||
array('name' => 'newsitems', 'value' => $SITE->newsitems),
|
||||
array('name' => 'commentsperpage', 'value' => $CFG->commentsperpage),
|
||||
array('name' => 'sitepolicy', 'value' => $mysitepolicy),
|
||||
array('name' => 'disableuserimages', 'value' => $CFG->disableuserimages),
|
||||
array('name' => 'mygradesurl', 'value' => user_mygrades_url()->out(false)),
|
||||
);
|
||||
@@ -150,8 +157,7 @@ class tool_mobile_external_testcase extends externallib_advanced_testcase {
|
||||
// Change a value and retrieve filtering by section.
|
||||
set_config('commentsperpage', 1);
|
||||
$expected[10]['value'] = 1;
|
||||
unset($expected[11]);
|
||||
unset($expected[12]);
|
||||
array_splice($expected, 11);
|
||||
|
||||
$result = external::get_config('frontpagesettings');
|
||||
$result = external_api::clean_returnvalue(external::get_config_returns(), $result);
|
||||
|
||||
@@ -256,8 +256,9 @@ class core_course_external extends external_api {
|
||||
|
||||
if (!empty($cm->showdescription) or $cm->modname == 'label') {
|
||||
// We want to use the external format. However from reading get_formatted_content(), $cm->content format is always FORMAT_HTML.
|
||||
$options = array('noclean' => true);
|
||||
list($module['description'], $descriptionformat) = external_format_text($cm->content,
|
||||
FORMAT_HTML, $modcontext->id, $cm->modname, 'intro', $cm->id);
|
||||
FORMAT_HTML, $modcontext->id, $cm->modname, 'intro', $cm->id, $options);
|
||||
}
|
||||
|
||||
//url of the module
|
||||
|
||||
@@ -489,7 +489,7 @@ class grading_manager {
|
||||
* Returns the given method's controller in the gradable area
|
||||
*
|
||||
* @param string $method the method name, eg 'rubric' (must be available)
|
||||
* @return grading_controller
|
||||
* @return gradingform_controller
|
||||
*/
|
||||
public function get_controller($method) {
|
||||
global $CFG, $DB;
|
||||
@@ -534,7 +534,7 @@ class grading_manager {
|
||||
/**
|
||||
* Returns the controller for the active method if it is available
|
||||
*
|
||||
* @return null|grading_controller
|
||||
* @return null|gradingform_controller
|
||||
*/
|
||||
public function get_active_controller() {
|
||||
if ($gradingmethod = $this->get_active_method()) {
|
||||
|
||||
@@ -242,7 +242,7 @@ abstract class base_testcase extends PHPUnit_Framework_TestCase {
|
||||
}
|
||||
} // match by exact string
|
||||
else {
|
||||
if ($node->getAttribute($name) != $value) {
|
||||
if ($node->getAttribute($name) !== (string) $value) {
|
||||
$invalid = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,33 +53,21 @@
|
||||
{{$headertext}}{{#str}} messages, message {{/str}}{{/headertext}}
|
||||
{{$headeractions}}
|
||||
<div class="newmessage-link">
|
||||
{{$anchor}}
|
||||
<a href="{{{urls.writeamessage}}}">{{#str}} newmessage, message {{/str}}
|
||||
</a>
|
||||
{{/anchor}}
|
||||
<a href="{{{urls.writeamessage}}}">{{#str}} newmessage, message {{/str}}
|
||||
</a>
|
||||
</div>
|
||||
{{< core/hover_tooltip }}
|
||||
{{$anchor}}
|
||||
<a class="mark-all-read-button"
|
||||
href="#"
|
||||
role="button"
|
||||
title="{{#str}} markallread {{/str}}"
|
||||
data-action="mark-all-read">
|
||||
<span class="normal-icon">{{#pix}} t/markasread, core, {{#str}} markallread {{/str}} {{/pix}}</span>
|
||||
{{> core/loading }}
|
||||
</a>
|
||||
{{/anchor}}
|
||||
{{$tooltip}}{{#str}} markallread {{/str}}{{/tooltip}}
|
||||
{{/ core/hover_tooltip }}
|
||||
{{< core/hover_tooltip }}
|
||||
{{$anchor}}
|
||||
<a href="{{{urls.preferences}}}"
|
||||
title="{{#str}} messagepreferences, message {{/str}}">
|
||||
{{#pix}} i/settings, core, {{#str}} messagepreferences, message {{/str}} {{/pix}}
|
||||
</a>
|
||||
{{/anchor}}
|
||||
{{$tooltip}}{{#str}} messagepreferences, message {{/str}}{{/tooltip}}
|
||||
{{/ core/hover_tooltip }}
|
||||
<a class="mark-all-read-button"
|
||||
href="#"
|
||||
role="button"
|
||||
title="{{#str}} markallread {{/str}}"
|
||||
data-action="mark-all-read">
|
||||
<span class="normal-icon">{{#pix}} t/markasread, core, {{#str}} markallread {{/str}} {{/pix}}</span>
|
||||
{{> core/loading }}
|
||||
</a>
|
||||
<a href="{{{urls.preferences}}}"
|
||||
title="{{#str}} messagepreferences, message {{/str}}">
|
||||
{{#pix}} i/settings, core, {{#str}} messagepreferences, message {{/str}} {{/pix}}
|
||||
</a>
|
||||
{{/headeractions}}
|
||||
|
||||
{{$content}}
|
||||
|
||||
@@ -52,28 +52,18 @@
|
||||
|
||||
{{$headertext}}{{#str}} notifications, message {{/str}}{{/headertext}}
|
||||
{{$headeractions}}
|
||||
{{< core/hover_tooltip }}
|
||||
{{$anchor}}
|
||||
<a class="mark-all-read-button"
|
||||
href="#"
|
||||
title="{{#str}} markallread {{/str}}"
|
||||
data-action="mark-all-read"
|
||||
role="button">
|
||||
<span class="normal-icon">{{#pix}} t/markasread, core, {{#str}} markallread {{/str}} {{/pix}}</span>
|
||||
{{> core/loading }}
|
||||
</a>
|
||||
{{/anchor}}
|
||||
{{$tooltip}}{{#str}} markallread {{/str}}{{/tooltip}}
|
||||
{{/ core/hover_tooltip }}
|
||||
{{< core/hover_tooltip }}
|
||||
{{$anchor}}
|
||||
<a href="{{{urls.preferences}}}"
|
||||
title="{{#str}} notificationpreferences, message {{/str}}">
|
||||
{{#pix}} i/settings, core, {{#str}} notificationpreferences, message {{/str}} {{/pix}}
|
||||
</a>
|
||||
{{/anchor}}
|
||||
{{$tooltip}}{{#str}} notificationpreferences, message {{/str}}{{/tooltip}}
|
||||
{{/ core/hover_tooltip }}
|
||||
<a class="mark-all-read-button"
|
||||
href="#"
|
||||
title="{{#str}} markallread {{/str}}"
|
||||
data-action="mark-all-read"
|
||||
role="button">
|
||||
<span class="normal-icon">{{#pix}} t/markasread, core, {{#str}} markallread {{/str}} {{/pix}}</span>
|
||||
{{> core/loading }}
|
||||
</a>
|
||||
<a href="{{{urls.preferences}}}"
|
||||
title="{{#str}} notificationpreferences, message {{/str}}">
|
||||
{{#pix}} i/settings, core, {{#str}} notificationpreferences, message {{/str}} {{/pix}}
|
||||
</a>
|
||||
{{/headeractions}}
|
||||
|
||||
{{$content}}
|
||||
|
||||
@@ -1218,3 +1218,10 @@
|
||||
position: inherit;
|
||||
}
|
||||
/** End of base fixes **/
|
||||
|
||||
/** Fix to YUI tree (which is a table) when displayed within grading table. **/
|
||||
.path-mod-assign table.generaltable table td.ygtvcell {
|
||||
border: 0;
|
||||
padding: 0;
|
||||
}
|
||||
/** End of YUI tree fix **/
|
||||
|
||||
@@ -30,6 +30,9 @@ require_once ($CFG->dirroot.'/course/moodleform_mod.php');
|
||||
class mod_label_mod_form extends moodleform_mod {
|
||||
|
||||
function definition() {
|
||||
global $PAGE;
|
||||
|
||||
$PAGE->force_settings_menu();
|
||||
|
||||
$mform = $this->_form;
|
||||
|
||||
|
||||
@@ -138,6 +138,48 @@ abstract class quiz_attempts_report extends quiz_default_report {
|
||||
return array($currentgroup, $studentsjoins, $groupstudentsjoins, $groupstudentsjoins);
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs the things you commonly want at the top of a quiz report.
|
||||
*
|
||||
* Calls through to {@link print_header_and_tabs()} and then
|
||||
* outputs the standard group selector, number of attempts summary,
|
||||
* and messages to cover common cases when the report can't be shown.
|
||||
*
|
||||
* @param stdClass $cm the course_module information.
|
||||
* @param stdClass $course the course settings.
|
||||
* @param stdClass $quiz the quiz settings.
|
||||
* @param mod_quiz_attempts_report_options $options the current report settings.
|
||||
* @param int $currentgroup the current group.
|
||||
* @param bool $hasquestions whether there are any questions in the quiz.
|
||||
* @param bool $hasstudents whether there are any relevant students.
|
||||
*/
|
||||
protected function print_standard_header_and_messages($cm, $course, $quiz,
|
||||
$options, $currentgroup, $hasquestions, $hasstudents) {
|
||||
global $OUTPUT;
|
||||
|
||||
$this->print_header_and_tabs($cm, $course, $quiz, $this->mode);
|
||||
|
||||
if (groups_get_activity_groupmode($cm)) {
|
||||
// Groups are being used, so output the group selector if we are not downloading.
|
||||
groups_print_activity_menu($cm, $options->get_url());
|
||||
}
|
||||
|
||||
// Print information on the number of existing attempts.
|
||||
if ($strattemptnum = quiz_num_attempt_summary($quiz, $cm, true, $currentgroup)) {
|
||||
echo '<div class="quizattemptcounts">' . $strattemptnum . '</div>';
|
||||
}
|
||||
|
||||
if (!$hasquestions) {
|
||||
echo quiz_no_questions_message($quiz, $cm, $this->context);
|
||||
} else if ($currentgroup == self::NO_GROUPS_ALLOWED) {
|
||||
echo $OUTPUT->notification(get_string('notingroup'));
|
||||
} else if (!$hasstudents) {
|
||||
echo $OUTPUT->notification(get_string('nostudentsyet'));
|
||||
} else if ($currentgroup && !$this->hasgroupstudents) {
|
||||
echo $OUTPUT->notification(get_string('nostudentsingroup'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add all the user-related columns to the $columns and $headers arrays.
|
||||
* @param table_sql $table the table being constructed.
|
||||
|
||||
@@ -98,36 +98,13 @@ class quiz_overview_report extends quiz_attempts_report {
|
||||
$this->course = $course; // Hack to make this available in process_actions.
|
||||
$this->process_actions($quiz, $cm, $currentgroup, $groupstudentsjoins, $allowedjoins, $options->get_url());
|
||||
|
||||
$hasquestions = quiz_has_questions($quiz->id);
|
||||
|
||||
// Start output.
|
||||
if (!$table->is_downloading()) {
|
||||
// Only print headers if not asked to download data.
|
||||
$this->print_header_and_tabs($cm, $course, $quiz, $this->mode);
|
||||
}
|
||||
|
||||
if ($groupmode = groups_get_activity_groupmode($cm)) {
|
||||
// Groups are being used, so output the group selector if we are not downloading.
|
||||
if (!$table->is_downloading()) {
|
||||
groups_print_activity_menu($cm, $options->get_url());
|
||||
}
|
||||
}
|
||||
|
||||
// Print information on the number of existing attempts.
|
||||
if (!$table->is_downloading()) {
|
||||
// Do not print notices when downloading.
|
||||
if ($strattemptnum = quiz_num_attempt_summary($quiz, $cm, true, $currentgroup)) {
|
||||
echo '<div class="quizattemptcounts">' . $strattemptnum . '</div>';
|
||||
}
|
||||
}
|
||||
|
||||
$hasquestions = quiz_has_questions($quiz->id);
|
||||
if (!$table->is_downloading()) {
|
||||
if (!$hasquestions) {
|
||||
echo quiz_no_questions_message($quiz, $cm, $this->context);
|
||||
} else if (!$hasstudents) {
|
||||
echo $OUTPUT->notification(get_string('nostudentsyet'));
|
||||
} else if ($currentgroup && !$this->hasgroupstudents) {
|
||||
echo $OUTPUT->notification(get_string('nostudentsingroup'));
|
||||
}
|
||||
$this->print_standard_header_and_messages($cm, $course, $quiz,
|
||||
$options, $currentgroup, $hasquestions, $hasstudents);
|
||||
|
||||
// Print the display options.
|
||||
$this->form->display();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@mod @mod_quiz
|
||||
@mod @mod_quiz @quiz @quiz_overview
|
||||
Feature: Basic use of the Grades report
|
||||
In order to easily get an overview of quiz attempts
|
||||
As a teacher
|
||||
|
||||
@@ -68,6 +68,15 @@ class quiz_first_or_all_responses_table extends quiz_last_responses_table {
|
||||
// Insert an extra field in attempt data and extra rows where necessary.
|
||||
$newrawdata = array();
|
||||
foreach ($this->rawdata as $attempt) {
|
||||
if (!isset($this->questionusagesbyactivity[$attempt->usageid])) {
|
||||
// This is a user without attempts.
|
||||
$attempt->try = 0;
|
||||
$attempt->lasttryforallparts = true;
|
||||
$newrawdata[] = $attempt;
|
||||
continue;
|
||||
}
|
||||
|
||||
// We have an attempt, which may require several rows.
|
||||
$maxtriesinanyslot = 1;
|
||||
foreach ($this->questionusagesbyactivity[$attempt->usageid]->get_slots() as $slot) {
|
||||
$tries = $this->get_no_of_tries($attempt, $slot);
|
||||
@@ -230,7 +239,7 @@ class quiz_first_or_all_responses_table extends quiz_last_responses_table {
|
||||
* @return string What to put in the cell for this column, for this row data.
|
||||
*/
|
||||
public function col_email($tablerow) {
|
||||
if ($tablerow->try != 1) {
|
||||
if ($tablerow->try > 1) {
|
||||
return '';
|
||||
} else {
|
||||
return $tablerow->email;
|
||||
@@ -244,18 +253,27 @@ class quiz_first_or_all_responses_table extends quiz_last_responses_table {
|
||||
* @return string What to put in the cell for this column, for this row data.
|
||||
*/
|
||||
public function col_sumgrades($tablerow) {
|
||||
if (!$tablerow->lasttryforallparts) {
|
||||
if ($tablerow->try == 0) {
|
||||
// We are showing a user without a quiz attempt.
|
||||
return '-';
|
||||
} else if (!$tablerow->lasttryforallparts) {
|
||||
// There are more rows to come for this quiz attempt, so we will show this later.
|
||||
return '';
|
||||
} else {
|
||||
// Last row for this attempt. Now is the time to show attempt-related data.
|
||||
return parent::col_sumgrades($tablerow);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function col_state($tablerow) {
|
||||
if (!$tablerow->lasttryforallparts) {
|
||||
if ($tablerow->try == 0) {
|
||||
// We are showing a user without a quiz attempt.
|
||||
return '-';
|
||||
} else if (!$tablerow->lasttryforallparts) {
|
||||
// There are more rows to come for this quiz attempt, so we will show this later.
|
||||
return '';
|
||||
} else {
|
||||
// Last row for this attempt. Now is the time to show attempt-related data.
|
||||
return parent::col_state($tablerow);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,36 +111,13 @@ class quiz_responses_report extends quiz_attempts_report {
|
||||
|
||||
$this->process_actions($quiz, $cm, $currentgroup, $groupstudentsjoins, $allowedjoins, $options->get_url());
|
||||
|
||||
$hasquestions = quiz_has_questions($quiz->id);
|
||||
|
||||
// Start output.
|
||||
if (!$table->is_downloading()) {
|
||||
// Only print headers if not asked to download data.
|
||||
$this->print_header_and_tabs($cm, $course, $quiz, $this->mode);
|
||||
}
|
||||
|
||||
if ($groupmode = groups_get_activity_groupmode($cm)) {
|
||||
// Groups are being used, so output the group selector if we are not downloading.
|
||||
if (!$table->is_downloading()) {
|
||||
groups_print_activity_menu($cm, $options->get_url());
|
||||
}
|
||||
}
|
||||
|
||||
// Print information on the number of existing attempts.
|
||||
if (!$table->is_downloading()) {
|
||||
// Do not print notices when downloading.
|
||||
if ($strattemptnum = quiz_num_attempt_summary($quiz, $cm, true, $currentgroup)) {
|
||||
echo '<div class="quizattemptcounts">' . $strattemptnum . '</div>';
|
||||
}
|
||||
}
|
||||
|
||||
$hasquestions = quiz_has_questions($quiz->id);
|
||||
if (!$table->is_downloading()) {
|
||||
if (!$hasquestions) {
|
||||
echo quiz_no_questions_message($quiz, $cm, $this->context);
|
||||
} else if (!$hasstudents) {
|
||||
echo $OUTPUT->notification(get_string('nostudentsyet'));
|
||||
} else if ($currentgroup && !$this->hasgroupstudents) {
|
||||
echo $OUTPUT->notification(get_string('nostudentsingroup'));
|
||||
}
|
||||
$this->print_standard_header_and_messages($cm, $course, $quiz,
|
||||
$options, $currentgroup, $hasquestions, $hasstudents);
|
||||
|
||||
// Print the display options.
|
||||
$this->form->display();
|
||||
|
||||
@@ -70,6 +70,7 @@ class quiz_responses_settings_form extends mod_quiz_attempts_report_form {
|
||||
question_attempt::ALL_TRIES => get_string('alltries', 'question'))
|
||||
);
|
||||
$mform->setDefault('whichtries', question_attempt::LAST_TRY);
|
||||
$mform->disabledIf('whichtries', 'attempts', 'eq', quiz_attempts_report::ENROLLED_WITHOUT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
@mod @mod_quiz @quiz @quiz_reponses
|
||||
Feature: Basic use of the Responses report
|
||||
In order to see how my students are progressing
|
||||
As a teacher
|
||||
I need to see all their quiz responses
|
||||
|
||||
Background: Using the Responses report
|
||||
Given the following "users" exist:
|
||||
| username | firstname | lastname |
|
||||
| teacher | The | Teacher |
|
||||
| student1 | Student | One |
|
||||
| student2 | Student | Two |
|
||||
And the following "courses" exist:
|
||||
| fullname | shortname |
|
||||
| Course 1 | C1 |
|
||||
And the following "course enrolments" exist:
|
||||
| user | course | role |
|
||||
| teacher | C1 | editingteacher |
|
||||
| student1 | C1 | student |
|
||||
| student2 | C1 | student |
|
||||
And the following "question categories" exist:
|
||||
| contextlevel | reference | name |
|
||||
| Course | C1 | Test questions |
|
||||
And the following "activities" exist:
|
||||
| activity | name | intro | course | idnumber | preferredbehaviour |
|
||||
| quiz | Quiz 1 | Quiz 1 description | C1 | quiz1 | interactive |
|
||||
And the following "questions" exist:
|
||||
| questioncategory | qtype | name | template |
|
||||
| Test questions | numerical | NQ | pi3tries |
|
||||
And quiz "Quiz 1" contains the following questions:
|
||||
| question | page | maxmark |
|
||||
| NQ | 1 | 3.0 |
|
||||
|
||||
@javascript
|
||||
Scenario: Report works when there are no attempts
|
||||
When I log in as "teacher"
|
||||
And I am on "Course 1" course homepage
|
||||
And I follow "Quiz 1"
|
||||
And I navigate to "Results > Responses" in current page administration
|
||||
Then I should see "Attempts: 0"
|
||||
And I should see "Nothing to display"
|
||||
And I set the field "Attempts from" to "enrolled users who have not attempted the quiz"
|
||||
And I press "Show report"
|
||||
And "Student One" row "State" column of "responses" table should contain "-"
|
||||
|
||||
@javascript
|
||||
Scenario: Report works when there are attempts
|
||||
# Add an attempt
|
||||
Given I log in as "student1"
|
||||
And I am on "Course 1" course homepage
|
||||
And I follow "Quiz 1"
|
||||
And I press "Attempt quiz now"
|
||||
And I set the field "Answer" to "1.0"
|
||||
And I press "Check"
|
||||
And I press "Try again"
|
||||
And I set the field "Answer" to "3.0"
|
||||
And I press "Check"
|
||||
And I press "Try again"
|
||||
And I set the field "Answer" to "3.14"
|
||||
And I press "Check"
|
||||
And I press "Finish attempt ..."
|
||||
And I press "Submit all and finish"
|
||||
And I click on "Submit all and finish" "button" in the "Confirmation" "dialogue"
|
||||
And I log out
|
||||
|
||||
When I log in as "teacher"
|
||||
And I am on "Course 1" course homepage
|
||||
And I follow "Quiz 1"
|
||||
And I navigate to "Results > Responses" in current page administration
|
||||
Then I should see "Attempts: 1"
|
||||
And I should see "Student One"
|
||||
And I should not see "Student Two"
|
||||
And I set the field "Attempts from" to "enrolled users who have, or have not, attempted the quiz"
|
||||
And I set the field "Which tries" to "All tries"
|
||||
And I press "Show report"
|
||||
And "Student OneReview attempt" row "Response 1Sort by Response 1 Ascending" column of "responses" table should contain "1.0"
|
||||
And "Student OneReview attempt" row "State" column of "responses" table should contain ""
|
||||
And "Finished" row "Grade/100.00Sort by Grade/100.00 Ascending" column of "responses" table should contain "33.33"
|
||||
And "Finished" row "Response 1Sort by Response 1 Ascending" column of "responses" table should contain "3.14"
|
||||
And "Student Two" row "State" column of "responses" table should contain "-"
|
||||
And "Student Two" row "Response 1Sort by Response 1 Ascending" column of "responses" table should contain "-"
|
||||
|
||||
@javascript
|
||||
Scenario: Report does not allow strange combinations of options
|
||||
When I log in as "teacher"
|
||||
And I am on "Course 1" course homepage
|
||||
And I follow "Quiz 1"
|
||||
And I navigate to "Results > Responses" in current page administration
|
||||
And the "Which tries" "select" should be enabled
|
||||
And I set the field "Attempts from" to "enrolled users who have not attempted the quiz"
|
||||
Then the "Which tries" "select" should be disabled
|
||||
@@ -18,8 +18,7 @@
|
||||
* This file contains tests that walks a question through the manual graded
|
||||
* behaviour.
|
||||
*
|
||||
* @package qbehaviour
|
||||
* @subpackage manualgraded
|
||||
* @package qbehaviour_manualgraded
|
||||
* @copyright 2009 The Open University
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
@@ -622,4 +621,40 @@ class qbehaviour_manualgraded_walkthrough_testcase extends qbehaviour_walkthroug
|
||||
new question_pattern_expectation($preg)
|
||||
);
|
||||
}
|
||||
|
||||
public function test_manual_grading_reshows_exactly_the_mark_input() {
|
||||
global $PAGE;
|
||||
|
||||
// The current text editor depends on the users profile setting - so it needs a valid user.
|
||||
$this->setAdminUser();
|
||||
// Required to init a text editor.
|
||||
$PAGE->set_url('/');
|
||||
|
||||
// Create an essay question graded out of 15 and attempt it.
|
||||
$essay = test_question_maker::make_an_essay_question();
|
||||
$this->start_attempt_at_question($essay, 'deferredfeedback', 15);
|
||||
$this->process_submission(array('answer' => 'This is my wonderful essay!', 'answerformat' => FORMAT_HTML));
|
||||
$this->quba->finish_all_questions();
|
||||
|
||||
// Verify.
|
||||
$this->check_current_state(question_state::$needsgrading);
|
||||
$this->check_current_mark(null);
|
||||
$this->assertEquals('This is my wonderful essay!',
|
||||
$this->quba->get_response_summary($this->slot));
|
||||
|
||||
// Try to process a grade where the score will be stored rounded.
|
||||
$this->manual_grade('Comment', '5.0', FORMAT_HTML);
|
||||
|
||||
// Verify.
|
||||
$this->check_current_state(question_state::$mangrpartial);
|
||||
$this->check_current_mark(5);
|
||||
$this->displayoptions->manualcomment = question_display_options::EDITABLE;
|
||||
$this->render();
|
||||
$this->check_output_contains_text_input('-mark', '5.0');
|
||||
|
||||
// Rescale what the question is worth, and verify the display.
|
||||
$this->get_question_attempt()->set_max_mark(1);
|
||||
$this->render();
|
||||
$this->check_output_contains_text_input('-mark', '0.3333333');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,9 +126,6 @@ abstract class qbehaviour_renderer extends plugin_renderer_base {
|
||||
if (!is_null($currentmark)) {
|
||||
$attributes['value'] = $currentmark;
|
||||
}
|
||||
$a = new stdClass();
|
||||
$a->max = $qa->format_max_mark($options->markdp);
|
||||
$a->mark = html_writer::empty_tag('input', $attributes);
|
||||
|
||||
$markrange = html_writer::empty_tag('input', array(
|
||||
'type' => 'hidden',
|
||||
@@ -152,6 +149,9 @@ abstract class qbehaviour_renderer extends plugin_renderer_base {
|
||||
array('class' => 'error')) . html_writer::empty_tag('br');
|
||||
}
|
||||
|
||||
$a = new stdClass();
|
||||
$a->max = $qa->format_max_mark($options->markdp);
|
||||
$a->mark = html_writer::empty_tag('input', $attributes);
|
||||
$mark = html_writer::tag('div', html_writer::tag('div',
|
||||
html_writer::tag('label', get_string('mark', 'question'),
|
||||
array('for' => $markfield)),
|
||||
|
||||
@@ -525,15 +525,11 @@ ORDER BY
|
||||
qas.sequencenumber
|
||||
", $qubaids->usage_id_in_params());
|
||||
|
||||
if (!$records->valid()) {
|
||||
throw new coding_exception('Failed to load questions_usages_by_activity for qubaid_condition :' . $qubaids);
|
||||
}
|
||||
|
||||
$qubas = array();
|
||||
do {
|
||||
while ($records->valid()) {
|
||||
$record = $records->current();
|
||||
$qubas[$record->qubaid] = question_usage_by_activity::load_from_records($records, $record->qubaid);
|
||||
} while ($records->valid());
|
||||
}
|
||||
|
||||
$records->close();
|
||||
|
||||
|
||||
@@ -649,17 +649,29 @@ class question_attempt {
|
||||
|
||||
/**
|
||||
* This is used by the manual grading code, particularly in association with
|
||||
* validation. If there is a mark submitted in the request, then use that,
|
||||
* otherwise use the latest mark for this question.
|
||||
* @return number the current manual mark for this question, formatted for display.
|
||||
* validation. It gets the current manual mark for a question, in exactly the string
|
||||
* form that the teacher entered it, if possible. This may come from the current
|
||||
* POST request, if there is one, otherwise from the database.
|
||||
*
|
||||
* @return string the current manual mark for this question, in the format the teacher typed,
|
||||
* if possible.
|
||||
*/
|
||||
public function get_current_manual_mark() {
|
||||
// Is there a current value in the current POST data? If so, use that.
|
||||
$mark = $this->get_submitted_var($this->get_behaviour_field_name('mark'), PARAM_RAW_TRIMMED);
|
||||
if (is_null($mark)) {
|
||||
return format_float($this->get_mark(), 7, true, true);
|
||||
} else {
|
||||
if ($mark !== null) {
|
||||
return $mark;
|
||||
}
|
||||
|
||||
// Otherwise, use the stored value.
|
||||
// If the question max mark has not changed, use the stored value that was input.
|
||||
$storedmaxmark = $this->get_last_behaviour_var('maxmark');
|
||||
if ($storedmaxmark !== null && ($storedmaxmark - $this->get_max_mark()) < 0.0000005) {
|
||||
return $this->get_last_behaviour_var('mark');
|
||||
}
|
||||
|
||||
// The max mark for this question has changed so we must re-scale the current mark.
|
||||
return format_float($this->get_mark(), 7, true, true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -35,7 +35,7 @@ defined('MOODLE_INTERNAL') || die();
|
||||
*/
|
||||
class qtype_numerical_test_helper extends question_test_helper {
|
||||
public function get_test_questions() {
|
||||
return array('pi', 'unit', 'currency');
|
||||
return array('pi', 'unit', 'currency', 'pi3tries');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -71,6 +71,15 @@ class qtype_numerical_test_helper extends question_test_helper {
|
||||
return $num;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the form data that corresponds to saving a numerical question.
|
||||
*
|
||||
* This question asks for Pi to two decimal places. It has feedback
|
||||
* for various wrong responses. There is hint data there, but
|
||||
* it is all blank, so no hints are created if this question is saved.
|
||||
*
|
||||
* @return stdClass simulated question form data.
|
||||
*/
|
||||
public function get_numerical_question_form_data_pi() {
|
||||
$form = new stdClass();
|
||||
$form->name = 'Pi to two d.p.';
|
||||
@@ -156,6 +165,22 @@ class qtype_numerical_test_helper extends question_test_helper {
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the form data that corresponds to saving a numerical question.
|
||||
*
|
||||
* Like {@link get_numerical_question_form_data_pi()}, but
|
||||
* this time with two hints, making this suitable for use
|
||||
* with the Interactive with multiple tries behaviour.
|
||||
*
|
||||
* @return stdClass simulated question form data.
|
||||
*/
|
||||
public function get_numerical_question_form_data_pi3tries() {
|
||||
$form = $this->get_numerical_question_form_data_pi();
|
||||
$form->hint[0]['text'] = 'First hint';
|
||||
$form->hint[1]['text'] = 'Second hint';
|
||||
return $form;
|
||||
}
|
||||
|
||||
public function get_numerical_question_data_pi() {
|
||||
$q = new stdClass();
|
||||
$q->name = 'Pi to two d.p.';
|
||||
|
||||
@@ -28,7 +28,8 @@ $string['errorcreatingschema'] = 'Error creating the Solr schema: {$a}';
|
||||
$string['errorvalidatingschema'] = 'Error validating Solr schema: field {$a->fieldname} does not exist. Please <a href="{$a->setupurl}">follow this link</a> to set up the required fields.';
|
||||
$string['extensionerror'] = 'The Apache Solr PHP extension is not installed. Please check the documentation.';
|
||||
$string['fileindexing'] = 'Enable file indexing';
|
||||
$string['fileindexing_help'] = 'If your Solr install supports it, this feature allows Moodle to send files to be indexed.';
|
||||
$string['fileindexing_help'] = 'If your Solr install supports it, this feature allows Moodle to send files to be indexed.<br/>
|
||||
You will need to reindex all site contents after enabling this option for all files to be added.';
|
||||
$string['fileindexsettings'] = 'File indexing settings';
|
||||
$string['maxindexfilekb'] = 'Maximum file size to index (kB)';
|
||||
$string['maxindexfilekb_help'] = 'Files larger than this number of kilobytes will not be included in search indexing. If set to zero, files of any size will be indexed.';
|
||||
|
||||
@@ -538,13 +538,20 @@ span.editinstructions {
|
||||
}
|
||||
|
||||
.dndupload-progress-outer {
|
||||
@extend progress;
|
||||
background-color: $progress-bg;
|
||||
@include border-radius($progress-border-radius);
|
||||
@include box-shadow($progress-box-shadow);
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: $spacer-y;
|
||||
margin-bottom: $spacer-y;
|
||||
}
|
||||
|
||||
.dndupload-progress-inner {
|
||||
.progress {
|
||||
@extend .progress-bar;
|
||||
}
|
||||
background-color: $progress-bar-color;
|
||||
@include border-left-radius($progress-border-radius);
|
||||
display: inline-block;
|
||||
height: $spacer-y;
|
||||
}
|
||||
|
||||
.dndupload-hidden {
|
||||
|
||||
@@ -304,6 +304,14 @@ body.path-question-type {
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
.que.multianswer .formulation .yui3-widget-positioned {
|
||||
box-sizing: content-box;
|
||||
.feedbackspan {
|
||||
width: inherit;
|
||||
max-width: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
.path-mod-quiz input[size] {
|
||||
width: auto;
|
||||
max-width: 100%;
|
||||
|
||||
@@ -237,6 +237,12 @@ body.path-question-type .fitem_fgroup .accesshide {
|
||||
width: auto;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
.que.multianswer .formulation .yui3-widget-positioned .feedbackspan {
|
||||
box-sizing: content-box;
|
||||
padding-bottom: 0;
|
||||
max-width: inherit;
|
||||
width: inherit;
|
||||
}
|
||||
.path-mod-quiz input[size] {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
@@ -6962,6 +6962,12 @@ body.path-question-type .fitem_fgroup .accesshide {
|
||||
width: auto;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
.que.multianswer .formulation .yui3-widget-positioned .feedbackspan {
|
||||
box-sizing: content-box;
|
||||
padding-bottom: 0;
|
||||
max-width: inherit;
|
||||
width: inherit;
|
||||
}
|
||||
.path-mod-quiz input[size] {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
+2
-2
@@ -29,11 +29,11 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$version = 2016120505.10; // YYYYMMDD = weekly release date of this DEV branch.
|
||||
$version = 2016120505.11; // YYYYMMDD = weekly release date of this DEV branch.
|
||||
// RR = release increments - 00 in DEV branches.
|
||||
// .XX = incremental changes.
|
||||
|
||||
$release = '3.2.5+ (Build: 20171025)'; // Human-friendly version name
|
||||
$release = '3.2.5+ (Build: 20171027)'; // Human-friendly version name
|
||||
|
||||
$branch = '32'; // This version's branch.
|
||||
$maturity = MATURITY_STABLE; // This version's maturity level.
|
||||
|
||||
Reference in New Issue
Block a user