Skip to content

Commit

Permalink
Enhancement: Question-writing and question-responding phases
Browse files Browse the repository at this point in the history
  • Loading branch information
HuongNV13 committed Jan 3, 2019
1 parent 89a55c7 commit 9756632
Show file tree
Hide file tree
Showing 11 changed files with 402 additions and 11 deletions.
15 changes: 11 additions & 4 deletions classes/question/bank/studentquiz_bank_view.php
Original file line number Diff line number Diff line change
Expand Up @@ -491,10 +491,17 @@ public function create_new_question_form($categoryid, $canadd) {
$qtypecontainer = \html_writer::div(
print_choose_qtype_to_add_form(array(), $allowedtypes, true
), '', array('id' => 'qtypechoicecontainer'));
$output .= \html_writer::div(
$OUTPUT->render(new \single_button($url, $caption, 'get', true)) .
$qtypecontainer, 'createnewquestion'
);
$questionsubmissionbutton = new \single_button($url, $caption, 'get', true);

list($message, $questionsubmissionallow) = mod_studentquiz_check_availability($this->studentquiz->opensubmissionfrom,
$this->studentquiz->closesubmissionfrom, 'submission');

$questionsubmissionbutton->disabled = !$questionsubmissionallow;
$output .= \html_writer::div($OUTPUT->render($questionsubmissionbutton) . $qtypecontainer, 'createnewquestion');

if (!empty($message)) {
$output .= $this->renderer->render_availability_message($message, 'mod_studentquiz_submission_info');
}
} else {
$output .= get_string('nopermissionadd', 'question');
}
Expand Down
4 changes: 4 additions & 0 deletions db/install.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@
<FIELD NAME="incorrectanswerquantifier" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Point factor multiplied with number of incorrect answers"/>
<FIELD NAME="allowedqtypes" TYPE="text" LENGTH="medium" NOTNULL="true" SEQUENCE="false" COMMENT="which question types are allowed"/>
<FIELD NAME="aggregated" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Property if studentquiz instance is using aggregated values"/>
<FIELD NAME="opensubmissionfrom" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="If non-zero, then users cannot create questions to the StudentQuiz until the specified date"/>
<FIELD NAME="closesubmissionfrom" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="If non-zero, users cannot create questions to the StudentQuiz after the specified date"/>
<FIELD NAME="openansweringfrom" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="If non-zero, then users cannot attempt questions until the specified date"/>
<FIELD NAME="closeansweringfrom" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="If non-zero, users cannot attempt questions after the specified date"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
Expand Down
14 changes: 14 additions & 0 deletions db/upgrade.php
Original file line number Diff line number Diff line change
Expand Up @@ -451,5 +451,19 @@ function xmldb_studentquiz_upgrade($oldversion) {
upgrade_mod_savepoint(true, 2018121800, 'studentquiz');
}

if ($oldversion < 2018122500) {
$table = new xmldb_table('studentquiz');
$fieldnames = ['opensubmissionfrom', 'closesubmissionfrom', 'openansweringfrom', 'closeansweringfrom'];

foreach ($fieldnames as $fieldname) {
$field = new xmldb_field($fieldname, XMLDB_TYPE_INTEGER, 10, null, XMLDB_NOTNULL, null, '0');
if (!$dbman->field_exists($table, $field)) {
$dbman->add_field($table, $field);
}
}

upgrade_mod_savepoint(true, 2018122500, 'studentquiz');
}

return true;
}
12 changes: 12 additions & 0 deletions lang/en/studentquiz.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,12 @@
$string['progress_bar_caption'] = 'Your progress in this StudentQuiz activity';
$string['no_questions_filter'] = 'None of the questions matched your filter criteria. Reset the filter to see all.';
$string['no_questions_add'] = 'There are no questions in this StudentQuiz. Feel free to add some questions.';
$string['before_submission_start_date'] = 'Open for question submission from {$a}.';
$string['before_submission_end_date'] = 'This StudentQuiz closes for question submission on {$a}.';
$string['after_submission_end_date'] = 'This StudentQuiz closed for question submission on {$a}.';
$string['before_answering_start_date'] = 'Open for answering from {$a}.';
$string['before_answering_end_date'] = 'This StudentQuiz closes for answering on {$a}.';
$string['after_answering_end_date'] = 'This StudentQuiz closed for answering on {$a}.';

