Browse Source

Add new field for student availability,

allow statuses to be hidden from students during self marking.
backport from master
MOODLE_32_STABLE
Dan Marsden 8 years ago
parent
commit
3569d778d5
  1. 2
      classes/event/status_updated.php
  2. 5
      db/install.xml
  3. 15
      db/upgrade.php
  4. 14
      defaultstatus.php
  5. 7
      lang/en/attendance.php
  6. 57
      locallib.php
  7. 17
      preferences.php
  8. 35
      renderer.php
  9. 27
      student_attendance_form.php
  10. 22
      tests/behat/attendance_mod.feature
  11. 4
      version.php

2
classes/event/status_updated.php

@ -84,7 +84,7 @@ class status_updated extends \core\event\base {
*/
protected function get_legacy_logdata() {
return array($this->courseid, 'attendance', 'status updated', $this->get_url(),
$this->other['updated'], $this->contextinstanceid);
'', $this->contextinstanceid);
}
/**

5
db/install.xml

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8" ?>
<XMLDB PATH="mod/attendance/db" VERSION="20170307" COMMENT="XMLDB file for Moodle mod/attendance"
<XMLDB PATH="mod/attendance/db" VERSION="20170511" COMMENT="XMLDB file for Moodle mod/attendance"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../../lib/xmldb/xmldb.xsd"
>
>
<TABLES>
<TABLE NAME="attendance" COMMENT="Attendance module table">
<FIELDS>
@ -78,6 +78,7 @@
<FIELD NAME="acronym" TYPE="char" LENGTH="2" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="description" TYPE="char" LENGTH="30" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="grade" TYPE="number" LENGTH="5" NOTNULL="true" DEFAULT="0" SEQUENCE="false" DECIMALS="2"/>
<FIELD NAME="studentavailability" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false" COMMENT="How many minutes this status is available when self marking is enabled."/>
<FIELD NAME="visible" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="1" SEQUENCE="false"/>
<FIELD NAME="deleted" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
<FIELD NAME="setnumber" TYPE="int" LENGTH="5" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Allows different sets of statuses to be allocated to different sessions"/>

15
db/upgrade.php

@ -245,5 +245,20 @@ function xmldb_attendance_upgrade($oldversion=0) {
upgrade_mod_savepoint(true, 2016121306, 'attendance');
}
if ($oldversion < 2016121309) {
// Define field studentavailability to be added to attendance_statuses.
$table = new xmldb_table('attendance_statuses');
$field = new xmldb_field('studentavailability', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'grade');
// Conditionally launch add field studentavailability.
if (!$dbman->field_exists($table, $field)) {
$dbman->add_field($table, $field);
}
// Attendance savepoint reached.
upgrade_mod_savepoint(true, 2016121309, 'attendance');
}
return $result;
}

14
defaultstatus.php

@ -51,10 +51,18 @@ switch ($action) {
$newacronym = optional_param('newacronym', null, PARAM_TEXT);
$newdescription = optional_param('newdescription', null, PARAM_TEXT);
$newgrade = optional_param('newgrade', 0, PARAM_RAW);
$newstudentavailability = optional_param('newstudentavailability', null, PARAM_INT);
$newgrade = unformat_float($newgrade);
// Default value uses setnumber/attendanceid = 0.
attendance_add_status($newacronym, $newdescription, $newgrade, 0);
$status = new stdClass();
$status->attendanceid = 0;
$status->acronym = $newacronym;
$status->description = $newdescription;
$status->grade = $newgrade;
$status->studentavailability = $newstudentavailability;
$status->setnumber = 0;
attendance_add_status($status);
break;
case mod_attendance_preferences_page_params::ACTION_DELETE:
@ -92,6 +100,7 @@ switch ($action) {
$acronym = required_param_array('acronym', PARAM_TEXT);
$description = required_param_array('description', PARAM_TEXT);
$grade = required_param_array('grade', PARAM_RAW);
$studentavailability = required_param_array('studentavailability', PARAM_RAW);
foreach ($grade as &$val) {
$val = unformat_float($val);
}
@ -99,7 +108,8 @@ switch ($action) {
foreach ($acronym as $id => $v) {
$status = $statuses[$id];
$errors[$id] = attendance_update_status($status, $acronym[$id], $description[$id], $grade[$id], null);
$errors[$id] = attendance_update_status($status, $acronym[$id], $description[$id], $grade[$id],
null, null, null, $studentavailability[$id]);
}
echo $OUTPUT->notification(get_string('eventstatusupdated', 'attendance'), 'success');

7
lang/en/attendance.php

@ -380,3 +380,10 @@ $string['defaultstatus'] = 'Default status set';
$string['defaultsessionsettings'] = 'Default session settings';
$string['defaultsessionsettings_help'] = 'These settings define the defaults for all new sessions';
$string['studentavailability'] = 'Available for students (minutes)';
$string['studentavailability_help'] = 'When students are marking their own attendance, the number of minutes after session starts that this status is available.
<br/>If empty, this status will always be available, If set to 0 it will always be hidden to students.';
$string['somedisabledstatus'] = '(Some options have been removed as the session has started.)';
$string['invalidstatus'] = 'You have selected an invalid status, please try again';

57
locallib.php

@ -258,40 +258,31 @@ function attendance_update_users_grade($attendance, $userids=array()) {
/**
* Add an attendance status variable
*
* @param string $acronym
* @param string $description
* @param int $grade
* @param int $attendanceid
* @param int $setnumber
* @param stdClass $context
* @param stdClass $cm
* @param stdClass $status
* @return bool
*/
function attendance_add_status($acronym, $description, $grade, $attendanceid, $setnumber = 0, $context = null, $cm = null) {
function attendance_add_status($status) {
global $DB;
if (empty($context)) {
$context = context_system::instance();
if (empty($status->context)) {
$status->context = context_system::instance();
}
if ($acronym && $description) {
$rec = new stdClass();
$rec->attendanceid = $attendanceid;
$rec->acronym = $acronym;
$rec->description = $description;
$rec->grade = $grade;
$rec->setnumber = $setnumber; // Save which set it is part of.
$rec->deleted = 0;
$rec->visible = 1;
$id = $DB->insert_record('attendance_statuses', $rec);
$rec->id = $id;
if (!empty($status->acronym) && !empty($status->description)) {
$status->deleted = 0;
$status->visible = 1;
$id = $DB->insert_record('attendance_statuses', $status);
$status->id = $id;
$event = \mod_attendance\event\status_added::create(array(
'objectid' => $attendanceid,
'context' => $context,
'other' => array('acronym' => $acronym, 'description' => $description, 'grade' => $grade)));
if (!empty($cm)) {
$event->add_record_snapshot('course_modules', $cm);
'objectid' => $status->attendanceid,
'context' => $status->context,
'other' => array('acronym' => $status->acronym,
'description' => $status->description,
'grade' => $status->grade)));
if (!empty($status->cm)) {
$event->add_record_snapshot('course_modules', $status->cm);
}
$event->add_record_snapshot('attendance_statuses', $rec);
$event->add_record_snapshot('attendance_statuses', $status);
$event->trigger();
return true;
} else {
@ -338,7 +329,7 @@ function attendance_remove_status($status, $context = null, $cm = null) {
* @param stdClass $cm
* @return array
*/
function attendance_update_status($status, $acronym, $description, $grade, $visible, $context = null, $cm = null) {
function attendance_update_status($status, $acronym, $description, $grade, $visible, $context = null, $cm = null, $studentavailability = null) {
global $DB;
if (empty($context)) {
@ -366,6 +357,16 @@ function attendance_update_status($status, $acronym, $description, $grade, $visi
$status->grade = $grade;
$updated[] = $grade;
}
if (isset($studentavailability)) {
if (empty($studentavailability)) {
if ($studentavailability !== '0') {
$studentavailability = null;
}
}
$status->studentavailability = $studentavailability;
$updated[] = $studentavailability;
}
$DB->update_record('attendance_statuses', $status);
$event = \mod_attendance\event\status_updated::create(array(

17
preferences.php

@ -68,10 +68,20 @@ switch ($att->pageparams->action) {
$newacronym = optional_param('newacronym', null, PARAM_TEXT);
$newdescription = optional_param('newdescription', null, PARAM_TEXT);
$newgrade = optional_param('newgrade', 0, PARAM_RAW);
$newstudentavailability = optional_param('newstudentavailability', null, PARAM_INT);
$newgrade = unformat_float($newgrade);
$status = attendance_add_status($newacronym, $newdescription, $newgrade, $att->id,
$att->pageparams->statusset, $att->context, $att->cm);
$newstatus = new stdClass();
$newstatus->attendanceid = $att->id;
$newstatus->acronym = $newacronym;
$newstatus->description = $newdescription;
$newstatus->grade = $newgrade;
$newstatus->studentavailability = $newstudentavailability;
$newstatus->setnumber = $att->pageparams->statusset;
$newstatus->cm = $att->cm;
$newstatus->context = $att->context;
$status = attendance_add_status($newstatus);
if (!$status) {
print_error('cantaddstatus', 'attendance', $this->url_preferences());
}
@ -118,6 +128,7 @@ switch ($att->pageparams->action) {
$acronym = required_param_array('acronym', PARAM_TEXT);
$description = required_param_array('description', PARAM_TEXT);
$grade = required_param_array('grade', PARAM_RAW);
$studentavailability = optional_param_array('studentavailability', null, PARAM_RAW);
foreach ($grade as &$val) {
$val = unformat_float($val);
}
@ -126,7 +137,7 @@ switch ($att->pageparams->action) {
foreach ($acronym as $id => $v) {
$status = $statuses[$id];
$errors[$id] = attendance_update_status($status, $acronym[$id], $description[$id], $grade[$id],
null, $att->context, $att->cm);
null, $att->context, $att->cm, $studentavailability[$id]);
}
attendance_update_users_grade($att);
break;

35
renderer.php

@ -1602,14 +1602,25 @@ class mod_attendance_renderer extends plugin_renderer_base {
protected function render_attendance_preferences_data($prefdata) {
$this->page->requires->js('/mod/attendance/module.js');
$studentscanmark = false;
if (!empty(get_config('attendance', 'studentscanmark'))) {
$studentscanmark = true;
}
$table = new html_table();
$table->width = '100%';
$table->head = array('#',
get_string('acronym', 'attendance'),
get_string('description'),
get_string('points', 'attendance'),
get_string('action'));
get_string('points', 'attendance'));
$table->align = array('center', 'center', 'center', 'center', 'center', 'center');
if ($studentscanmark) {
$table->head[] = get_string('studentavailability', 'attendance').
$this->output->help_icon('studentavailability', 'attendance');
$table->align[] = 'center';
}
$table->head[] = get_string('action');
$i = 1;
foreach ($prefdata->statuses as $st) {
@ -1623,14 +1634,19 @@ class mod_attendance_renderer extends plugin_renderer_base {
$emptydescription = $this->construct_notice(get_string('emptydescription', 'mod_attendance') , 'notifyproblem');
}
}
$table->data[$i][] = $i;
$table->data[$i][] = $this->construct_text_input('acronym['.$st->id.']', 2, 2, $st->acronym) . $emptyacronym;
$table->data[$i][] = $this->construct_text_input('description['.$st->id.']', 30, 30, $st->description) .
$cells = array();
$cells[] = $i;
$cells[] = $this->construct_text_input('acronym['.$st->id.']', 2, 2, $st->acronym) . $emptyacronym;
$cells[] = $this->construct_text_input('description['.$st->id.']', 30, 30, $st->description) .
$emptydescription;
$table->data[$i][] = $this->construct_text_input('grade['.$st->id.']', 4, 4, $st->grade);
$table->data[$i][] = $this->construct_preferences_actions_icons($st, $prefdata);
$cells[] = $this->construct_text_input('grade['.$st->id.']', 4, 4, $st->grade);
if ($studentscanmark) {
$cells[] = $this->construct_text_input('studentavailability['.$st->id.']', 4, 5, $st->studentavailability);
}
$cells[] = $this->construct_preferences_actions_icons($st, $prefdata);
$table->data[$i] = new html_table_row($cells);
$table->data[$i]->id = "statusrow".$i;
$i++;
}
@ -1638,6 +1654,9 @@ class mod_attendance_renderer extends plugin_renderer_base {
$table->data[$i][] = $this->construct_text_input('newacronym', 2, 2);
$table->data[$i][] = $this->construct_text_input('newdescription', 30, 30);
$table->data[$i][] = $this->construct_text_input('newgrade', 4, 4);
if ($studentscanmark) {
$table->data[$i][] = $this->construct_text_input('newstudentavailability', 4, 5);
}
$table->data[$i][] = $this->construct_preferences_button(get_string('add', 'attendance'),
mod_attendance_preferences_page_params::ACTION_ADD);

27
student_attendance_form.php

@ -46,6 +46,18 @@ class mod_attendance_student_attendance_form extends moodleform {
$attblock = $this->_customdata['attendance'];
$statuses = $attblock->get_statuses();
// Check if user has access to all statuses.
$disabledduetotime = false;
foreach ($statuses as $status) {
if ($status->studentavailability === '0') {
unset($statuses[$status->id]);
}
if (!empty($status->studentavailability) &&
time() > $attforsession->sessdate + ($status->studentavailability * 60)) {
unset($statuses[$status->id]);
$disabledduetotime = true;
}
}
$mform->addElement('hidden', 'sessid', null);
$mform->setType('sessid', PARAM_INT);
@ -75,10 +87,23 @@ class mod_attendance_student_attendance_form extends moodleform {
foreach ($statuses as $status) {
$radioarray[] =& $mform->createElement('radio', 'status', '', $status->description, $status->id, array());
}
if ($disabledduetotime) {
$warning = html_writer::span(get_string('somedisabledstatus', 'attendance'), 'somedisabledstatus');
$radioarray[] =& $mform->createElement('static', '', '', $warning);
}
// Add the radio buttons as a control with the user's name in front.
$mform->addGroup($radioarray, 'statusarray', $USER->firstname.' '.$USER->lastname.':', array(''), false);
$mform->addRule('statusarray', get_string('attendancenotset', 'attendance'), 'required', '', 'client', false, false);
$this->add_action_buttons();
}
public function validation($data, $files) {
$errors = array();
// Check if this status is allowed to be set.
if (empty($data['status'])) {
$errors['statusarray'] = get_string('invalidstatus', 'attendance');
}
return $errors;
}
}

22
tests/behat/attendance_mod.feature

@ -38,7 +38,7 @@ Feature: Teachers and Students can record session attendance
Then I should see "Attendance"
And I log out
Scenario: Students can mark their own attendance
Scenario: Students can mark their own attendance and teacher can hide specific status from students.
When I log in as "teacher1"
And I follow "Course 1"
And I follow "Attendance"
@ -50,15 +50,29 @@ Feature: Teachers and Students can record session attendance
| id_sestime_endminute | 55 |
And I click on "id_submitbutton" "button"
And I log out
When I log in as "student1"
And I log in as "student1"
And I follow "Course 1"
And I follow "Attendance"
And I follow "Submit attendance"
And I should see "Excused"
And I log out
And I log in as "teacher1"
And I follow "Course 1"
And I follow "Attendance"
And I follow "Status set"
And I set the field with xpath "//*[@id='preferencesform']/table/tbody/tr[3]/td[5]/input" to "0"
And I press "Update"
And I log out
And I log in as "student1"
And I follow "Course 1"
And I follow "Attendance"
And I follow "Submit attendance"
And I should not see "Excused"
And I set the field "Present" to "1"
And I press "Save changes"
Then I should see "Self-recorded"
And I should see "Self-recorded"
And I log out
When I log in as "teacher1"
And I log in as "teacher1"
And I follow "Course 1"
And I expand "Reports" node
And I follow "Logs"

4
version.php

@ -23,9 +23,9 @@
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2016121308;
$plugin->version = 2016121309;
$plugin->requires = 2016111800;
$plugin->release = '3.2.7';
$plugin->release = '3.2.8';
$plugin->maturity = MATURITY_STABLE;
$plugin->cron = 0;
$plugin->component = 'mod_attendance';

Loading…
Cancel
Save