From b55a30c34029e540a659f82fbb884449273cfac3 Mon Sep 17 00:00:00 2001 From: Artem Andreev Date: Sat, 11 Jun 2011 18:18:07 +0400 Subject: [PATCH] Implemented "This course" mode of view.php + related refactoring + enhancement: taken into account information about students enrolment(start/end date). --- lang/en/attforblock.php | 1 + lang/ru/attforblock.php | 3 + locallib.php | 263 +++++++++++++++++++++++++++++++++++----- manage.php | 4 +- renderables.php | 123 ++++++++++++------- renderer.php | 170 ++++++++++++++++++++++---- styles.css | 11 ++ view.php | 49 +++++--- 8 files changed, 506 insertions(+), 118 deletions(-) diff --git a/lang/en/attforblock.php b/lang/en/attforblock.php index e6eb987..0673f77 100644 --- a/lang/en/attforblock.php +++ b/lang/en/attforblock.php @@ -76,6 +76,7 @@ $string['duration'] = 'Duration'; $string['editsession'] = 'Edit Session'; $string['endtime'] = 'Session end time'; $string['endofperiod'] = 'End of period'; +$string['enrolmentend'] = 'User enrolment ends {$a}'; $string['enrolmentstart'] = 'User enrolment starts {$a}'; $string['enrolmentsuspended'] = 'Enrolment suspended'; $string['errorgroupsnotselected'] = 'Select one or more groups'; diff --git a/lang/ru/attforblock.php b/lang/ru/attforblock.php index 2c6b613..2667152 100644 --- a/lang/ru/attforblock.php +++ b/lang/ru/attforblock.php @@ -15,6 +15,7 @@ $string['add'] = 'Добавить'; $string['addmultiplesessions'] = 'Добавить несколько занятий'; $string['addsession'] = 'Добавить занятие'; $string['all'] = 'Все'; +$string['allcourses'] = 'Все курсы'; $string['alltaken'] = 'Все прошедшие'; $string['attendanceforthecourse'] = 'Посещаемость для курса'; $string['attendancegrade'] = 'Оценка за посещаемость'; @@ -62,6 +63,7 @@ $string['downloadtext'] = 'Скачать в текстовом формате'; $string['duration'] = 'Продолжительность'; $string['editsession'] = 'Редактировать занятие'; $string['endofperiod'] = 'Конец периода'; +$string['enrolmentend'] = 'Подписка на курс заканчивается {$a}'; $string['enrolmentstart'] = 'Подписка на курс начинается с {$a}'; $string['enrolmentsuspended'] = 'Подписка на курс приостановлена'; $string['errorgroupsnotselected'] = 'Выберите одну или более групп'; @@ -141,6 +143,7 @@ $string['strftimehm'] = '%H:%M'; $string['strftimeshortdate'] = '%%d.%%m.%%Y'; $string['studentid'] = 'ID студента'; $string['takeattendance'] = 'Отметить посещаемость'; +$string['thiscourse'] = 'Текущий курс'; $string['update'] = 'Обновить'; $string['variable'] = 'переменную'; $string['variablesupdated'] = 'Переменные успешно обновлены'; diff --git a/locallib.php b/locallib.php index b2969ab..bbb7235 100644 --- a/locallib.php +++ b/locallib.php @@ -5,6 +5,12 @@ defined('MOODLE_INTERNAL') || die(); global $CFG; require_once($CFG->libdir . '/gradelib.php'); +define('VIEW_DAYS', 1); +define('VIEW_WEEKS', 2); +define('VIEW_MONTHS', 3); +define('VIEW_ALLTAKEN', 4); +define('VIEW_ALL', 5); + class attforblock_permissions { private $canview; private $canviewreports; @@ -29,7 +35,11 @@ class attforblock_permissions { return $this->canview; } - public function can_viewreports() { + public function require_view_capability() { + require_capability('mod/attforblock:view', $this->context); + } + + public function can_view_reports() { if (is_null($this->canviewreports)) $this->canviewreports = has_capability('mod/attforblock:viewreports', $this->context); @@ -90,20 +100,11 @@ class attforblock_permissions { } } -class att_manage_page_params { - const VIEW_DAYS = 1; - const VIEW_WEEKS = 2; - const VIEW_MONTHS = 3; - const VIEW_ALLTAKEN = 4; - const VIEW_ALL = 5; - +class att_page_with_filter_controls { const SELECTOR_NONE = 1; const SELECTOR_GROUP = 2; const SELECTOR_SESS_TYPE = 3; - const DEFAULT_VIEW = self::VIEW_WEEKS; - const DEFAULT_SHOWENDTIME = 0; - /** @var int current view mode */ public $view; @@ -116,8 +117,9 @@ class att_manage_page_params { /** @var int end date of displayed date range */ public $enddate; - /** @var int whether sessions end time will be displayed on manage.php */ - public $showendtime; + public $selectortype = self::SELECTOR_NONE; + + protected $defaultview = VIEW_WEEKS; private $courseid; @@ -125,7 +127,6 @@ class att_manage_page_params { $this->courseid = $courseid; $this->init_view(); $this->init_curdate(); - $this->init_show_endtime(); $this->init_start_end_date(); } @@ -139,7 +140,7 @@ class att_manage_page_params { $this->view = $SESSION->attcurrentattview[$this->courseid]; } else { - $this->view = self::DEFAULT_VIEW; + $this->view = $this->defaultview; } } @@ -157,15 +158,6 @@ class att_manage_page_params { } } - private function init_show_endtime() { - if (isset($this->show_endtime)) { - set_user_preference("attforblock_showendtime", $this->show_endtime); - } - else { - $this->showendtime = get_user_preferences("attforblock_showendtime", self::DEFAULT_SHOWENDTIME); - } - } - private function init_start_end_date() { $date = usergetdate($this->curdate); $mday = $date['mday']; @@ -174,28 +166,56 @@ class att_manage_page_params { $year = $date['year']; switch ($this->view) { - case self::VIEW_DAYS: + case VIEW_DAYS: $this->startdate = make_timestamp($year, $mon, $mday); $this->enddate = make_timestamp($year, $mon, $mday + 1); break; - case self::VIEW_WEEKS: + case VIEW_WEEKS: $this->startdate = make_timestamp($year, $mon, $mday - $wday + 1); $this->enddate = make_timestamp($year, $mon, $mday + 7 - $wday + 1) - 1; break; - case self::VIEW_MONTHS: + case VIEW_MONTHS: $this->startdate = make_timestamp($year, $mon); $this->enddate = make_timestamp($year, $mon + 1); break; - case self::VIEW_ALLTAKEN: + case VIEW_ALLTAKEN: $this->startdate = 1; $this->enddate = time(); break; - case self::VIEW_ALL: + case VIEW_ALL: $this->startdate = 0; $this->enddate = 0; break; } } +} + +class att_view_page_params extends att_page_with_filter_controls { + const MODE_THIS_COURSE = 0; + const MODE_ALL_COURSES = 1; + + public $student; + + public $mode; + + public function __construct() { + $this->defaultview = VIEW_MONTHS; + } + + public function get_significant_params() { + $params = array(); + + if (isset($this->student)) $params['student'] = $this->student; + if ($this->mode != self::MODE_THIS_COURSE) $params['mode'] = $this->mode; + + return $params; + } +} + +class att_manage_page_params extends att_page_with_filter_controls { + public function __construct() { + $this->selectortype = self::SELECTOR_SESS_TYPE; + } public function get_significant_params() { return array(); @@ -312,6 +332,8 @@ class attforblock { private $sessioninfo; private $statuses; + private $usertakensesscount; + private $userstatusesstat; /** * Initializes the attendance API instance using the data from DB @@ -439,6 +461,32 @@ class attforblock { return $DB->count_records_select('attendance_sessions', $where, $params); } + public function get_filtered_sessions() { + global $DB; + + if ($this->pageparams->startdate && $this->pageparams->enddate) { + $where = "courseid=:cid AND attendanceid = :aid AND sessdate >= :csdate AND sessdate >= :sdate AND sessdate < :edate"; + } else { + $where = "courseid=:cid AND attendanceid = :aid AND sessdate >= :csdate"; + } + if ($this->get_current_group() > attforblock::SELECTOR_ALL) { + $where .= " AND groupid=:cgroup"; + } + $params = array( + 'cid' => $this->course->id, + 'aid' => $this->id, + 'csdate' => $this->course->startdate, + 'sdate' => $this->pageparams->startdate, + 'edate' => $this->pageparams->enddate, + 'cgroup' => $this->get_current_group()); + $sessions = $DB->get_records_select('attendance_sessions', $where, $params, 'sessdate asc'); + foreach ($sessions as $sess) { + $sess->description = file_rewrite_pluginfile_urls($sess->description, 'pluginfile.php', $this->context->id, 'mod_attforblock', 'session', $sess->id); + } + + return $sessions; + } + /** * @return moodle_url of manage.php for attendance instance */ @@ -730,6 +778,28 @@ class attforblock { return $users; } + public function get_user($userid) { + global $DB; + + $user = $DB->get_record('user', array('id' => $userid), '*', MUST_EXIST); + + $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 = :uid + AND e.status = :estatus + AND e.courseid = :courseid + GROUP BY ue.userid"; + $params = array('uid' => $userid, 'estatus'=>ENROL_INSTANCE_ENABLED, 'courseid'=>$this->course->id); + $enrolmentsparams = $DB->get_record_sql($sql, $params); + + $user->enrolmentstatus = $enrolmentsparams->status; + $user->enrolmentstart = $enrolmentsparams->timestart; + $user->enrolmentend = $enrolmentsparams->timeend; + + return $user; + } + public function get_statuses($onlyvisible = true) { global $DB; @@ -760,6 +830,141 @@ class attforblock { return $DB->get_records('attendance_log', array('sessionid' => $sessionid), '', 'studentid,statusid,remarks,id'); } + + public function get_user_stat($userid) { + global $DB; + + $ret = array(); + $ret['completed'] = $this->get_user_taken_sessions_count($userid); + $ret['statuses'] = $this->get_user_statuses_stat($userid); + + return $ret; + } + + public function get_user_taken_sessions_count($userid, $courseid=NULL) { + global $DB; + + if (!isset($this->usertakensesscount)) { + $qry = "SELECT count(*) as cnt + FROM {attendance_log} al + JOIN {attendance_sessions} ats + ON al.sessionid = ats.id + WHERE ats.attendanceid = :aid AND + ats.sessdate >= :cstartdate AND + al.studentid = :uid"; + $params = array( + 'aid' => $this->id, + 'cstartdate' => $this->course->startdate, + 'uid' => $userid); + + $this->usertakensesscount = $DB->count_records_sql($qry, $params); + } + + return $this->usertakensesscount; + } + + public function get_user_statuses_stat($userid) { + global $DB; + + if (!isset($this->userstatusesstat)) { + $qry = "SELECT al.statusid, count(al.statusid) AS stcnt + FROM {attendance_log} al + JOIN {attendance_sessions} ats + ON al.sessionid = ats.id + WHERE ats.attendanceid = :aid AND + ats.sessdate >= :cstartdate AND + al.studentid = :uid + GROUP BY al.statusid"; + $params = array( + 'aid' => $this->id, + 'cstartdate' => $this->course->startdate, + 'uid' => $userid); + + $this->userstatusesstat = $DB->get_records_sql($qry, $params); + } + + return $this->userstatusesstat; + } + + public function get_user_grade($userid, $courseid=NULL) { + $statistics = $this->get_user_statuses_stat($userid, $courseid); + $statuses = $this->get_statuses($courseid); + + $sum = 0; + foreach ($statistics as $stat) { + $sum += $stat->stcnt * $statuses[$stat->statusid]->grade; + } + + return $sum; + } + + // For getting sessions count implemented simplest method - taken sessions. + // It can have error if users don't have attendance info for some sessions. + // In the future we can implement another methods: + // * all sessions between user start enrolment date and now; + // * all sessions between user start and end enrolment date. + public function get_user_max_grade($userid, $courseid=NULL) { + $takensessions = $this->get_user_taken_sessions_count($userid, $courseid); + $statuses = $this->get_statuses($courseid); + + return current($statuses)->grade * $takensessions; + } + + public function get_user_filtered_sessions_log($userid) { + global $DB; + + if ($this->pageparams->startdate && $this->pageparams->enddate) { + $where = "ats.courseid=:cid AND ats.attendanceid = :aid AND + ats.sessdate >= :csdate AND ats.sessdate >= :sdate AND ats.sessdate < :edate"; + } else { + $where = "AND ats.courseid=:cid AND ats.attendanceid = :aid AND ats.sessdate >= :csdate"; + } + + $sql = "SELECT ats.id, ats.sessdate, ats.duration, ats.description, al.statusid, al.remarks + FROM {attendance_sessions} ats + LEFT JOIN {attendance_log} al + ON ats.id = al.sessionid AND al.studentid = :uid + WHERE $where + ORDER BY ats.sessdate ASC"; + + $params = array( + 'uid' => $userid, + 'cid' => $this->course->id, + 'aid' => $this->id, + 'csdate' => $this->course->startdate, + 'sdate' => $this->pageparams->startdate, + 'edate' => $this->pageparams->enddate); + $sessions = $DB->get_records_sql($sql, $params); + foreach ($sessions as $sess) { + $sess->description = file_rewrite_pluginfile_urls($sess->description, 'pluginfile.php', $this->context->id, 'mod_attforblock', 'session', $sess->id); + } + + return $sessions; + } + + public function get_user_courses_with_attendance($userid) { + global $DB; + + // we can't get user courses based only on attendance_log information + // because of then users will see only courses with taked attendance + $usercourses = enrol_get_users_courses($userid); + + list($usql, $uparams) = $DB->get_in_or_equal(array_keys($usercourses), SQL_PARAMS_NAMED, 'cid0'); + + $sql = "SELECT ats.courseid, course.fullname + FROM {attendance_sessions} ats + JOIN {attendance_log} al + ON ats.id = al.sessionid AND al.studentid = :uid + JOIN {course} course + ON ats.courseid = course.id + WHERE ats.courseid $usql + GROUP BY ats.courseid + ORDER BY course.fullname ASC"; + + $params = array_merge($uparams, array('uid' => $userid)); + + return $DB->get_records_sql($sql, $params); + } } diff --git a/manage.php b/manage.php index fdb2522..8b8f1f5 100644 --- a/manage.php +++ b/manage.php @@ -18,7 +18,6 @@ $id = required_param('id', PARAM_INT); $from = optional_param('from', NULL, PARAM_ACTION); $pageparams ->view = optional_param('view', NULL, PARAM_INT); $pageparams ->curdate = optional_param('curdate', NULL, PARAM_INT); -$pageparams ->showendtime = optional_param('showendtime', 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); @@ -44,7 +43,7 @@ if ($from === 'block') { } elseif ($size > 1) { $att->curdate = $today; //temporally set $view for single access to page from block - $att->$view = attforblock::VIEW_DAYS; + $att->$view = VIEW_DAYS; } } @@ -70,5 +69,4 @@ echo $output->render($sesstable); echo $output->footer(); - ?> diff --git a/renderables.php b/renderables.php index ab2e178..d16a3d1 100644 --- a/renderables.php +++ b/renderables.php @@ -60,7 +60,7 @@ class attforblock_tabs implements renderable { get_string('add','attforblock')); } - if ($this->att->perm->can_viewreports()) { + if ($this->att->perm->can_view_reports()) { $toprow[] = new tabobject(self::TAB_REPORT, $this->att->url_report()->out(), get_string('report','attforblock')); } @@ -82,7 +82,7 @@ class attforblock_tabs implements renderable { class attforblock_filter_controls implements renderable { /** @var int current view mode */ - public $view; + public $pageparams; public $curdate; @@ -98,7 +98,7 @@ class attforblock_filter_controls implements renderable { public function __construct(attforblock $att) { global $PAGE; - $this->view = $att->pageparams->view; + $this->pageparams = $att->pageparams; $this->curdate = $att->pageparams->curdate; @@ -108,20 +108,20 @@ class attforblock_filter_controls implements renderable { $mon = $date['mon']; $year = $date['year']; - switch ($this->view) { - case att_manage_page_params::VIEW_DAYS: + switch ($this->pageparams->view) { + case VIEW_DAYS: $format = get_string('strftimedm', 'attforblock'); $this->prevcur = make_timestamp($year, $mon, $mday - 1); $this->nextcur = make_timestamp($year, $mon, $mday + 1); $this->curdatetxt = userdate($att->pageparams->startdate, $format); break; - case att_manage_page_params::VIEW_WEEKS: + case VIEW_WEEKS: $format = get_string('strftimedm', 'attforblock'); $this->prevcur = $att->pageparams->startdate - WEEKSECS; $this->nextcur = $att->pageparams->startdate + WEEKSECS; $this->curdatetxt = userdate($att->pageparams->startdate, $format)." - ".userdate($att->pageparams->enddate, $format); break; - case att_manage_page_params::VIEW_MONTHS: + case VIEW_MONTHS: $format = '%B'; $this->prevcur = make_timestamp($year, $mon - 1); $this->nextcur = make_timestamp($year, $mon + 1); @@ -171,12 +171,6 @@ class attforblock_filter_controls implements renderable { * */ class attforblock_sessions_manage_data implements renderable { - /** @var int start date of displayed date range */ - public $startdate; - - /** @var int end date of displayed date range */ - public $enddate; - /** @var array of sessions*/ public $sessions; @@ -186,9 +180,6 @@ class attforblock_sessions_manage_data implements renderable { /** @var attforblock_permissions permission of current user for attendance instance*/ public $perm; - /** @var int whether sessions end time will be displayed */ - public $showendtime; - public $groups; public $hiddensesscount; @@ -205,37 +196,7 @@ class attforblock_sessions_manage_data implements renderable { $this->perm = $att->perm; - $this->showendtime = $att->pageparams->showendtime; - - $this->startdate = $att->pageparams->startdate; - $this->enddate = $att->pageparams->enddate; - - if ($this->startdate && $this->enddate) { - $where = "courseid=:cid AND attendanceid = :aid AND sessdate >= :csdate AND sessdate >= :sdate AND sessdate < :edate"; - } else { - $where = "courseid=:cid AND attendanceid = :aid AND sessdate >= :csdate"; - } - if ($att->get_current_group() > attforblock::SELECTOR_ALL) { - $where .= " AND groupid=:cgroup"; - } - $params = array( - 'cid' => $att->course->id, - 'aid' => $att->id, - 'csdate' => $att->course->startdate, - 'sdate' => $this->startdate, - 'edate' => $this->enddate, - 'cgroup' => $att->get_current_group()); - $this->sessions = $DB->get_records_select('attendance_sessions', $where, $params, 'sessdate asc'); - foreach ($this->sessions as $sess) { - $sess->description = file_rewrite_pluginfile_urls($sess->description, 'pluginfile.php', $att->context->id, 'mod_attforblock', 'session', $sess->id); - } - - $where = "courseid = :cid AND attendanceid = :aid AND sessdate < :csdate"; - $params = array( - 'cid' => $att->course->id, - 'aid' => $att->id, - 'csdate' => $att->course->startdate); - $this->hiddensessionscount = $DB->count_records_select('attendance_sessions', $where, $params); + $this->sessions = $att->get_filtered_sessions(); $this->groups = groups_get_all_groups($att->course->id); @@ -342,4 +303,72 @@ class attforblock_take_data implements renderable { } } +class attforblock_user_data implements renderable { + public $user; + + public $pageparams; + + public $stat; + + public $statuses; + + public $gradable; + + public $grade; + + public $maxgrade; + + public $decimalpoints; + + public $filtercontrols; + + public $sessionslog; + + public $courses; + + private $urlpath; + private $urlparams; + + public function __construct(attforblock $att, $userid) { + global $CFG; + + $this->user = $att->get_user($userid); + + $this->pageparams = $att->pageparams; + + $this->statuses = $att->get_statuses(); + + if (!$this->decimalpoints = grade_get_setting($att->course->id, 'decimalpoints')) { + $this->decimalpoints = $CFG->grade_decimalpoints; + } + + if ($this->pageparams->mode == att_view_page_params::MODE_THIS_COURSE) { + $this->stat = $att->get_user_stat($userid); + + $this->gradable = $att->grade > 0; + if ($this->gradable) { + $this->grade = $att->get_user_grade($userid); + $this->maxgrade = $att->get_user_max_grade($userid); + } + + + $this->filtercontrols = new attforblock_filter_controls($att); + + $this->sessionslog = $att->get_user_filtered_sessions_log($userid); + } + else { + $this->courses = $att->get_user_courses_with_attendance($userid); + } + + $this->urlpath = $att->url_view()->out_omit_querystring(); + $params = $att->pageparams->get_significant_params(); + $params['id'] = $att->cm->id; + $this->urlparams = $params; + } + + public function url() { + return new moodle_url($this->urlpath, $this->urlparams); + } +} + ?> \ No newline at end of file diff --git a/renderer.php b/renderer.php index d0bda45..457748e 100644 --- a/renderer.php +++ b/renderer.php @@ -59,15 +59,19 @@ class mod_attforblock_renderer extends plugin_renderer_base { } protected function render_sess_group_selector(attforblock_filter_controls $fcontrols) { - if ($fcontrols->get_group_mode() == NOGROUPS) - return ''; - - $select = new single_select($fcontrols->url(), 'group', $fcontrols->get_sess_groups_list(), - $fcontrols->get_current_group(), null, 'selectgroup'); - $select->label = get_string('sessions', 'attforblock'); - $output = $this->output->render($select); + switch ($fcontrols->pageparams->selectortype) { + case att_page_with_filter_controls::SELECTOR_SESS_TYPE: + $select = new single_select($fcontrols->url(), 'group', $fcontrols->get_sess_groups_list(), + $fcontrols->get_current_group(), null, 'selectgroup'); + $select->label = get_string('sessions', 'attforblock'); + $output = $this->output->render($select); + + return html_writer::tag('div', $output, array('class' => 'groupselector')); + + default: + return ''; + } - return html_writer::tag('div', $output, array('class' => 'groupselector')); } protected function render_curdate_controls(attforblock_filter_controls $fcontrols) { @@ -117,14 +121,14 @@ class mod_attforblock_renderer extends plugin_renderer_base { } protected function render_view_controls(attforblock_filter_controls $fcontrols) { - $views[att_manage_page_params::VIEW_ALL] = get_string('all', 'attforblock'); - $views[att_manage_page_params::VIEW_ALLTAKEN] = get_string('alltaken', 'attforblock'); - $views[att_manage_page_params::VIEW_MONTHS] = get_string('months', 'attforblock'); - $views[att_manage_page_params::VIEW_WEEKS] = get_string('weeks', 'attforblock'); - $views[att_manage_page_params::VIEW_DAYS] = get_string('days', 'attforblock'); + $views[VIEW_ALL] = get_string('all', 'attforblock'); + $views[VIEW_ALLTAKEN] = get_string('alltaken', 'attforblock'); + $views[VIEW_MONTHS] = get_string('months', 'attforblock'); + $views[VIEW_WEEKS] = get_string('weeks', 'attforblock'); + $views[VIEW_DAYS] = get_string('days', 'attforblock'); $viewcontrols = ''; foreach ($views as $key => $sview) { - if ($key != $fcontrols->view) { + if ($key != $fcontrols->pageparams->view) { $link = html_writer::link($fcontrols->url(array('view' => $key)), $sview); $viewcontrols .= html_writer::tag('span', $link, array('class' => 'attbtn')); } @@ -189,9 +193,7 @@ class mod_attforblock_renderer extends plugin_renderer_base { $actions = ''; $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 : '')); + $time = $this->construct_time($sess->sessdate ,$sess->duration); if($sess->lasttaken > 0) { if ($sessdata->perm->can_change()) { @@ -367,7 +369,7 @@ class mod_attforblock_renderer extends plugin_renderer_base { $row = new html_table_row(); $row->cells[] = $i; $fullname = html_writer::link($takedata->url_view(array('student' => $user->id)), fullname($user)); - $row->cells[] = $this->output->render(new user_picture($user)).$fullname; + $row->cells[] = $this->output->user_picture($user).$fullname; $celldata = $this->construct_take_user_controls($takedata, $user); if (array_key_exists('colspan', $celldata)) { @@ -403,9 +405,7 @@ class mod_attforblock_renderer extends plugin_renderer_base { $i = 0; $row = new html_table_row(); foreach($takedata->users as $user) { - $userpict = new user_picture($user); - $userpict->size = 100; - $celltext = $this->output->render($userpict); + $celltext = $this->output->user_picture($user, array('size' => 100)); $celltext .= html_writer::empty_tag('br'); $fullname = html_writer::link($takedata->url_view(array('student' => $user->id)), fullname($user)); $celltext .= html_writer::tag('span', $fullname, array('class' => 'fullname')); @@ -494,5 +494,133 @@ class mod_attforblock_renderer extends plugin_renderer_base { return $celldata; } + protected function render_attforblock_user_data(attforblock_user_data $userdata) { + $o = $this->render_user_report_tabs($userdata); + + $table = new html_table(); + + $table->attributes['class'] = 'userinfobox'; + $table->colclasses = array('left side', ''); + $table->data[0][] = $this->output->user_picture($userdata->user, array('size' => 100)); + $table->data[0][] = $this->construct_user_data($userdata); + + $o .= html_writer::table($table); + + return $o; + } + + protected function render_user_report_tabs(attforblock_user_data $userdata) { + $tabs = array(); + + $tabs[] = new tabobject(att_view_page_params::MODE_THIS_COURSE, + $userdata->url()->out(true, array('mode' => att_view_page_params::MODE_THIS_COURSE)), + get_string('thiscourse','attforblock')); + + $tabs[] = new tabobject(att_view_page_params::MODE_ALL_COURSES, + $userdata->url()->out(true, array('mode' => att_view_page_params::MODE_ALL_COURSES)), + get_string('allcourses','attforblock')); + + return print_tabs(array($tabs), $userdata->pageparams->mode, NULL, NULL, true); + } + + private function construct_user_data(attforblock_user_data $userdata) { + $o = html_writer::tag('h2', fullname($userdata->user)); + $o .= html_writer::empty_tag('hr'); + + if ($userdata->pageparams->mode == att_view_page_params::MODE_THIS_COURSE) { + $o .= $this->construct_user_data_stat($userdata); + + $o .= $this->render_attforblock_filter_controls($userdata->filtercontrols); + + $o .= $this->construct_user_sessions_log($userdata); + } + + return $o; + } + + private function construct_user_data_stat(attforblock_user_data $userdata) { + $stattable = new html_table(); + $stattable->attributes['class'] = 'list'; + $row = new html_table_row(); + $row->cells[] = get_string('sessionscompleted','attforblock').':'; + $row->cells[] = $userdata->stat['completed']; + $stattable->data[] = $row; + + foreach ($userdata->statuses as $st) { + $row = new html_table_row(); + $row->cells[] = $st->description . ':'; + $row->cells[] = array_key_exists($st->id, $userdata->stat['statuses']) ? $userdata->stat['statuses'][$st->id]->stcnt : 0; + + $stattable->data[] = $row; + } + + if ($userdata->gradable) { + $row = new html_table_row(); + $row->cells[] = get_string('attendancegrade','attforblock') . ':'; + $row->cells[] = $userdata->grade . ' / ' . $userdata->maxgrade; + $stattable->data[] = $row; + + $row = new html_table_row(); + $row->cells[] = get_string('attendancepercent','attforblock') . ':'; + if ($userdata->maxgrade == 0) { + $percent = 0; + } else { + $percent = $userdata->grade / $userdata->maxgrade * 100; + } + $row->cells[] = sprintf("%0.{$userdata->decimalpoints}f", $percent); + $stattable->data[] = $row; + } + + return html_writer::table($stattable); + } + + private function construct_user_sessions_log(attforblock_user_data $userdata) { + $table = new html_table(); + $table->attributes['class'] = 'generaltable attwidth boxaligncenter'; + $table->head = array('#', get_string('date'), get_string('time'), get_string('description','attforblock'), get_string('status','attforblock'), get_string('remarks','attforblock')); + $table->align = array('', '', 'left', 'left', 'center', 'left'); + $table->size = array('1px', '1px', '1px', '*', '1px', '1px'); + + $i = 0; + foreach ($userdata->sessionslog as $sess) { + $i++; + + $row = new html_table_row(); + $row->cells[] = $i; + $row->cells[] = userdate($sess->sessdate, get_string('strftimedmyw', 'attforblock')); + $row->cells[] = $this->construct_time($sess->sessdate, $sess->duration); + $row->cells[] = empty($sess->description) ? get_string('nodescription', 'attforblock') : $sess->description; + if (isset($sess->statusid)) { + $row->cells[] = $userdata->statuses[$sess->statusid]->description; + $row->cells[] = $sess->remarks; + } + elseif ($userdata->user->enrolmentstart && $sess->sessdate < $userdata->user->enrolmentstart) { + $cell = new html_table_cell(get_string('enrolmentstart', 'attforblock', userdate($userdata->user->enrolmentstart, '%d.%m.%Y'))); + $cell->colspan = 2; + $row->cells[] = $cell; + } + elseif ($userdata->user->enrolmentend && $sess->sessdate > $userdata->user->enrolmentend) { + $cell = new html_table_cell(get_string('enrolmentend', 'attforblock', userdate($userdata->user->enrolmentend, '%d.%m.%Y'))); + $cell->colspan = 2; + $row->cells[] = $cell; + } + else { + $row->cells[] = '?'; + $row->cells[] = ''; + } + + $table->data[] = $row; + } + + return html_writer::table($table); + } + + private function construct_time($datetime, $duration) { + $starttime = userdate($datetime, get_string('strftimehm', 'attforblock')); + $endtime = userdate($datetime + $duration, get_string('strftimehm', 'attforblock')); + $time = html_writer::tag('nobr', $starttime . ($duration > 0 ? ' - ' . $endtime : '')); + + return $time; + } } ?> diff --git a/styles.css b/styles.css index 53c684d..3f47381 100644 --- a/styles.css +++ b/styles.css @@ -102,3 +102,14 @@ display: inline; } +.path-mod-attforblock table.userinfobox { + border: 1px solid #EEEEEE; + padding: 0px; +} +.path-mod-attforblock table.userinfobox td.left { + background-color: #EEEEEE; + padding: 30px 10px; +} +.path-mod-attforblock table.list td.c0 { + text-align: right; +} \ No newline at end of file diff --git a/view.php b/view.php index c916119..50b704f 100644 --- a/view.php +++ b/view.php @@ -12,12 +12,13 @@ require_once(dirname(__FILE__).'/../../config.php'); require_once(dirname(__FILE__).'/locallib.php'); -$id = required_param('id', PARAM_INT); // Course Module ID, or -$student = optional_param('student', 0, PARAM_INT); -$printing = optional_param('printing', 0, PARAM_INT); -$mode = optional_param('mode', 'thiscourse', PARAM_ALPHA); -$view = optional_param('view', NULL, PARAM_INT); // which page to show -$current = optional_param('current', 0, PARAM_INT); +$pageparams = new att_view_page_params(); + +$id = required_param('id', PARAM_INT); +$pageparams->student = optional_param('student', NULL, PARAM_INT); +$pageparams->mode = optional_param('mode', att_view_page_params::MODE_THIS_COURSE, PARAM_INT); +$pageparams->view = optional_param('view', NULL, PARAM_INT); +$pageparams->curdate = optional_param('curdate', 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); @@ -25,25 +26,37 @@ $attforblock = $DB->get_record('attforblock', array('id' => $cm->instance), ' require_login($course, true, $cm); +$pageparams->init($course->id); +$att = new attforblock($attforblock, $cm, $course, $PAGE->context, $pageparams); + // Not specified studentid for displaying attendance? // Redirect to appropriate page if can -if (!$studentid) { - if (has_capability('mod/attforblock:manageattendances', $PAGE->context) || - has_capability('mod/attforblock:takeattendances', $PAGE->context) || - has_capability('mod/attforblock:changeattendances', $PAGE->context)) { - redirect("manage.php?id=$cm->id"); +if (!$pageparams->student) { + if ($att->perm->can_manage() || $att->perm->can_take() || $att->perm->can_change()) { + redirect($att->url_manage()); } - elseif (has_capability('mod/attforblock:viewreports', $PAGE->context)) { - redirect("report.php?id=$cm->id"); + elseif ($att->perm->can_view_reports()) { + redirect($att->url_report()); } } -if ($view) - set_current_view($course->id, $_GET['view']); -else - $view = get_current_view($course->id, 'months'); +$att->perm->require_view_capability(); + +$PAGE->set_url($att->url_view()); +$PAGE->set_title($course->shortname. ": ".$att->name); +$PAGE->set_heading($course->fullname); +$PAGE->set_cacheable(true); +$PAGE->navbar->add(get_string('attendancereport', 'attforblock')); + +$output = $PAGE->get_renderer('mod_attforblock'); + +$userid = isset($pageparams->student) ? $pageparams->student : $USER->id; +$userdata = new attforblock_user_data($att, $userid); + +echo $output->header(); -require_capability('mod/attforblock:view', $PAGE->context); +echo $output->render($userdata); +echo $output->footer(); ?>