// Blocks.
$string['statistic_block_title'] = 'My Progress';
Expand Down Expand Up @@ -167,10 +173,16 @@
$string['settings_allowedqtypes'] = 'Allowed question types';
$string['settings_allowedqtypes_help'] = 'Here you specify the type of questions that are allowed';
$string['settings_qtypes_default_new_activity'] = 'The following are default for a new activity';
$string['settings_availability_open_submission_from'] = 'Open for question submission from';
$string['settings_availability_close_submission_from'] = 'Closed for question submission from';
$string['settings_availability_open_answering_from'] = 'Open for answering from';
$string['settings_availability_close_answering_from'] = 'Close for answering from';

// Error messages.
$string['needtoallowatleastoneqtype'] = 'You need to allow at least one question type';
$string['please_enrole_message'] = 'Please enroll in this course to see your personal progress';
$string['submissionendbeforestart'] = 'Submissions deadline can not be specified before the open for submissions date';
$string['answeringndbeforestart'] = 'Answering deadline can not be specified before the open for answering date';

// Admin settings.
$string['rankingsettingsheader'] = 'Ranking settings';
Expand Down
29 changes: 29 additions & 0 deletions locallib.php
Original file line number Diff line number Diff line change
Expand Up @@ -1301,3 +1301,32 @@ function mod_studentquiz_fix_wrong_parent_in_question_categories() {
}
}
}

