From 2b3b13f4252cca245cee107950948904a737327a Mon Sep 17 00:00:00 2001 From: Artem Andreev Date: Sat, 28 May 2011 17:46:42 +0400 Subject: [PATCH] Unfinished implementation take.php (previously attendance.php) with enhancement: take into account information about students enrolment(status, start date). --- lang/en/attforblock.php | 4 + lang/ru/attforblock.php | 3 + locallib.php | 183 +++++++++++++++++++++++++++++++++++----- manage.php | 2 +- renderables.php | 61 +++++++++++++- renderer.php | 177 ++++++++++++++++++++++++++++++-------- sessions.php | 6 +- styles.css | 33 ++++---- take.php | 52 ++++++++++++ 9 files changed, 443 insertions(+), 78 deletions(-) create mode 100644 take.php diff --git a/lang/en/attforblock.php b/lang/en/attforblock.php index 412e938..e6eb987 100644 --- a/lang/en/attforblock.php +++ b/lang/en/attforblock.php @@ -76,6 +76,8 @@ $string['duration'] = 'Duration'; $string['editsession'] = 'Edit Session'; $string['endtime'] = 'Session end time'; $string['endofperiod'] = 'End of period'; +$string['enrolmentstart'] = 'User enrolment starts {$a}'; +$string['enrolmentsuspended'] = 'Enrolment suspended'; $string['errorgroupsnotselected'] = 'Select one or more groups'; $string['errorinaddingsession'] = 'Error in adding session'; $string['erroringeneratingsessions'] = 'Error in generating sessions '; @@ -113,6 +115,7 @@ $string['olddate'] = 'Old date'; $string['period'] = 'Frequency'; $string['pluginname'] = 'Attendance'; $string['pluginadministration'] = 'Attendance administration'; +$string['remarks'] = 'Remarks'; $string['report'] = 'Report'; $string['resetdescription'] = 'Remember that deleting attendance data will erase information from database. You can just hide older sessions having changed start date of course!'; $string['resetstatuses'] = 'Reset statuses to default'; @@ -139,6 +142,7 @@ $string['sessiontype_help'] = 'There are two types of sessions: common and group '; $string['sessiontypeshort'] = 'Type'; $string['sessionupdated'] = 'Session successfully updated'; +$string['setallstatusesto'] = 'Set status for all users to «{$a}»'; $string['settings'] = 'Settings'; $string['showdefaults'] = 'Show defaults'; $string['showduration'] = 'Show duration'; diff --git a/lang/ru/attforblock.php b/lang/ru/attforblock.php index 99c7ee8..2c6b613 100644 --- a/lang/ru/attforblock.php +++ b/lang/ru/attforblock.php @@ -62,6 +62,8 @@ $string['downloadtext'] = 'Скачать в текстовом формате'; $string['duration'] = 'Продолжительность'; $string['editsession'] = 'Редактировать занятие'; $string['endofperiod'] = 'Конец периода'; +$string['enrolmentstart'] = 'Подписка на курс начинается с {$a}'; +$string['enrolmentsuspended'] = 'Подписка на курс приостановлена'; $string['errorgroupsnotselected'] = 'Выберите одну или более групп'; $string['errorinaddingsession'] = 'Ошибка при добавлении занятия'; $string['erroringeneratingsessions'] = 'Ошибка при создании занятий'; @@ -123,6 +125,7 @@ $string['sessiontype_help'] = 'Существует 2 типа занятий: '; $string['sessiontypeshort'] = 'Тип'; $string['sessionupdated'] = 'Занятие успешно изменено'; +$string['setallstatusesto'] = 'Установить статус для всех учащихся в «{$a}»'; $string['settings'] = 'Настройки'; $string['showdefaults'] = 'Показать значения по-умолчанию'; $string['sortedgrid'] = 'Таблица'; diff --git a/locallib.php b/locallib.php index 5d038ec..37ab9f0 100644 --- a/locallib.php +++ b/locallib.php @@ -1,5 +1,7 @@ libdir . '/gradelib.php'); @@ -194,6 +196,10 @@ class att_manage_page_params { break; } } + + public function get_significant_params() { + return array(); + } } class att_sessions_page_params { @@ -213,32 +219,55 @@ class att_take_page_params { const DEFAULT_VIEW_MODE = self::SORTED_LIST; - /** @var int view mode of taking attendance page*/ - public $view_mode; + const SORT_LASTNAME = 1; + const SORT_FIRSTNAME = 2; - public static function create_default() { - $instance = new att_take_page_params(); + public $sessionid; + public $grouptype; + public $group; + public $sort; + public $copyfrom; + + /** @var int view mode of taking attendance page*/ + public $viewmode; - $instance->view_mode = self::DEFAULT_VIEW_MODE; + public $gridcols; - return $instance; + public function init() { + if (!isset($this->sort)) $this->sort = self::SORT_LASTNAME; + $this->init_view_mode(); + $this->init_gridcols(); } - public function init(att_manage_page_params $view_params, $courseid) { - $this->init_view_mode($view_params->view_mode); + private function init_view_mode() { + if (isset($this->viewmode)) { + set_user_preference("attforblock_take_view_mode", $this->viewmode); + } + else { + $this->viewmode = get_user_preferences("attforblock_take_view_mode", self::DEFAULT_VIEW_MODE); + } } - private function init_view_mode($view_mode) { - global $SESSION; - - if (isset($view_mode)) { - set_user_preference("attforblock_take_view_mode", $view_mode); - $this->view_mode = $view_mode; + private function init_gridcols() { + if (isset($this->gridcols)) { + set_user_preference("attforblock_gridcolumns", $this->gridcols); } else { - $this->view_mode = get_user_preferences("attforblock_take_view_mode", $this->view_mode); + $this->gridcols = get_user_preferences("attforblock_gridcolumns", 5); } } + + public function get_significant_params() { + $params = array(); + + $params['sessionid'] = $this->sessionid; + $params['grouptype'] = $this->grouptype; + if (isset($this->group)) $params['group'] = $this->group; + $params['sort'] = $this->sort; + if (isset($this->copyfrom)) $params['copyfrom'] = $this->copyfrom; + + return $params; + } } class attforblock { @@ -279,6 +308,10 @@ class attforblock { private $currentgroup; + private $sessioninfo; + + private $statuses; + /** * Initializes the attendance API instance using the data from DB * @@ -367,7 +400,7 @@ class attforblock { * @return moodle_url of sessions.php for attendance instance */ public function url_sessions($params=array()) { - $params = array_merge(array('id' => $this->cm->id), $params); + $params = array('id' => $this->cm->id) + $params; return new moodle_url('/mod/attforblock/sessions.php', $params); } @@ -400,14 +433,13 @@ class attforblock { */ public function url_take() { $params = array('id' => $this->cm->id); - return new moodle_url('/mod/attforblock/attendances.php', $params); + return new moodle_url('/mod/attforblock/take.php', $params); } private function calc_groupmode_sessgroupslist_currentgroup(){ global $USER, $SESSION; $cm = $this->cm; - $this->groupmode = groups_get_activity_groupmode($cm); if ($this->groupmode == NOGROUPS) return; @@ -484,7 +516,7 @@ class attforblock { public function get_group_mode() { if (is_null($this->groupmode)) - $this->calc_groupmode_sessgroupslist_currentgroup(); + $this->groupmode = groups_get_activity_groupmode($this->cm); return $this->groupmode; } @@ -555,6 +587,119 @@ class attforblock { // TODO: log // add_to_log($course->id, 'attendance', 'Session updated', 'mod/attforblock/manage.php?id='.$id, $user->lastname.' '.$user->firstname); } + + public function take_from_form_data($formdata) { + global $DB, $USER; + + $statuses = implode(',', array_keys( (array)$this->get_statuses() )); + $now = time(); + $sesslog = array(); + $formdata = (array)$formdata; + foreach($formdata as $key => $value) { + if(substr($key, 0, 4) == 'user' && $value !== '') { + $sid = substr($key, 4); + $sesslog[$sid] = new Object(); + $sesslog[$sid]->studentid = $sid; + $sesslog[$sid]->statusid = $value; + $sesslog[$sid]->statusset = $statuses; + $sesslog[$sid]->remarks = array_key_exists('remarks'.$sid, $formdata) ? $formdata['remarks'.$sid] : ''; + $sesslog[$sid]->sessionid = $this->pageparams->sessionid; + $sesslog[$sid]->timetaken = $now; + $sesslog[$sid]->takenby = $USER->id; + } + } + + $dbsesslog = $this->get_session_log($this->pageparams->sessionid); + foreach ($sesslog as $log) { + if (array_key_exists($log->studentid, $dbsesslog)) { + $log->id = $dbsesslog[$log->studentid]->id; + $DB->update_record('attendance_log', $log); + } + else + $DB->insert_record('attendance_log', $log, false); + } + + $rec = new object(); + $rec->id = $this->pageparams->sessionid; + $rec->lasttaken = $now; + $rec->lasttakenby = $USER->id; + $DB->update_record('attendance_sessions', $rec); + + // TODO: update_grades + // TODO: log + redirect($this->url_manage(), get_string('attendancesuccess','attforblock')); + } + + /** + * MDL-27591 made this method obsolete. + */ + public function get_users($groupid = 0) { + global $DB; + + //fields we need from the user table + $userfields = user_picture::fields('u'); + + if (isset($this->pageparams->sort) and ($this->pageparams->sort == att_take_page_params::SORT_FIRSTNAME)) { + $orderby = "u.firstname ASC, u.lastname ASC"; + } + else { + $orderby = "u.lastname ASC, u.firstname ASC"; + } + + $users = get_enrolled_users($this->context, 'mod/attforblock:canbelisted', $groupid, $userfields, $orderby); + + //add a flag to each user indicating whether their enrolment is active + if (!empty($users)) { + list($usql, $uparams) = $DB->get_in_or_equal(array_keys($users), SQL_PARAMS_NAMED, 'usid0'); + + $sql = "SELECT ue.userid, ue.status, ue.timestart, ue.timeend + FROM {user_enrolments} ue + JOIN {enrol} e ON e.id = ue.enrolid + WHERE ue.userid $usql + AND e.status = :estatus + AND e.courseid = :courseid + GROUP BY ue.userid"; + $params = array_merge($uparams, array('estatus'=>ENROL_INSTANCE_ENABLED, 'courseid'=>$this->course->id)); + $enrolmentsparams = $DB->get_records_sql($sql, $params); + + foreach ($users as $user) { + $users[$user->id]->enrolmentstatus = $enrolmentsparams[$user->id]->status; + $users[$user->id]->enrolmentstart = $enrolmentsparams[$user->id]->timestart; + $users[$user->id]->enrolmentend = $enrolmentsparams[$user->id]->timeend; + } + } + + return $users; + } + + public function get_statuses($onlyvisible = true) { + global $DB; + + if (!isset($this->statuses)) { + if ($onlyvisible) { + $this->statuses = $DB->get_records_select('attendance_statuses', "attendanceid = :aid AND visible = 1 AND deleted = 0", array('aid' => $this->id), 'grade DESC'); + } else { + $this->statuses = $DB->get_records_select('attendance_statuses', "attendanceid = :aid AND deleted = 0", array('aid' => $this->id), 'grade DESC'); + } + } + + return $this->statuses; + } + + public function get_session_info($sessionid) { + global $DB; + + if (!isset($this->sessioninfo)) + $this->sessioninfo = $DB->get_record('attendance_sessions', array('id' => $sessionid)); + + return $this->sessioninfo; + } + + public function get_session_log($sessionid) { + global $DB; + + return $DB->get_records('attendance_log', array('sessionid' => $sessionid), '', 'studentid,statusid,remarks,id'); + } } diff --git a/manage.php b/manage.php index b8089d6..fdb2522 100644 --- a/manage.php +++ b/manage.php @@ -56,7 +56,7 @@ $PAGE->set_button($OUTPUT->update_module_button($cm->id, 'attforblock')); $PAGE->navbar->add($att->name); $output = $PAGE->get_renderer('mod_attforblock'); -$tabs = new attforblock_tabs($att); +$tabs = new attforblock_tabs($att, attforblock_tabs::TAB_SESSIONS); $filtercontrols = new attforblock_filter_controls($att); $sesstable = new attforblock_sessions_manage_data($att); diff --git a/renderables.php b/renderables.php index 23f8def..d991781 100644 --- a/renderables.php +++ b/renderables.php @@ -37,7 +37,7 @@ class attforblock_tabs implements renderable { * @param attforblock $att instance * @param $currenttab - one of attforblock_tabs constants */ - public function __construct(attforblock $att, $currenttab=self::TAB_SESSIONS) { + public function __construct(attforblock $att, $currenttab=NULL) { $this->att = $att; $this->currenttab = $currenttab; } @@ -130,9 +130,8 @@ class attforblock_filter_controls implements renderable { } $this->urlpath = $PAGE->url->out_omit_querystring(); - $params = array('id' => $att->cm->id); - if (isset($att->pageparams->studentssort)) $params['sort'] = $att->pageparams->studentssort; - if (isset($att->pageparams->studentid)) $params['studentid'] = $att->pageparams->studentid; + $params = $att->pageparams->get_significant_params(); + $params['id'] = $att->cm->id; $this->urlparams = $params; $this->att = $att; @@ -266,4 +265,58 @@ class attforblock_sessions_manage_data implements renderable { } } +class attforblock_take_data implements renderable { + public $users; + + public $pageparams; + public $perm; + + public $groupmode; + public $cm; + + public $statuses; + + public $sessioninfo; + + public $sessionlog; + + public $updatemode; + + private $urlpath; + private $urlparams; + + public function __construct(attforblock $att) { + $this->users = $att->get_users(); + + $this->pageparams = $att->pageparams; + $this->perm = $att->perm; + + $this->groupmode = $att->get_group_mode(); + $this->cm = $att->cm; + + $this->statuses = $att->get_statuses(); + + $this->sessioninfo = $att->get_session_info($att->pageparams->sessionid); + + $this->sessionlog = $att->get_session_log($att->pageparams->sessionid); + + $this->urlpath = $att->url_take()->out_omit_querystring(); + $params = $att->pageparams->get_significant_params(); + $params['id'] = $att->cm->id; + $this->urlparams = $params; + + $this->updatemode =$this->sessioninfo->lasttaken > 0; + } + + public function url($params=array()) { + $params = array_merge($this->urlparams, $params); + + return new moodle_url($this->urlpath, $params); + } + + public function url_path() { + return $this->urlpath; + } +} + ?> \ No newline at end of file diff --git a/renderer.php b/renderer.php index c408c0d..960a7dc 100644 --- a/renderer.php +++ b/renderer.php @@ -153,37 +153,43 @@ class mod_attforblock_renderer extends plugin_renderer_base { } protected function render_sess_manage_table(attforblock_sessions_manage_data $sessdata) { - $sesstable = new html_table(); - $sesstable->width = '100%'; - $sesstable->head = array( + $table = new html_table(); + $table->width = '100%'; + $table->head = array( '#', get_string('sessiontypeshort', 'attforblock'), - get_string('date'), get_string('from'), - ($sessdata->showendtime == '0') ? get_string('duration', 'attforblock') : get_string('to'), + get_string('date'), + get_string('time'), get_string('description','attforblock'), get_string('actions'), get_string('select') ); - $sesstable->align = array('', '', '', 'right', 'left', 'center', 'center'); - $sesstable->size = array('1px', '', '1px', '1px', '1px', '*', '1px', '1px'); + $table->align = array('', '', '', '', 'center', 'center', 'center'); + $table->size = array('1px', '', '1px', '1px', '*', '1px', '1px'); $i = 0; foreach ($sessdata->sessions as $key => $sess) { $i++; $actions = ''; - $desctext = empty($sess->description) ? get_string('nodescription', 'attforblock') : $sess->description; - if($sess->lasttaken > 0) //attendance has taken + $desc = empty($sess->description) ? get_string('nodescription', 'attforblock') : $sess->description; + + $date = userdate($sess->sessdate, get_string('strftimedmyw', 'attforblock')); + $starttime = userdate($sess->sessdate, get_string('strftimehm', 'attforblock')); + $endtime = userdate($sess->sessdate + $sess->duration, get_string('strftimehm', 'attforblock')); + $time = html_writer::tag('nobr', $starttime . ($sess->duration > 0 ? ' - ' . $endtime : '')); + if($sess->lasttaken > 0) { if ($sessdata->perm->can_change()) { $url = $sessdata->url_take($sess->id, $sess->groupid); $title = get_string('changeattendance','attforblock'); - $desc = html_writer::link($url, $desctext, array('title' => $title)); + $date = html_writer::link($url, $date, array('title' => $title)); + $time = html_writer::link($url, $time, array('title' => $title)); } else { - $desc = '' . $desctext . ''; + $date = '' . $date . ''; + $time = '' . $time . ''; } } else { - $desc = $desctext; if ($sessdata->perm->can_take()) { $url = $sessdata->url_take($sess->id, $sess->groupid); $title = get_string('takeattendance','attforblock'); @@ -200,33 +206,25 @@ class mod_attforblock_renderer extends plugin_renderer_base { $actions .= $this->output->action_icon($url, new pix_icon('t/delete', $title)); } - $sesstable->data[$sess->id][] = $i; - $sesstable->data[$sess->id][] = $sess->groupid ? $sessdata->groups[$sess->groupid]->name : get_string('commonsession', 'attforblock'); - $sesstable->data[$sess->id][] = userdate($sess->sessdate, get_string('strftimedmyw', 'attforblock')); - $sesstable->data[$sess->id][] = userdate($sess->sessdate, get_string('strftimehm', 'attforblock')); - $hours = floor($sess->duration / HOURSECS); - $mins = floor(($sess->duration - $hours * HOURSECS) / MINSECS); - $mins = $mins < 10 ? "0$mins" : "$mins"; - $duration = "{$mins} " . get_string('min'); - if ($hours) - $duration = "{$hours} " . get_string('hours') . " " . $duration; - $endtime = userdate($sess->sessdate+$sess->duration, get_string('strftimehm', 'attforblock')); - $sesstable->data[$sess->id][] = ($sessdata->showendtime == 0) ? $duration : $endtime; - $sesstable->data[$sess->id][] = $desc; - $sesstable->data[$sess->id][] = $actions; - $sesstable->data[$sess->id][] = html_writer::checkbox('sessid', $sess->id, false); + $table->data[$sess->id][] = $i; + $table->data[$sess->id][] = $sess->groupid ? $sessdata->groups[$sess->groupid]->name : get_string('commonsession', 'attforblock'); + $table->data[$sess->id][] = $date; + $table->data[$sess->id][] = $time; + $table->data[$sess->id][] = $desc; + $table->data[$sess->id][] = $actions; + $table->data[$sess->id][] = html_writer::checkbox('sessid', $sess->id, false); } - return html_writer::table($sesstable); + return html_writer::table($table); } protected function render_sess_control_table(attforblock_sessions_manage_data $sessdata) { - $controltable = new html_table(); - $controltable->attributes['class'] = ' '; - $controltable->width = '100%'; - $controltable->align = array('left', 'right'); + $table = new html_table(); + $table->attributes['class'] = ' '; + $table->width = '100%'; + $table->align = array('left', 'right'); - $controltable->data[0][] = $this->output->help_icon('hiddensessions', 'attforblock', + $table->data[0][] = $this->output->help_icon('hiddensessions', 'attforblock', get_string('hiddensessions', 'attforblock').': '.$sessdata->hiddensessionscount); $controls = html_writer::link('javascript:checkall();', get_string('selectall')).' / '. @@ -244,9 +242,118 @@ class mod_attforblock_renderer extends plugin_renderer_base { } else { $controls .= get_string('youcantdo', 'attforblock'); //You can't do anything } - $controltable->data[0][] = $controls; + $table->data[0][] = $controls; + + return html_writer::table($table); + } + + protected function render_attforblock_take_data(attforblock_take_data $takedata) { + $controls = ''; + if ($takedata->pageparams->grouptype == attforblock::SESSION_COMMON and + ($takedata->groupmode == VISIBLEGROUPS or + ($takedata->groupmode and $takedata->perm->can_access_all_groups()))) { + $controls .= groups_print_activity_menu($takedata->cm, $takedata->url(), true); + } + + $controls = html_writer::tag('div', $controls); + + $table = $this->render_attforblock_take_list($takedata); + $table .= html_writer::input_hidden_params($takedata->url()); + $params = array( + 'type' => 'submit', + 'value' => get_string('save','attforblock')); + $table .= html_writer::tag('center', html_writer::empty_tag('input', $params)); + $table = html_writer::tag('form', $table, array('method' => 'post', 'action' => $takedata->url_path())); + return $table; + } + + protected function render_attforblock_take_list(attforblock_take_data $takedata) { + $table = new html_table(); + $table->width = '0%'; + $table->head = array( + '#', + $this->get_fullname_head($takedata) + ); + $table->align = array('left', 'left'); + $table->size = array('20px', ''); + $table->wrap[1] = 'nowrap'; + foreach ($takedata->statuses as $st) { + $table->head[] = html_writer::link("javascript:select_all_in(null, 'st" . $st->id . "', null);", $st->acronym, array('title' => get_string('setallstatusesto', 'attforblock', $st->description))); + $table->align[] = 'center'; + $table->size[] = '20px'; + } + $table->head[] = get_string('remarks', 'attforblock'); + $table->align[] = 'center'; + $table->size[] = '20px'; + $table->attributes['class'] = 'generaltable taketable'; + + $i = 0; + foreach ($takedata->users as $user) { + $i++; + $row = new html_table_row(); + $row->cells[] = $i; + $row->cells[] = $this->output->render(new user_picture($user)).fullname($user); + if ($user->enrolmentstart > $takedata->sessioninfo->sessdate) { + $cell = new html_table_cell(get_string('enrolmentstart', 'attforblock', userdate($user->enrolmentstart, '%d.%m.%Y'))); + $cell->colspan = count($takedata->statuses) + 1; + $row->cells[] = $cell; + $row->attributes['class'] = 'userwithoutenrol'; + } + elseif ($user->enrolmentstatus == ENROL_USER_SUSPENDED) { + $cell = new html_table_cell(get_string('enrolmentsuspended', 'attforblock')); + $cell->colspan = count($takedata->statuses) + 1; + $row->cells[] = $cell; + $row->attributes['class'] = 'userwithoutenrol'; + } + else { + if ($takedata->updatemode and !array_key_exists($user->id, $takedata->sessionlog)) + $row->attributes['class'] = 'userwithoutdata'; + + foreach ($takedata->statuses as $st) { + $params = array( + 'type' => 'radio', + 'name' => 'user'.$user->id, + 'class' => 'st'.$st->id, + 'value' => $st->id); + if (array_key_exists($user->id, $takedata->sessionlog) and $st->id == $takedata->sessionlog[$user->id]->statusid) + $params['checked'] = ''; + $row->cells[] = html_writer::empty_tag('input', $params); + } + $params = array( + 'type' => 'text', + 'name' => 'remarks'.$user->id); + if (array_key_exists($user->id, $takedata->sessionlog)) + $params['value'] = $takedata->sessionlog[$user->id]->remarks; + $row->cells[] = html_writer::empty_tag('input', $params); + } + //$row->attributes['class'] = + + $table->data[] = $row; + } + return html_writer::table($table); + + } + + private function get_fullname_head(attforblock_take_data $takedata) { + global $CFG; + + if ($takedata->pageparams->sort == att_take_page_params::SORT_LASTNAME) + $firstname = html_writer::link($takedata->url(array('sort' => att_take_page_params::SORT_FIRSTNAME)), get_string('firstname')); + else + $firstname = get_string('firstname'); + + if ($takedata->pageparams->sort == att_take_page_params::SORT_FIRSTNAME) + $lastname = html_writer::link($takedata->url(array('sort' => att_take_page_params::SORT_LASTNAME)), get_string('lastname')); + else + $lastname = get_string('lastname'); + + if ($CFG->fullnamedisplay == 'lastname firstname') { + $fullnamehead = "$lastname / $firstname"; + } else { + $fullnamehead = "$firstname / $lastname"; + } - return html_writer::table($controltable); + return $fullnamehead; } } diff --git a/sessions.php b/sessions.php index 0438937..54314be 100644 --- a/sessions.php +++ b/sessions.php @@ -9,7 +9,7 @@ require_once(dirname(__FILE__).'/duration_form.php'); $pageparams = new att_sessions_page_params(); $id = required_param('id', PARAM_INT); -$pageparams->action = required_param('action', PARAM_INT); +$pageparams->action = required_param('action', PARAM_INT); $cm = get_coursemodule_from_id('attforblock', $id, 0, false, MUST_EXIST); $course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST); @@ -41,7 +41,7 @@ switch ($att->pageparams->action) { } else { $att->add_session_from_form_data($formdata); - redirect($url, get_string('sessionadded','attforblock'), 3); + redirect($url, get_string('sessionadded','attforblock')); } } @@ -60,7 +60,7 @@ switch ($att->pageparams->action) { if ($mform->is_submitted()) { $att->update_session_from_form_data($mform->get_data(), $sessionid); - redirect($att->url_manage(), get_string('sessionupdated','attforblock'), 3); + redirect($att->url_manage(), get_string('sessionupdated','attforblock')); } break; } diff --git a/styles.css b/styles.css index 1064dea..e1f410e 100644 --- a/styles.css +++ b/styles.css @@ -31,6 +31,23 @@ margin: auto; } +.path-mod-attforblock .userwithoutenrol { + color: gray; +} + +.path-mod-attforblock .userwithoutdata { + color: red; +} + +.path-mod-attforblock .taketable td { + vertical-align: middle; +} + +.path-mod-attforblock .taketable .userpicture { + margin:0 3px; + vertical-align:middle; +} + .path-mod-attforblock #mod-attforblock-attendances table.controls { width: 100%; text-align: center; @@ -55,19 +72,3 @@ .path-mod-attforblock .filtercontrols td { padding:6px; } - -/*wwwroot}/lib/yui" -?> -/* -Copyright (c) 2010, Yahoo! Inc. All rights reserved. -Code licensed under the BSD License: -http://developer.yahoo.net/yui/license.txt -version: 2.8.1 -*/ -/*.yuidialog body{font:13px/1.231 arial,helvetica,clean,sans-serif;*font-size:small;*font:x-small;} .yuidialog select,.yuidialog input,.yuidialog button,.yuidialog textarea,.yuidialog button{font:99% arial,helvetica,clean,sans-serif;} .yuidialog table{font-size:inherit;font:100%;} .yuidialog pre,.yuidialog code,.yuidialog kbd,.yuidialog samp,.yuidialog tt{font-family:monospace;*font-size:108%;line-height:100%;} -.yui-button{display:-moz-inline-box;display:inline-block;vertical-align:text-bottom;}.yui-button .first-child{display:block;*display:inline-block;}.yui-button button,.yui-button a{display:block;*display:inline-block;border:none;margin:0;}.yui-button button{background-color:transparent;*overflow:visible;cursor:pointer;}.yui-button a{text-decoration:none;}.yui-skin-sam .yui-button{border-width:1px 0;border-style:solid;border-color:#808080;background:url(http://yui.yahooapis.com/2.8.1/build/assets/skins/sam/sprite.png) repeat-x 0 0;margin:auto .25em;}.yui-skin-sam .yui-button .first-child{border-width:0 1px;border-style:solid;border-color:#808080;margin:0 -1px;_margin:0;}.yui-skin-sam .yui-button button,.yui-skin-sam .yui-button a,.yui-skin-sam .yui-button a:visited{padding:0 10px;font-size:93%;line-height:2;*line-height:1.7;min-height:2em;*min-height:auto;color:#000;}.yui-skin-sam .yui-button a{*line-height:1.875;*padding-bottom:1px;}.yui-skin-sam .yui-split-button button,.yui-skin-sam .yui-menu-button button{padding-right:20px;background-position:right center;background-repeat:no-repeat;}.yui-skin-sam .yui-menu-button button{background-image:url(/assets/skins/sam/menu-button-arrow.png);}.yui-skin-sam .yui-split-button button{background-image:url(/assets/skins/sam/split-button-arrow.png);}.yui-skin-sam .yui-button-focus{border-color:#7D98B8;background-position:0 -1300px;}.yui-skin-sam .yui-button-focus .first-child{border-color:#7D98B8;}.yui-skin-sam .yui-split-button-focus button{background-image:url(/assets/skins/sam/split-button-arrow-focus.png);}.yui-skin-sam .yui-button-hover{border-color:#7D98B8;background-position:0 -1300px;}.yui-skin-sam .yui-button-hover .first-child{border-color:#7D98B8;}.yui-skin-sam .yui-split-button-hover button{background-image:url(/assets/skins/sam/split-button-arrow-hover.png);}.yui-skin-sam .yui-button-active{border-color:#7D98B8;background-position:0 -1700px;}.yui-skin-sam .yui-button-active .first-child{border-color:#7D98B8;}.yui-skin-sam .yui-split-button-activeoption{border-color:#808080;background-position:0 0;}.yui-skin-sam .yui-split-button-activeoption .first-child{border-color:#808080;}.yui-skin-sam .yui-split-button-activeoption button{background-image:url(/assets/skins/sam/split-button-arrow-active.png);}.yui-skin-sam .yui-radio-button-checked,.yui-skin-sam .yui-checkbox-button-checked{border-color:#304369;background-position:0 -1400px;}.yui-skin-sam .yui-radio-button-checked .first-child,.yui-skin-sam .yui-checkbox-button-checked .first-child{border-color:#304369;}.yui-skin-sam .yui-radio-button-checked button,.yui-skin-sam .yui-checkbox-button-checked button{color:#fff;}.yui-skin-sam .yui-button-disabled{border-color:#ccc;background-position:0 -1500px;}.yui-skin-sam .yui-button-disabled .first-child{border-color:#ccc;}.yui-skin-sam .yui-button-disabled button,.yui-skin-sam .yui-button-disabled a,.yui-skin-sam .yui-button-disabled a:visited{color:#A6A6A6;cursor:default;}.yui-skin-sam .yui-menu-button-disabled button{background-image:url(/assets/skins/sam/menu-button-arrow-disabled.png);}.yui-skin-sam .yui-split-button-disabled button{background-image:url(/assets/skins/sam/split-button-arrow-disabled.png);} -.yui-overlay,.yui-panel-container{visibility:hidden;position:absolute;z-index:2;}.yui-panel{position:relative;}.yui-panel-container form{margin:0;}.mask{z-index:1;display:none;position:absolute;top:0;left:0;right:0;bottom:0;}.mask.block-scrollbars{overflow:auto;}.masked select,.drag select,.hide-select select{_visibility:hidden;}.yui-panel-container select{_visibility:inherit;}.hide-scrollbars,.hide-scrollbars *{overflow:hidden;}.hide-scrollbars select{display:none;}.show-scrollbars{overflow:auto;}.yui-panel-container.show-scrollbars,.yui-tt.show-scrollbars{overflow:visible;}.yui-panel-container.show-scrollbars .underlay,.yui-tt.show-scrollbars .yui-tt-shadow{overflow:auto;}.yui-panel-container.shadow .underlay.yui-force-redraw{padding-bottom:1px;}.yui-effect-fade .underlay,.yui-effect-fade .yui-tt-shadow{display:none;}.yui-tt-shadow{position:absolute;}.yui-override-padding{padding:0!important;}.yui-panel-container .container-close{overflow:hidden;text-indent:-10000em;text-decoration:none;}.yui-overlay.yui-force-redraw,.yui-panel-container.yui-force-redraw{margin-bottom:1px;}.yui-skin-sam .mask{background-color:#000;opacity:.25;filter:alpha(opacity=25);}.yui-skin-sam .yui-panel-container{padding:0 1px;*padding:2px;}.yui-skin-sam .yui-panel{position:relative;left:0;top:0;border-style:solid;border-width:1px 0;border-color:#808080;z-index:1;*border-width:1px;*zoom:1;_zoom:normal;}.yui-skin-sam .yui-panel .hd,.yui-skin-sam .yui-panel .bd,.yui-skin-sam .yui-panel .ft{border-style:solid;border-width:0 1px;border-color:#808080;margin:0 -1px;*margin:0;*border:0;}.yui-skin-sam .yui-panel .hd{border-bottom:solid 1px #ccc;}.yui-skin-sam .yui-panel .bd,.yui-skin-sam .yui-panel .ft{background-color:#F2F2F2;}.yui-skin-sam .yui-panel .hd{padding:0 10px;font-size:93%;line-height:2;*line-height:1.9;font-weight:bold;color:#000;background:url(http://yui.yahooapis.com/2.8.1/build/assets/skins/sam/sprite.png) repeat-x 0 -200px;}.yui-skin-sam .yui-panel .bd{padding:10px;}.yui-skin-sam .yui-panel .ft{border-top:solid 1px #808080;padding:5px 10px;font-size:77%;}.yui-skin-sam .container-close{position:absolute;top:5px;right:6px;width:25px;height:15px;background:url(http://yui.yahooapis.com/2.8.1/build/assets/skins/sam/sprite.png) no-repeat 0 -300px;cursor:pointer;}.yui-skin-sam .yui-panel-container .underlay{right:-1px;left:-1px;}.yui-skin-sam .yui-panel-container.matte{padding:9px 10px;background-color:#fff;}.yui-skin-sam .yui-panel-container.shadow{_padding:2px 4px 0 2px;}.yui-skin-sam .yui-panel-container.shadow .underlay{position:absolute;top:2px;left:-3px;right:-3px;bottom:-3px;*top:4px;*left:-1px;*right:-1px;*bottom:-1px;_top:0;_left:0;_right:0;_bottom:0;_margin-top:3px;_margin-left:-1px;background-color:#000;opacity:.12;filter:alpha(opacity=12);}.yui-skin-sam .yui-dialog .ft{border-top:none;padding:0 10px 10px 10px;font-size:100%;}.yui-skin-sam .yui-dialog .ft .button-group{display:block;text-align:right;}.yui-skin-sam .yui-dialog .ft button.default{font-weight:bold;}.yui-skin-sam .yui-dialog .ft span.default{border-color:#304369;background-position:0 -1400px;}.yui-skin-sam .yui-dialog .ft span.default .first-child{border-color:#304369;}.yui-skin-sam .yui-dialog .ft span.default button{color:#fff;}.yui-skin-sam .yui-dialog .ft span.yui-button-disabled{background-position:0 -1500px;border-color:#ccc;}.yui-skin-sam .yui-dialog .ft span.yui-button-disabled .first-child{border-color:#ccc;}.yui-skin-sam .yui-dialog .ft span.yui-button-disabled button{color:#a6a6a6;}.yui-skin-sam .yui-simple-dialog .bd .yui-icon{background:url(http://yui.yahooapis.com/2.8.1/build/assets/skins/sam/sprite.png) no-repeat 0 0;width:16px;height:16px;margin-right:10px;float:left;}.yui-skin-sam .yui-simple-dialog .bd span.blckicon{background-position:0 -1100px;}.yui-skin-sam .yui-simple-dialog .bd span.alrticon{background-position:0 -1050px;}.yui-skin-sam .yui-simple-dialog .bd span.hlpicon{background-position:0 -1150px;}.yui-skin-sam .yui-simple-dialog .bd span.infoicon{background-position:0 -1200px;}.yui-skin-sam .yui-simple-dialog .bd span.warnicon{background-position:0 -1900px;}.yui-skin-sam .yui-simple-dialog .bd span.tipicon{background-position:0 -1250px;}.yui-skin-sam .yui-tt .bd{position:relative;top:0;left:0;z-index:1;color:#000;padding:2px 5px;border-color:#D4C237 #A6982B #A6982B #A6982B;border-width:1px;border-style:solid;background-color:#FFEE69;}.yui-skin-sam .yui-tt.show-scrollbars .bd{overflow:auto;}.yui-skin-sam .yui-tt-shadow{top:2px;right:-3px;left:-3px;bottom:-3px;background-color:#000;}.yui-skin-sam .yui-tt-shadow-visible{opacity:.12;filter:alpha(opacity=12);} -.yui-calcontainer{position:relative;float:left;_overflow:hidden;}.yui-calcontainer iframe{position:absolute;border:none;margin:0;padding:0;z-index:0;width:100%;height:100%;left:0;top:0;}.yui-calcontainer iframe.fixedsize{width:50em;height:50em;top:-1px;left:-1px;}.yui-calcontainer.multi .groupcal{z-index:1;float:left;position:relative;}.yui-calcontainer .title{position:relative;z-index:1;}.yui-calcontainer .close-icon{position:absolute;z-index:1;text-indent:-10000em;overflow:hidden;}.yui-calendar{position:relative;}.yui-calendar .calnavleft{position:absolute;z-index:1;text-indent:-10000em;overflow:hidden;}.yui-calendar .calnavright{position:absolute;z-index:1;text-indent:-10000em;overflow:hidden;}.yui-calendar .calheader{position:relative;width:100%;text-align:center;}.yui-calcontainer .yui-cal-nav-mask{position:absolute;z-index:2;margin:0;padding:0;width:100%;height:100%;_width:0;_height:0;left:0;top:0;display:none;}.yui-calcontainer .yui-cal-nav{position:absolute;z-index:3;top:0;display:none;}.yui-calcontainer .yui-cal-nav .yui-cal-nav-btn{display:-moz-inline-box;display:inline-block;}.yui-calcontainer .yui-cal-nav .yui-cal-nav-btn button{display:block;*display:inline-block;*overflow:visible;border:none;background-color:transparent;cursor:pointer;}.yui-calendar .calbody a:hover{background:inherit;}p#clear{clear:left;padding-top:10px;}.yui-skin-sam .yui-calcontainer{background-color:#f2f2f2;border:1px solid #808080;padding:10px;}.yui-skin-sam .yui-calcontainer.multi{padding:0 5px 0 5px;}.yui-skin-sam .yui-calcontainer.multi .groupcal{background-color:transparent;border:none;padding:10px 5px 10px 5px;margin:0;}.yui-skin-sam .yui-calcontainer .title{background:url(http://yui.yahooapis.com/2.8.1/build/assets/skins/sam/sprite.png) repeat-x 0 0;border-bottom:1px solid #ccc;font:100% sans-serif;color:#000;font-weight:bold;height:auto;padding:.4em;margin:0 -10px 10px -10px;top:0;left:0;text-align:left;}.yui-skin-sam .yui-calcontainer.multi .title{margin:0 -5px 0 -5px;}.yui-skin-sam .yui-calcontainer.withtitle{padding-top:0;}.yui-skin-sam .yui-calcontainer .calclose{background:url(http://yui.yahooapis.com/2.8.1/build/assets/skins/sam/sprite.png) no-repeat 0 -300px;width:25px;height:15px;top:.4em;right:.4em;cursor:pointer;}.yui-skin-sam .yui-calendar{border-spacing:0;border-collapse:collapse;font:100% sans-serif;text-align:center;margin:0;}.yui-skin-sam .yui-calendar .calhead{background:transparent;border:none;vertical-align:middle;padding:0;}.yui-skin-sam .yui-calendar .calheader{background:transparent;font-weight:bold;padding:0 0 .6em 0;text-align:center;}.yui-skin-sam .yui-calendar .calheader img{border:none;}.yui-skin-sam .yui-calendar .calnavleft{background:url(http://yui.yahooapis.com/2.8.1/build/assets/skins/sam/sprite.png) no-repeat 0 -450px;width:25px;height:15px;top:0;bottom:0;left:-10px;margin-left:.4em;cursor:pointer;}.yui-skin-sam .yui-calendar .calnavright{background:url(http://yui.yahooapis.com/2.8.1/build/assets/skins/sam/sprite.png) no-repeat 0 -500px;width:25px;height:15px;top:0;bottom:0;right:-10px;margin-right:.4em;cursor:pointer;}.yui-skin-sam .yui-calendar .calweekdayrow{height:2em;}.yui-skin-sam .yui-calendar .calweekdayrow th{padding:0;border:none;}.yui-skin-sam .yui-calendar .calweekdaycell{color:#000;font-weight:bold;text-align:center;width:2em;}.yui-skin-sam .yui-calendar .calfoot{background-color:#f2f2f2;}.yui-skin-sam .yui-calendar .calrowhead,.yui-skin-sam .yui-calendar .calrowfoot{color:#a6a6a6;font-size:85%;font-style:normal;font-weight:normal;border:none;}.yui-skin-sam .yui-calendar .calrowhead{text-align:right;padding:0 2px 0 0;}.yui-skin-sam .yui-calendar .calrowfoot{text-align:left;padding:0 0 0 2px;}.yui-skin-sam .yui-calendar td.calcell{border:1px solid #ccc;background:#fff;padding:1px;height:1.6em;line-height:1.6em;text-align:center;white-space:nowrap;}.yui-skin-sam .yui-calendar td.calcell a{color:#06c;display:block;height:100%;text-decoration:none;}.yui-skin-sam .yui-calendar td.calcell.today{background-color:#000;}.yui-skin-sam .yui-calendar td.calcell.today a{background-color:#fff;}.yui-skin-sam .yui-calendar td.calcell.oom{background-color:#ccc;color:#a6a6a6;cursor:default;}.yui-skin-sam .yui-calendar td.calcell.selected{background-color:#fff;color:#000;}.yui-skin-sam .yui-calendar td.calcell.selected a{background-color:#b3d4ff;color:#000;}.yui-skin-sam .yui-calendar td.calcell.calcellhover{background-color:#426fd9;color:#fff;cursor:pointer;}.yui-skin-sam .yui-calendar td.calcell.calcellhover a{background-color:#426fd9;color:#fff;}.yui-skin-sam .yui-calendar td.calcell.previous{color:#e0e0e0;}.yui-skin-sam .yui-calendar td.calcell.restricted{text-decoration:line-through;}.yui-skin-sam .yui-calendar td.calcell.highlight1{background-color:#cf9;}.yui-skin-sam .yui-calendar td.calcell.highlight2{background-color:#9cf;}.yui-skin-sam .yui-calendar td.calcell.highlight3{background-color:#fcc;}.yui-skin-sam .yui-calendar td.calcell.highlight4{background-color:#cf9;}.yui-skin-sam .yui-calendar a.calnav{border:1px solid #f2f2f2;padding:0 4px;text-decoration:none;color:#000;zoom:1;}.yui-skin-sam .yui-calendar a.calnav:hover{background:url(http://yui.yahooapis.com/2.8.1/build/assets/skins/sam/sprite.png) repeat-x 0 0;border-color:#A0A0A0;cursor:pointer;}.yui-skin-sam .yui-calcontainer .yui-cal-nav-mask{background-color:#000;opacity:.25;filter:alpha(opacity=25);}.yui-skin-sam .yui-calcontainer .yui-cal-nav{font-family:arial,helvetica,clean,sans-serif;font-size:93%;border:1px solid #808080;left:50%;margin-left:-7em;width:14em;padding:0;top:2.5em;background-color:#f2f2f2;}.yui-skin-sam .yui-calcontainer.withtitle .yui-cal-nav{top:4.5em;}.yui-skin-sam .yui-calcontainer.multi .yui-cal-nav{width:16em;margin-left:-8em;}.yui-skin-sam .yui-calcontainer .yui-cal-nav-y,.yui-skin-sam .yui-calcontainer .yui-cal-nav-m,.yui-skin-sam .yui-calcontainer .yui-cal-nav-b{padding:5px 10px 5px 10px;}.yui-skin-sam .yui-calcontainer .yui-cal-nav-b{text-align:center;}.yui-skin-sam .yui-calcontainer .yui-cal-nav-e{margin-top:5px;padding:5px;background-color:#EDF5FF;border-top:1px solid black;display:none;}.yui-skin-sam .yui-calcontainer .yui-cal-nav label{display:block;font-weight:bold;} -.yui-skin-sam .yui-calcontainer .yui-cal-nav-mc{width:100%;_width:auto;}.yui-skin-sam .yui-calcontainer .yui-cal-nav-y input.yui-invalid{background-color:#FFEE69;border:1px solid #000;}.yui-skin-sam .yui-calcontainer .yui-cal-nav-yc{width:4em;}.yui-skin-sam .yui-calcontainer .yui-cal-nav .yui-cal-nav-btn{border:1px solid #808080;background:url(http://yui.yahooapis.com/2.8.1/build/assets/skins/sam/sprite.png) repeat-x 0 0;background-color:#ccc;margin:auto .15em;}.yui-skin-sam .yui-calcontainer .yui-cal-nav .yui-cal-nav-btn button{padding:0 8px;font-size:93%;line-height:2;*line-height:1.7;min-height:2em;*min-height:auto;color:#000;}.yui-skin-sam .yui-calcontainer .yui-cal-nav .yui-cal-nav-btn.yui-default{border:1px solid #304369;background-color:#426fd9;background:url(http://yui.yahooapis.com/2.8.1/build/assets/skins/sam/sprite.png) repeat-x 0 -1400px;}.yui-skin-sam .yui-calcontainer .yui-cal-nav .yui-cal-nav-btn.yui-default button{color:#fff;} -*/ \ No newline at end of file diff --git a/take.php b/take.php new file mode 100644 index 0000000..d7a1469 --- /dev/null +++ b/take.php @@ -0,0 +1,52 @@ +sessionid = required_param('sessionid', PARAM_INT); +$pageparams->grouptype = required_param('grouptype', PARAM_INT); +$pageparams->group = optional_param('group', null, PARAM_INT); +$pageparams->sort = optional_param('sort', null, PARAM_INT); +$pageparams->copyfrom = optional_param('copyfrom', null, PARAM_INT); +$pageparams->view_mode = optional_param('view', null, PARAM_INT); +$pageparams->gridcols = optional_param('gridcols', null, PARAM_INT); + +$cm = get_coursemodule_from_id('attforblock', $id, 0, false, MUST_EXIST); +$course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST); +$att = $DB->get_record('attforblock', array('id' => $cm->instance), '*', MUST_EXIST); + +require_login($course, true, $cm); + +$pageparams->init($course->id); +$att = new attforblock($att, $cm, $course, $PAGE->context, $pageparams); + +if ($formdata = data_submitted()) { + $att->take_from_form_data($formdata); +} + +$PAGE->set_url($att->url_take()); +$PAGE->set_title($course->shortname. ": ".$att->name); +$PAGE->set_heading($course->fullname); +$PAGE->set_cacheable(true); +$PAGE->set_button($OUTPUT->update_module_button($cm->id, 'attforblock')); +$PAGE->navbar->add($att->name); + +$output = $PAGE->get_renderer('mod_attforblock'); +$tabs = new attforblock_tabs($att); +$sesstable = new attforblock_take_data($att); + +/// Output starts here + +echo $output->header(); +echo $output->heading(get_string('attendanceforthecourse','attforblock').' :: ' .$course->fullname); +echo $output->render($tabs); +echo $output->render($sesstable); + +echo $output->footer(); + + + +?>