summaryrefslogtreecommitdiffstats
path: root/modules-available/exams/page.inc.php
diff options
context:
space:
mode:
authorSimon Rettberg2016-07-12 16:54:36 +0200
committerSimon Rettberg2016-07-12 16:54:36 +0200
commitd072920a676743dd4ba9d4cc4af080eee9809a01 (patch)
treed5df552bd3878d8704447593cffedd24ffb8f90b /modules-available/exams/page.inc.php
parent[exams] Fix layout/type (diff)
downloadslx-admin-d072920a676743dd4ba9d4cc4af080eee9809a01.tar.gz
slx-admin-d072920a676743dd4ba9d4cc4af080eee9809a01.tar.xz
slx-admin-d072920a676743dd4ba9d4cc4af080eee9809a01.zip
[exams] Show list of upcomfing exam lectures; allow adding exam period based on upcoming exam
Diffstat (limited to 'modules-available/exams/page.inc.php')
-rw-r--r--modules-available/exams/page.inc.php173
1 files changed, 123 insertions, 50 deletions
diff --git a/modules-available/exams/page.inc.php b/modules-available/exams/page.inc.php
index d0d2255f..d6b1ccea 100644
--- a/modules-available/exams/page.inc.php
+++ b/modules-available/exams/page.inc.php
@@ -12,12 +12,14 @@ class Page_Exams extends Page
/** if examid is set, also add a column 'selected' **/
- protected function readLocations($examid = null)
+ protected function readLocations($examidOrLocations = null)
{
- if ($examid == null) {
+ if ($examidOrLocations == null) {
$active = 0;
+ } elseif (is_array($examidOrLocations)) {
+ $active = $examidOrLocations;
} else {
- $tmp = Database::simpleQuery("SELECT locationid FROM exams_x_location WHERE examid= :examid", compact('examid'));
+ $tmp = Database::simpleQuery("SELECT locationid FROM exams_x_location WHERE examid= :examid", array('examid' => $examidOrLocations));
$active = array();
while ($row = $tmp->fetch(PDO::FETCH_ASSOC)) {
$active[] = (int)$row['locationid'];
@@ -29,7 +31,7 @@ class Page_Exams extends Page
protected function readExams()
{
$tmp = Database::simpleQuery("SELECT examid, starttime, endtime, description, GROUP_CONCAT(locationid) AS locationids, "
- . "GROUP_CONCAT(locationname) AS locationnames FROM exams "
+ . "GROUP_CONCAT(locationname SEPARATOR ', ') AS locationnames FROM exams "
. "NATURAL LEFT JOIN exams_x_location NATURAL LEFT JOIN location GROUP BY examid");
while ($exam = $tmp->fetch(PDO::FETCH_ASSOC)) {
$this->exams[] = $exam;
@@ -39,20 +41,15 @@ class Page_Exams extends Page
protected function readLectures()
{
$tmp = Database::simpleQuery(
- "SELECT lectureid, locationid, displayname, starttime, endtime, isenabled " .
+ "SELECT lectureid, Group_Concat(locationid) as lids, displayname, starttime, endtime, isenabled, firstname, lastname, email " .
"FROM sat.lecture " .
+ "INNER JOIN sat.user ON (user.userid = lecture.ownerid) " .
"NATURAL LEFT JOIN sat.lecture_x_location " .
- "WHERE isexam <> 0 AND starttime < :rangeMax AND endtime > :rangeMin",
+ "WHERE isexam <> 0 AND starttime < :rangeMax AND endtime > :rangeMin " .
+ "GROUP BY lectureid",
['rangeMax' => $this->rangeMax, 'rangeMin' => $this->rangeMin]);
while ($lecture = $tmp->fetch(PDO::FETCH_ASSOC)) {
- if (is_null($lecture['locationid'])) {
- foreach ($this->locations as $location) {
- $lecture['locationid'] = $location['locationid'];
- $this->lectures[] = $lecture;
- }
- } else {
- $this->lectures[] = $lecture;
- }
+ $this->lectures[] = $lecture;
}
}
@@ -81,8 +78,8 @@ class Page_Exams extends Page
$locationids = explode(',', $e['locationids']);
if ($locationids[0] == 0) {
$locationids = [];
- foreach($this->locations as $l) {
- $locationids[] = $l['locationid'];
+ foreach($this->locations as $location) {
+ $locationids[] = $location['locationid'];
}
}
foreach ($locationids as $locationid) {
@@ -98,20 +95,28 @@ class Page_Exams extends Page
}
}
/* add the lectures */
+ $allLocationIds = array_map(function($loc) { return $loc['locationid']; }, $this->locations);
$i = 2;
- foreach ($this->lectures as $l) {
- $mark = '<span class="' . ($l['isenabled'] ? '' : 'glyphicon glyphicon-exclamation-sign') . '"></span>';
- $out[] = [
- 'id' => $l['lectureid'] . '/' . $l['locationid'],
- 'content' => htmlspecialchars($l['displayname']) . $mark,
- 'title' => $l['isenabled'] ? '' : Dictionary::translate('warning_lecture_is_not_enabled'),
- 'start' => intval($l['starttime']) * 1000,
- 'end' => intval($l['endtime']) * 1000,
- 'group' => $l['locationid'],
- 'className' => $l['isenabled'] ? '' : 'disabled',
- 'editable' => false,
- 'subgroup' => $i++,
- ];
+ foreach ($this->lectures as $lecture) {
+ $mark = '<span class="' . ($lecture['isenabled'] ? '' : 'glyphicon glyphicon-exclamation-sign') . '"></span>';
+ if (empty($lecture['lids'])) {
+ $locations = $allLocationIds;
+ } else {
+ $locations = explode(',', $lecture['lids']);
+ }
+ foreach ($locations as $location) {
+ $out[] = [
+ 'id' => $lecture['lectureid'] . '/' . $location,
+ 'content' => htmlspecialchars($lecture['displayname']) . $mark,
+ 'title' => $lecture['isenabled'] ? '' : Dictionary::translate('warning_lecture_is_not_enabled'),
+ 'start' => intval($lecture['starttime']) * 1000,
+ 'end' => intval($lecture['endtime']) * 1000,
+ 'group' => $location,
+ 'className' => $lecture['isenabled'] ? '' : 'disabled',
+ 'editable' => false,
+ 'subgroup' => $i++,
+ ];
+ }
}
return json_encode($out);
@@ -136,7 +141,7 @@ class Page_Exams extends Page
$now = time();
foreach ($this->exams as $exam) {
if ($exam['endtime'] < $now) {
- $exam['rowClass'] = 'gray';
+ $exam['rowClass'] = 'text-muted';
$exam['btnClass'] = 'btn-success';
$exam['liesInPast'] = true;
} else {
@@ -149,6 +154,42 @@ class Page_Exams extends Page
return $out;
}
+ protected function makeLectureExamList()
+ {
+ $out = [];
+ $now = time();
+ $cutoff = strtotime('+ 5 day');
+ foreach ($this->lectures as $lecture) {
+ if ($lecture['endtime'] < $now || $lecture['starttime'] > $cutoff)
+ continue;
+ $entry = $lecture;
+ if (!$lecture['isenabled']) {
+ $entry['class'] = 'text-muted';
+ }
+ $entry['starttime_s'] = date('Y-m-d H:i', $lecture['starttime']);
+ $entry['endtime_s'] = date('Y-m-d H:i', $lecture['endtime']);
+ $duration = $lecture['endtime'] - $lecture['starttime'];
+ if ($duration < 86400) {
+ $entry['duration_s'] = gmdate('H:i', $duration);
+ }
+ $out[] = $entry;
+ }
+ return $out;
+ }
+
+ protected function makeEditFromArray($source)
+ {
+ if (!isset($source['description']) && isset($source['displayname'])) {
+ $source['description'] = $source['displayname'];
+ }
+ return [
+ 'starttime_date' => date('Y-m-d', $source['starttime']),
+ 'starttime_time' => date('H:i', $source['starttime']),
+ 'endtime_date' => date('Y-m-d', $source['endtime']),
+ 'endtime_time' => date('H:i', $source['endtime'])
+ ] + $source;
+ }
+
private function isDateSane($time)
{
return ($time >= $this->rangeMin && $time <= $this->rangeMax);
@@ -249,6 +290,10 @@ class Page_Exams extends Page
$this->readLocations();
$this->readLectures();
+ } elseif ($this->action === 'add') {
+
+ $this->readLectures();
+
} elseif ($this->action === 'edit') {
$examid = Request::get('examid', 0, 'int');
@@ -258,6 +303,7 @@ class Page_Exams extends Page
Util::redirect('?do=exams');
}
$this->readLocations($examid);
+ $this->readLectures();
} elseif ($this->action === 'save') {
@@ -288,32 +334,59 @@ class Page_Exams extends Page
protected function doRender()
{
if ($this->action === "show") {
- Render::setTitle("All Exams");
- Render::addTemplate('page-exams',
- ['exams' => $this->makeExamsForTemplate(),
- 'exams_json' => $this->makeItemsForVis(),
- 'rooms_json' => $this->makeGroupsForVis(),
- 'vis_begin' => strtotime('-5 minute') * 1000,
- 'vis_end' => strtotime('+2 day') * 1000,
- 'vis_min_date' => $this->rangeMin * 1000,
- 'vis_max_date' => $this->rangeMax * 1000,
- 'axis_label' => (count($this->locations) > 5 ? 'both' : 'bottom')
+
+ // General title and description
+ Render::addTemplate('page-main-heading');
+ // List of defined exam periods
+ Render::addTemplate('page-exams', [
+ 'exams' => $this->makeExamsForTemplate()
+ ]);
+ // List of upcoming lectures marked as exam
+ $upcoming = $this->makeLectureExamList();
+ if (empty($upcoming)) {
+ Message::addInfo('no-upcoming-lecture-exams');
+ } else {
+ Render::addTemplate('page-upcoming-lectures', [
+ 'pending_lectures' => $upcoming
]);
+ }
+ // Vis.js timeline
+ Render::addTemplate('page-exams-vis', [
+ 'exams_json' => $this->makeItemsForVis(),
+ 'rooms_json' => $this->makeGroupsForVis(),
+ 'vis_begin' => strtotime('-5 minute') * 1000,
+ 'vis_end' => strtotime('+2 day') * 1000,
+ 'vis_min_date' => $this->rangeMin * 1000,
+ 'vis_max_date' => $this->rangeMax * 1000,
+ 'axis_label' => (count($this->locations) > 5 ? 'both' : 'bottom'),
+ 'utc_offset' => date('P')
+ ]);
+
} elseif ($this->action === "add") {
+
Render::setTitle(Dictionary::translate('title_add-exam'));
- $this->readLocations();
- Render::addTemplate('page-add-edit-exam', ['locations' => $this->locations]);
+ $data = [];
+ $baseLecture = Request::any('lectureid', false, 'string');
+ $locations = null;
+ if ($baseLecture !== false) {
+ foreach ($this->lectures as $lecture) {
+ if ($lecture['lectureid'] === $baseLecture) {
+ $data['exam'] = $this->makeEditFromArray($lecture);
+ $locations = explode(',', $lecture['lids']);
+ break;
+ }
+ }
+ }
+ $this->readLocations($locations);
+ $data['locations'] = $this->locations;
+ Render::addTemplate('page-add-edit-exam', $data);
+
} elseif ($this->action === 'edit') {
+
Render::setTitle(Dictionary::translate('title_edit-exam'));
- $exam = [
- 'examid' => $this->currentExam['examid'],
- 'starttime_date' => date('Y-m-d', $this->currentExam['starttime']),
- 'starttime_time' => date('H:i', $this->currentExam['starttime']),
- 'endtime_date' => date('Y-m-d', $this->currentExam['endtime']),
- 'endtime_time' => date('H:i', $this->currentExam['endtime']),
- 'description' => $this->currentExam['description']
- ];
+ $exam = $this->makeEditFromArray($this->currentExam);
Render::addTemplate('page-add-edit-exam', ['exam' => $exam, 'locations' => $this->locations]);
+
}
}