/**
* Check that StudentQuiz is allowing answering or not.
*
* @param int $openform Open date
* @param int $closefrom Close date
* @param string $type submission or answering
* @return array Message and Allow or not
*/
function mod_studentquiz_check_availability($openform, $closefrom, $type) {
$message = '';
$availabilityallow = true;

if (time() < $openform) {
$availabilityallow = false;
$message = get_string('before_' . $type . '_start_date', 'studentquiz',
userdate($openform, get_string('strftimedatetimeshort', 'langconfig')));
} else if (time() < $closefrom) {
$message = get_string('before_' . $type . '_end_date', 'studentquiz',
userdate($closefrom, get_string('strftimedatetimeshort', 'langconfig')));
}
if ($closefrom && time() >= $closefrom) {
$availabilityallow = false;
$message = get_string('after_' . $type . '_end_date', 'studentquiz',
userdate($closefrom, get_string('strftimedatetimeshort', 'langconfig')));
}

return [$message, $availabilityallow];
}
19 changes: 19 additions & 0 deletions mod_form.php
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,17 @@ public function definition() {
$mform->disabledIf('allowedqtypes', "allowedqtypes[ALL]", 'checked');
$mform->addHelpButton('allowedqtypes', 'settings_allowedqtypes', 'studentquiz');

// Availability.
$mform->addElement('header', 'availability', get_string('availability', 'moodle'));
$mform->addElement('date_time_selector', 'opensubmissionfrom',
get_string('settings_availability_open_submission_from', 'studentquiz'), ['optional' => true]);
$mform->addElement('date_time_selector', 'closesubmissionfrom',
get_string('settings_availability_close_submission_from', 'studentquiz'), ['optional' => true]);
$mform->addElement('date_time_selector', 'openansweringfrom',
get_string('settings_availability_open_answering_from', 'studentquiz'), ['optional' => true]);
$mform->addElement('date_time_selector', 'closeansweringfrom',
get_string('settings_availability_close_answering_from', 'studentquiz'), ['optional' => true]);

// Add standard elements, common to all modules.
$this->standard_coursemodule_elements();

Expand Down Expand Up @@ -183,6 +194,14 @@ public function validation($data, $files) {
if (!isset($data['allowedqtypes'])) {
$errors['allowedqtypes'] = get_string('needtoallowatleastoneqtype', 'studentquiz');
}
if ($data['opensubmissionfrom'] > 0 && $data['closesubmissionfrom'] > 0 &&
$data['opensubmissionfrom'] >= $data['closesubmissionfrom']) {
$errors['closesubmissionfrom'] = get_string('submissionendbeforestart', 'studentquiz');
}
if ($data['openansweringfrom'] > 0 && $data['closeansweringfrom'] > 0 &&
$data['openansweringfrom'] >= $data['closeansweringfrom']) {
$errors['closeansweringfrom'] = get_string('answeringndbeforestart', 'studentquiz');
}
return $errors;
}
}
18 changes: 18 additions & 0 deletions pix/info.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
45 changes: 39 additions & 6 deletions renderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -1095,13 +1095,23 @@ public function render_control_buttons($catcontext, $hasquestionincategory, $add
$output .= html_writer::tag('strong', '&nbsp;' . get_string('withselected', 'question') . ':');
$output .= html_writer::empty_tag('br');

$studentquiz = mod_studentquiz_load_studentquiz($this->page->url->get_param('cmid'), $this->page->context->id);
list($message, $answeringallow) = mod_studentquiz_check_availability(
$studentquiz->openansweringfrom, $studentquiz->closeansweringfrom, 'answering');

if ($hasquestionincategory) {
$output .= html_writer::empty_tag('input', [
'class' => 'btn btn-primary form-submit',
'type' => 'submit',
'name' => 'startquiz',
'value' => get_string('start_quiz_button', 'studentquiz')
]);
$params = [
'class' => 'btn btn-primary form-submit',
'type' => 'submit',
'name' => 'startquiz',
'value' => get_string('start_quiz_button', 'studentquiz')
];

if (!$answeringallow) {
$params['disabled'] = 'disabled';
}

$output .= html_writer::empty_tag('input', $params);
}

if ($caneditall) {
Expand Down Expand Up @@ -1132,6 +1142,11 @@ public function render_control_buttons($catcontext, $hasquestionincategory, $add
ob_end_clean();
}

if (!empty($message)) {
$output .= $this->render_availability_message($message, 'mod_studentquiz_answering_info');
}


$output .= html_writer::end_div();

return $output;
Expand Down Expand Up @@ -1238,6 +1253,24 @@ private function generate_hidden_input($name, $value) {
return $output;
}

/**
* Render the availability message
*
* @param string $message Message to show
* @param string $class Class of the message
* @return string HTML string
*/
public function render_availability_message($message, $class) {
$output = '';

if (!empty($message)) {
$icon = new \pix_icon('info', get_string('info'), 'studentquiz');
$output = \html_writer::div($this->output->render($icon) . $message, $class);
}

return $output;
}

}

class mod_studentquiz_attempt_renderer extends mod_studentquiz_renderer {
Expand Down
72 changes: 72 additions & 0 deletions tests/behat/behat_mod_studentquiz.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.

/**
* Steps definitions related to mod_studentquiz.
*
* @package mod_studentquiz
* @category test
* @copyright 2019 HSR (http://www.hsr.ch)
* @author 2019 Huong Nguyen <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

require_once(__DIR__ . '/../../../../lib/behat/behat_base.php');

/**
* Steps definitions related to mod_studentquiz.
*
* @package mod_studentquiz
* @category test
* @copyright 2019 HSR (http://www.hsr.ch)
* @author 2019 Huong Nguyen <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class behat_mod_studentquiz extends behat_base {

/**
* @Given /^I set the availability field "(?P<field_string>(?:[^"]|\\")*)" to "(?P<days_value_integer>(?:[^"]|\\")*)" days from now$/
* @param string $field Field name.
* @param string $days Number of days from now.
*/
public function i_set_availability_field_to($field, $days) {
$date = strtotime($days . ' day');
$day = date('j', $date);
$month = date('F', $date);
$year = date('Y', $date);
$this->set_field_value('id_' . $field . '_day', $day);
$this->set_field_value('id_' . $field . '_month', $month);
$this->set_field_value('id_' . $field . '_year', $year);
}

/**
* Generic field setter.
*
* Internal API method, a generic *I set "VALUE" to "FIELD" field*
* could be created based on it.
*
* @param string $fieldlocator The pointer to the field, it will depend on the field type.
* @param string $value
* @return void
*/
protected function set_field_value($fieldlocator, $value) {
// We delegate to behat_form_field class, it will
// guess the type properly as it is a select tag.
$field = behat_field_manager::get_form_field_from_label($fieldlocator, $this);
$field->set_value($value);
}

}
Loading

0 comments on commit 9756632

Please sign in to comment.