From cab4355fec9928639e688d096d9ad5e77cb28493 Mon Sep 17 00:00:00 2001 From: Christian Klinger Date: Fri, 10 Jun 2016 17:19:50 +0200 Subject: first rough version of exams-module. --- inc/request.inc.php | 15 ++- install/content.sql | 2 + install/schema.sql | 3 + modules-available/dozmod/api.inc.php | 128 +++++++++++---------- modules-available/exams/config.json | 5 + modules-available/exams/inc/exams.inc.php | 17 +++ modules-available/exams/page.inc.php | 76 ++++++++++++ .../exams/templates/page-add-exam.html | 25 ++++ modules-available/exams/templates/page-exams.html | 32 ++++++ 9 files changed, 242 insertions(+), 61 deletions(-) create mode 100644 modules-available/exams/config.json create mode 100644 modules-available/exams/inc/exams.inc.php create mode 100644 modules-available/exams/page.inc.php create mode 100644 modules-available/exams/templates/page-add-exam.html create mode 100644 modules-available/exams/templates/page-exams.html diff --git a/inc/request.inc.php b/inc/request.inc.php index f46210af..0052fb24 100644 --- a/inc/request.inc.php +++ b/inc/request.inc.php @@ -45,5 +45,18 @@ class Request if ($type !== false) settype($_REQUEST[$key], $type); return $_REQUEST[$key]; } - + + /** + * @return true iff the request is a GET request + */ + public static function isPost() { + return $_SERVER['REQUEST_METHOD'] == 'POST'; + } + + /** + * @return true iff the request is a POST request + */ + public static function isGet() { + return $_SERVER['REQUEST_METHOD'] == 'GET'; + } } diff --git a/install/content.sql b/install/content.sql index bf54a711..ca730611 100644 --- a/install/content.sql +++ b/install/content.sql @@ -1,2 +1,4 @@ +USE openslx; + INSERT INTO property (name, dateline, value) VALUES ('webif-version', 0, 11); diff --git a/install/schema.sql b/install/schema.sql index c4ca99c5..b8ea768b 100644 --- a/install/schema.sql +++ b/install/schema.sql @@ -1,6 +1,9 @@ SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; SET time_zone = "+00:00"; +CREATE DATABASE openslx; +USE openslx; + CREATE TABLE `callback` ( `taskid` varchar(40) CHARACTER SET ascii COLLATE ascii_bin NOT NULL, `dateline` int(10) unsigned NOT NULL, diff --git a/modules-available/dozmod/api.inc.php b/modules-available/dozmod/api.inc.php index 52c8dcfb..b37c668c 100644 --- a/modules-available/dozmod/api.inc.php +++ b/modules-available/dozmod/api.inc.php @@ -11,7 +11,7 @@ if (!Module::isAvailable('locations')) { - die('require locations module'); + die('require locations module'); } @@ -23,52 +23,52 @@ $availableRessources = ['vmx', 'test', 'netrules']; function cache_hash($obj) { - return md5(serialize($obj)); + return md5(serialize($obj)); } function cache_key_to_filename($key) { - return "/tmp/bwlp-slxadmin-cache-$key"; // TODO: hash + return "/tmp/bwlp-slxadmin-cache-$key"; // TODO: hash } function cache_put($key, $value) { - $filename = cache_key_to_filename($key); - file_put_contents($filename, $value); + $filename = cache_key_to_filename($key); + file_put_contents($filename, $value); } function cache_has($key) { - $filename = cache_key_to_filename($key); - $mtime = filemtime($filename); + $filename = cache_key_to_filename($key); + $mtime = filemtime($filename); - if (!$mtime) { - return false; // cache miss - } - if (time() - $mtime > CONFIG_DOZMOD_EXPIRE) { - return false; - } else { - return true; - } + if (!$mtime) { + return false; // cache miss + } + if (time() - $mtime > CONFIG_DOZMOD_EXPIRE) { + return false; + } else { + return true; + } } function cache_get($key) { - $filename = cache_key_to_filename($key); - return file_get_contents($filename); + $filename = cache_key_to_filename($key); + return file_get_contents($filename); } /* good for large binary files */ function cache_get_passthru($key) { - $filename = cache_key_to_filename($key); - $fp = fopen($filename, "r"); - if ($fp) { - fpassthru($fp); - } else { - Util::traceError("cannot open file"); - } + $filename = cache_key_to_filename($key); + $fp = fopen($filename, "r"); + if ($fp) { + fpassthru($fp); + } else { + Util::traceError("cannot open file"); + } } /* END: Cache ---------------------------------------------------- */ @@ -88,56 +88,64 @@ function println($str) { echo "$str\n"; } * */ function _getLecturesForLocations($locationIds) { - $ids = implode('%20', $locationIds); - $url = LIST_URL . "?locations=$ids"; - $responseXML = Download::asString($url, 60, $code); - $xml = new SimpleXMLElement($responseXML); - $uuids = []; - foreach ($xml->eintrag as $e) { - $uuids[] = strval($e->uuid['param'][0]); - } - return $uuids; + /* if in any of the locations there is an exam active, consider the client + to be in "exam-mode" and only offer him exams (no lectures) */ + $examMode = false; + + if (Module::isAvailable('exams')) { + $examMode = Exams::isInExamMode($locationIds); + } + $ids = implode('%20', $locationIds); + $url = LIST_URL . "?locations=$ids" . ($examMode ? '&exams' : ''); + $responseXML = Download::asString($url, 60, $code); + $xml = new SimpleXMLElement($responseXML); + + $uuids = []; + foreach ($xml->eintrag as $e) { + $uuids[] = strval($e->uuid['param'][0]); + } + return $uuids; } /** Caching wrapper around _getLecturesForLocations() */ function getLecturesForLocations($locationIds) { - $key = 'lectures_' . cache_hash($locationIds); - if (cache_has($key)) { - return unserialize(cache_get($key)); - } else { - $value = _getLecturesForLocations($locationIds); - cache_put($key, serialize($value)); - return $value; - } + $key = 'lectures_' . cache_hash($locationIds); + if (cache_has($key)) { + return unserialize(cache_get($key)); + } else { + $value = _getLecturesForLocations($locationIds); + cache_put($key, serialize($value)); + return $value; + } } function _getVMX($lecture_uuid) { - $url = VMX_URL . '/' . $lecture_uuid; - $response = Download::asString($url, 60, $code); - return $response; + $url = VMX_URL . '/' . $lecture_uuid; + $response = Download::asString($url, 60, $code); + return $response; } /** Caching wrapper around _getVMX() **/ function getVMX($lecture_uuid) { - $key = 'vmx_' . $lecture_uuid; - if (cache_has($key)) { - cache_get_passthru($key); - } else { - $value = _getVMX($lecture_uuid); - cache_put($key, $value); - return $value; - } + $key = 'vmx_' . $lecture_uuid; + if (cache_has($key)) { + cache_get_passthru($key); + } else { + $value = _getVMX($lecture_uuid); + cache_put($key, $value); + return $value; + } } // -----------------------------------------------------------------------------// $ip = $_SERVER['REMOTE_ADDR']; if (substr($ip, 0, 7) === '::ffff:') { - $ip = substr($ip, 7); + $ip = substr($ip, 7); } /* request data, don't trust */ @@ -145,10 +153,10 @@ $resource = Request::get('resource', false, 'string'); $lecture = Request::get('lecture', false, 'string'); if ($resource === false) { - Util::traceError("you have to specify the 'resource' parameter"); + Util::traceError("you have to specify the 'resource' parameter"); } if ($lecture === false) { - Util::traceError("you have to specify the 'lecture' parameter"); + Util::traceError("you have to specify the 'lecture' parameter"); } /* lookup location id(s) */ @@ -161,18 +169,18 @@ $lectures = getLecturesForLocations($location_ids); /* validate request -------------------------------------------- */ /* check resources */ if (!in_array($resource, $availableRessources)) { - Util::traceError("unknown resource: $resource"); + Util::traceError("unknown resource: $resource"); } /* check that the user requests a lecture that he is allowed to have */ if (!in_array($lecture, $lectures)) { - Util::traceError("client is not allowed to access this lecture: $lecture"); + Util::traceError("client is not allowed to access this lecture: $lecture"); } if ($resource === 'vmx') { - echo getVMX($lecture); + echo getVMX($lecture); } else if ($resource === 'test') { - echo "Here's your special test data!"; + echo "Here's your special test data!"; } else { - echo "I don't know how to give you that resource"; + echo "I don't know how to give you that resource"; } diff --git a/modules-available/exams/config.json b/modules-available/exams/config.json new file mode 100644 index 00000000..e109b27b --- /dev/null +++ b/modules-available/exams/config.json @@ -0,0 +1,5 @@ +{ + "category":"main.status", + "dependencies": [ "locations" ], + "permission": "0" +} diff --git a/modules-available/exams/inc/exams.inc.php b/modules-available/exams/inc/exams.inc.php new file mode 100644 index 00000000..9e5833ba --- /dev/null +++ b/modules-available/exams/inc/exams.inc.php @@ -0,0 +1,17 @@ + 0) as examMode FROM exams WHERE starttime < NOW() AND endtime > NOW() AND locationid IN $l", []); + + return $res['examMode']; + } +} diff --git a/modules-available/exams/page.inc.php b/modules-available/exams/page.inc.php new file mode 100644 index 00000000..e5129d38 --- /dev/null +++ b/modules-available/exams/page.inc.php @@ -0,0 +1,76 @@ +action = $req_action; + } + + if ($this->action === 'show') { + $tmp = Database::simpleQuery("select * from exams NATURAL LEFT OUTER JOIN location;", []); + while ($exam = $tmp->fetch(PDO::FETCH_ASSOC)) { + $this->exams[] = $exam; + } + } elseif ($this->action === 'add') { + $tmp = Database::simpleQuery("select * from location;", []); + while ($loc = $tmp->fetch(PDO::FETCH_ASSOC)) { + $this->locations[] = $loc; + } + + if (Request::isPost()) { + /* process form-data */ + $locationid = Request::post('location'); + $starttime = Request::post('starttime'); + $endtime = Request::post('endtime'); + + $res = Database::exec("INSERT INTO exams(locationid, starttime, endtime) VALUES(:locationid, :starttime, :endtime);", + compact('locationid', 'starttime', 'endtime')); + + if ($res === false) { + Message::addError('exam-not-added'); + } else { + Message::addInfo('exam-added-success'); + } + Util::redirect('?do=exams'); + } + + } elseif ($this->action === 'delete') { + if (!Request::isPost()) { die('delete only works with a post request'); } + $examid = Request::post('examid'); + $res = Database::exec("DELETE FROM exams WHERE examid = :examid;", compact('examid')); + if ($res === false) { + Message::addError('exam-not-deleted-error'); + } else { + Message::addInfo('exam-deleted-success'); + } + Util::redirect('?do=exams'); + } else { + Util::traceError("unknown action"); + } + } + + protected function doRender() + { + // Render::setTitle(Dictionary::translate('lang_exams')); + //Render::addTemplate('page-exams', $_POST); + + if ($this->action === "show") { + Render::setTitle("All Exams"); + Render::addTemplate('page-exams', ['exams' => $this->exams]); + } elseif ($this->action === "add") { + Render::setTitle("Add Exam"); + Render::addTemplate('page-add-exam', ['locations' => $this->locations]); + } + // Render::output('hi'); + } + +} diff --git a/modules-available/exams/templates/page-add-exam.html b/modules-available/exams/templates/page-add-exam.html new file mode 100644 index 00000000..b610fcd8 --- /dev/null +++ b/modules-available/exams/templates/page-add-exam.html @@ -0,0 +1,25 @@ +

Add Exam

+ +
+
+ + +
+ +
+ + +
+ +
+ + +
+ + + +
diff --git a/modules-available/exams/templates/page-exams.html b/modules-available/exams/templates/page-exams.html new file mode 100644 index 00000000..6c67fa2c --- /dev/null +++ b/modules-available/exams/templates/page-exams.html @@ -0,0 +1,32 @@ + +

All Exams

+ + + + + + + + + + {{#exams}} + + + + + + + + {{/exams}} + +
IDLocationBeginEndActions
{{examid}} + {{locationname}} + {{starttime}}{{endtime}} +
+ + + +
+
+Add Exam -- cgit v1.2.3-55-g7522