Compare commits

..

21 commits

Author SHA1 Message Date
Raphael Dannecker
c5d31f7812 jquery popover initialization fixed? 2021-01-06 20:57:16 +01:00
Raphael Dannecker
d746a4b2c2 formatting 2021-01-06 20:17:00 +01:00
Raphael Dannecker
7b8c4d6f11 jquery temporary fix 2021-01-06 20:02:38 +01:00
L_DA
31c581e4a6 Merge branch 'master' of gitlab.steinbeisschule-reutlingen.de:L_DA/mod_timetable 2021-01-02 15:50:49 +01:00
L_DA
735515e561 Zugriffsrechte 2021-01-02 15:50:35 +01:00
L_DA
0aa3854495 Variable week converted to int 2021-01-02 15:48:21 +01:00
L_DA
be422d0fef create token 2020-12-05 14:34:50 +01:00
L_DA
ae94d42fdf Webservice update data created 2020-12-05 10:03:20 +00:00
L_DA
da14cf4623 Merge branch 'master' of gitlab.steinbeisschule-reutlingen.de:L_DA/mod_timetable 2020-11-29 15:34:23 +00:00
L_DA
c94a215afc Popup hover and initialization 2020-11-29 15:31:06 +00:00
L_DA
1af66065bf Update README.md 2020-11-22 15:17:02 +01:00
L_DA
65e6a1b38a Update README.md 2020-11-22 15:13:15 +01:00
L_DA
466652fce0 Update README.md 2020-11-22 15:12:57 +01:00
L_DA
1bdc354bdd Update README.md 2020-11-22 15:12:25 +01:00
L_DA
c3a4f0e41a Update README.md 2020-11-22 15:11:40 +01:00
L_DA
c6947eb195 Upload New File 2020-11-22 15:10:58 +01:00
L_DA
05ca03b729 Upload New File 2020-11-22 15:10:45 +01:00
L_DA
38d7edeef3 Upload New File 2020-11-22 14:54:52 +01:00
L_DA
af988c401d Upload New File 2020-11-22 14:54:25 +01:00
L_DA
5b430bdca0 Add new directory 2020-11-22 14:52:41 +01:00
L_DA
c36507efa0 Documentation 2020-11-22 14:51:27 +01:00
16 changed files with 1063 additions and 631 deletions

View file

@ -1,8 +1,66 @@
# timetable # # mod_timetable #
mod_timetable is a moodle plugin that provides timetables based on Untis export data.
The provides timetable views are:
- teacher
- student
- room
You can search for the timetables:
![timetable text](doc/timetable_search_small.png)
Multiple results can be displayed at same time
![seachresults text](doc/timetable_searchresults_small.png)
Substitutions and events are displayed too.
On clicking on lessons you will get detailed information about it.
Required Untis-exportfiles:
- class.txt
- lesson.txt
- teacher.txt
- time.txt
- room.txt
- GPU012.TXT
- GPU013.TXT
- GPU014.TXT
If file content is changing, the moodle-database will be automatically updated.
You can also specify whether there are no classes on saturday.
The minimum number of teaching hours displayed is also configurable.
## Update data via WebService ##
- create user
- Website-Administration - Users - Rechte ändern - Rollen verwalten
- Add new role
- Basisrolle: keine
- Kurzbezeichnung: webservice-timetable
- Kontexttype: User
- add: update timetable data
webservice rest:use
webservice reatetoken
- Website-Administration - Users - timetable-user from step 1 - Einstellungen - rollen - Rollen relativ zu diesem Nutzerkonto zuweisen
- Website-Administration - Plugins - Webservice - Externe Webservices - Hinzufügen
- Name: timetableupdate
- Shortname: timetableupdate
x Aktiviert
x nur berechtigte Personen
- Erweitert:
Notwendige Rechte: keine
Funktion hinzufügen: mod/timetable:update: update timetable data
- Berechtigte Personen: add user from step 1
- Website-Administration - Plugins - Webservices - Token verwalten
- username: user from step 1
- service: timetableupdate
TODO Describe the plugin shortly here.
TODO Provide more detailed description here.
## License ## ## License ##

340
classes/import.php Executable file
View file

@ -0,0 +1,340 @@
<?php
namespace mod_timetable;
/**
* An example of a scheduled task.
*/
class import_data {
public function __construct() {
}
/**
* Return the task's name as shown in admin screens.
*
* @return string
*/
public function get_name() {
return get_string('import_data', 'mod_timetable');
}
private function update_lesson($content) {
global $DB,$CFG;
$filehash = get_config('timetable', 'filehash_lesson');
$hash = md5($content);
if ($hash == $filehash) return('Data not changed');
$result ="";
try {
$transaction = $DB->start_delegated_transaction();
$result .= "before delete\n";
$DB->delete_records_select("timetable_lesson", "id>0");
$result .= "after delete\n";
foreach (preg_split('/$\R?^/m',$content) as $buffer) {
//echo $buffer;
$result .= "+";
$buffer = utf8_encode(rtrim($buffer));
$data = explode("\t", $buffer);
if (count($data) != 10) throw new \Exception('Wrong size of elements ');
$dataobject = (object)array('teacher' => $data[0],
'day' => $data[1],
'period' => $data[2],
'subject' => $data[3],
'room' => $data[4],
'lessonid'=> $data[5],
'flag' => $data[6],
'class' => $data[7],
'week' => $data[8],
'unknown' => $data[9]);
$DB->insert_record("timetable_lesson", $dataobject);
}
$transaction->allow_commit();
set_config('filehash_lesson', $hash, 'timetable');
} catch(Exception $e) {
$transaction->rollback($e);
}
return ($result);
}
private function update_substitution($content) {
global $DB,$CFG;
$filehash = get_config('timetable', 'filehash_substitution');
$hash = md5($content);
if ($hash == $filehash) return('Data not changed');
$result ="";
try {
$transaction = $DB->start_delegated_transaction();
$result .= "before delete\n";
$DB->delete_records_select("timetable_substitution", "id>0");
$result .= "after delete\n";
foreach (preg_split('/$\R?^/m',$content) as $buffer) {
$data = str_getcsv($buffer, ',');
$dataobject = (object)array(
'id' => $data[0],
'date' => $data[1],
'period' => $data[2],
'absence' => $data[3],
'lesson' => $data[4],
'teachera' => $data[5],
'teacherb' => $data[6],
'subjecta' => utf8_encode($data[7]),
'statistica' => $data[8],
'subjectb' => utf8_encode($data[9]),
'statisticb' => $data[10],
'rooma' => $data[11],
'roomb' => $data[12],
'statisticflag' => $data[13],
'classa' => utf8_encode($data[14]),
'reason' => utf8_encode($data[15]),
'text' => utf8_encode($data[16]),
'type' => $data[17],
'classb' => utf8_encode($data[18]),
'substitutiontype' => $data[19],
'changetime' => $data[20],
'unknown' => $data[21]);
//echo var_dump($dataobject);
foreach (get_object_vars($dataobject) as $key => $value) {
if ($value=='') unset($dataobject->{$key});
}
$DB->insert_record_raw("timetable_substitution", $dataobject,false, false, true);
}
$transaction->allow_commit();
set_config('filehash_substitution', $hash, 'timetable');
} catch(Exception $e) {
$transaction->rollback($e);
}
return $result;
}
private function update_teacher($content) {
global $DB,$CFG;
$filehash = get_config('timetable', 'filehash_teacher');
$hash = md5($content);
if ($hash == $filehash) return('Data not changed');
$result = "";
try {
$transaction = $DB->start_delegated_transaction();
$result .= "before delete\n";
$DB->delete_records_select("timetable_teacher", "id>0");
$result .= "after delete\n";
foreach (preg_split('/$\R?^/m',$content) as $buffer) {
$buffer = utf8_encode(rtrim($buffer));
$data = explode("\t", $buffer);
if (!(array_key_exists(3,$data))) {
$data[3] = '';
} else {
$result .= "firstname exists: $data[3]\n";
}
//if (count($data) < 3) throw new Exception('Wrong size of elements');
$dataobject = (object)array('teacher' => $data[0],
'surname' => $data[1],
'firstname' => $data[3]);
$DB->insert_record("timetable_teacher", $dataobject);
}
$transaction->allow_commit();
set_config('filehash_teacher', $hash, 'timetable');
} catch(Exception $e) {
$transaction->rollback($e);
}
return $result;
}
private function update_room($content) {
global $DB,$CFG;
$filehash = get_config('timetable', 'filehash_room');
$hash = md5($content);
if ($hash == $filehash) return('Data not changed');
$result = "";
try {
$transaction = $DB->start_delegated_transaction();
$result .= "before delete\n";
$DB->delete_records_select("timetable_room", "id>0");
$result .= "after delete\n";
foreach (preg_split('/$\R?^/m',$content) as $buffer) {
$buffer = utf8_encode(rtrim($buffer));
$data = explode("\t", $buffer);
if (count($data) < 2) throw new \Exception('Wrong size of elements');
$dataobject = (object)array('room' => $data[0],
'description' => $data[1]);
$DB->insert_record("timetable_room", $dataobject);
}
$transaction->allow_commit();
set_config('filehash_room', $hash, 'timetable');
} catch(Exception $e) {
$transaction->rollback($e);
}
return $result;
}
private function update_class($content) {
global $DB,$CFG;
$filehash = get_config('timetable', 'filehash_class');
$hash = md5($content);
if ($hash == $filehash) return('Data not changed');
$result = "";
try {
$transaction = $DB->start_delegated_transaction();
$result .= "before delete\n";
$DB->delete_records_select("timetable_class", "id>0");
$result .= "after delete\n";
foreach (preg_split('/$\R?^/m',$content) as $buffer) {
$buffer = utf8_encode(rtrim($buffer));
$data = explode("\t", $buffer);
if (!(array_key_exists(1,$data))) $data[1] = $data[0];
if (count($data) < 2) throw new \Exception('Wrong size of elements');
$dataobject = (object)array('class' => $data[0],
'description' => $data[1]);
$DB->insert_record("timetable_class", $dataobject);
}
$transaction->allow_commit();
set_config('filehash_class', $hash, 'timetable');
} catch(Exception $e) {
$transaction->rollback($e);
}
return $result;
}
private function update_absence($content) {
global $DB,$CFG;
$filehash = get_config('timetable', 'filehash_abs');
$hash = md5($content);
if ($hash == $filehash) return('Data not changed');
$result = "";
try {
$transaction = $DB->start_delegated_transaction();
$result .= "before delete\n";
$DB->delete_records_select("timetable_absence", "id>0");
$result .= "after delete\n";
foreach (preg_split('/$\R?^/m',$content) as $buffer) {
$data = str_getcsv($buffer, ',');
$dataobject = (object)array('id' => $data[0],
'type' => $data[1],
'name' => utf8_encode($data[2]),
'startdate' => $data[3],
'enddate' => $data[4],
'startperiod' => $data[5],
'endperiod' => $data[6],
'reason' => utf8_encode($data[7]),
'text' => utf8_encode($data[8]));
foreach (get_object_vars($dataobject) as $key => $value) {
if ($value=='') unset($dataobject->{$key});
}
$DB->insert_record("timetable_absence", $dataobject);
}
$transaction->allow_commit();
set_config('filehash_abs', $hash, 'timetable');
} catch(Exception $e) {
$transaction->rollback($e);
}
return $result;
}
private function update_absence_reason($content) {
global $DB,$CFG;
$filehash = get_config('timetable', 'filehash_absreas');
$hash = md5($content);
if ($hash == $filehash) return('Data not changed');
$result = "";
try {
$transaction = $DB->start_delegated_transaction();
$result .= "before delete\n";
$DB->delete_records_select("timetable_absence_reason", "id>0");
$result .= "after delete\n";
foreach (preg_split('/$\R?^/m',$content) as $buffer) {
$data = str_getcsv($buffer, ',');
$dataobject = (object)array('reason' => utf8_encode($data[0]),
'description' => utf8_encode($data[1]),
'flag' => $data[2],
'statistic' => $data[3]);
foreach (get_object_vars($dataobject) as $key => $value) {
if ($value=='') unset($dataobject->{$key});
}
$DB->insert_record("timetable_absence_reason", $dataobject);
}
$transaction->allow_commit();
set_config('filehash_absreas', $hash, 'timetable');
} catch(Exception $e) {
$transaction->rollback($e);
}
return $result;
}
private function update_time($content) {
global $DB,$CFG;
$filehash = get_config('timetable', 'filehash_times');
$hash = md5($content);
if ($hash == $filehash) return('Data not changed');
$result = "";
try {
$transaction = $DB->start_delegated_transaction();
$result .= "before delete\n";
$DB->delete_records_select("timetable_time", "id>0");
$result .= "after delete\n";
foreach (preg_split('/$\R?^/m',$content) as $buffer) {
$buffer = utf8_encode(rtrim($buffer));
$data = explode("\t", $buffer);
$dataobject = (object)array('day' => $data[0],
'period' => $data[1],
'maxperiod' => $data[2],
'starttime' => $data[3],
'endtime' => $data[4]);
$DB->insert_record("timetable_time", $dataobject);
}
$transaction->allow_commit();
set_config('filehash_times', $hash, 'timetable');
} catch(Exception $e) {
$transaction->rollback($e);
}
return $result;
}
/**
* Execute the task.
*/
public function update($files) {
global $DB,$CFG;
$results = array();
foreach ($files as $file) {
$content = base64_decode($file['content']);
$result = array();
$result['name'] = $file['name'];
switch ($file['name']) {
case 'lesson':
$result['result'] = $this->update_lesson($content);
break;
case 'substitution':
$result['result'] = $this->update_substitution($content);
break;
case 'teacher':
$result['result'] = $this->update_teacher($content);
break;
case 'class':
$result['result'] = $this->update_class($content);
break;
case 'room':
$result['result'] = $this->update_room($content);
break;
case 'time':
$result['result'] = $this->update_time($content);
break;
case 'absence':
$result['result'] = $this->update_absence($content);
break;
case 'absence_reason':
$result['result'] = $this->update_absence_reason($content);
break;
default:
$result['result'] = "no handler";
}
$results[] = $result;
}
return $results;
}
}

View file

@ -37,6 +37,7 @@ class lesson {
$this->room = $lesson->room; $this->room = $lesson->room;
$this->period = $lesson->period; $this->period = $lesson->period;
$this->day = $lesson->day; $this->day = $lesson->day;
$this->type = $lesson->type;
$this->text = ""; $this->text = "";
$this->substitution = ""; $this->substitution = "";
$this->teachera = ""; $this->teachera = "";
@ -52,7 +53,7 @@ class lesson {
$this->classchanged = false; $this->classchanged = false;
$this->roomchanged = false; $this->roomchanged = false;
$this->reason = ""; $this->reason = "";
$this->type = 0; $this->subtype = 0;
} }
/** /**
@ -70,12 +71,12 @@ class lesson {
$this->subjecta = $substitution->subjecta; $this->subjecta = $substitution->subjecta;
$this->classa = $substitution->classa; $this->classa = $substitution->classa;
$this->rooma = $substitution->rooma; $this->rooma = $substitution->rooma;
$this->teacherchanged = ($this->teacher != $this->teachera) ? true : false; $this->teacherchanged = ($this->teacher != $this->teachera && $this->teachera) ? true : false;
$this->subjectchanged = ($this->subject != $this->subjecta) ? true : false; $this->subjectchanged = ($this->subject != $this->subjecta && $this->subjecta) ? true : false;
$this->classchanged = (!preg_match("/(^|~)".preg_quote($this->class,"/")."($|~)/" , $this->classa )) ? true : false; $this->classchanged = (!preg_match("/(^|~)".preg_quote($this->class,"/")."($|~)/" , $this->classa ) && $this->classa) ? true : false;
$this->roomchanged = (!preg_match("/(^|~)".preg_quote($this->room,"/")."($|~)/" , $this->rooma )) ? true : false; $this->roomchanged = (!preg_match("/(^|~)".preg_quote($this->room,"/")."($|~)/" , $this->rooma ) && $this->rooma) ? true : false;
if ($substitution->text) $this->text .= $substitution->text; if ($substitution->text) $this->text .= $substitution->text;
$this->type = $substitution->type; $this->subtype = $substitution->type;
$this->substitution = "1"; $this->substitution = "1";
return 1; return 1;
} elseif (//$this->lessonid == $substitution->lesson && } elseif (//$this->lessonid == $substitution->lesson &&
@ -94,7 +95,7 @@ class lesson {
$this->roomchanged = (!preg_match("/(^|~)".preg_quote($this->room,"/")."($|~)/" , $this->roomb )) ? true : false; $this->roomchanged = (!preg_match("/(^|~)".preg_quote($this->room,"/")."($|~)/" , $this->roomb )) ? true : false;
if ($substitution->text) $this->text .= $substitution->text; if ($substitution->text) $this->text .= $substitution->text;
// TODO Entfall, falls teacherb!=teacher bzw. class not in classb bzw. roomb!=room TODO // TODO Entfall, falls teacherb!=teacher bzw. class not in classb bzw. roomb!=room TODO
$this->type = $substitution->type; $this->subtype = $substitution->type;
$this->substitution = "1"; $this->substitution = "1";
return 1; return 1;
} else { } else {
@ -128,6 +129,9 @@ class lesson {
//$this->teacher == $lesson->teacher && //$this->teacher == $lesson->teacher &&
$this->subject == $lesson->subject && $this->subject == $lesson->subject &&
$this->room == $lesson->room && $this->room == $lesson->room &&
$this->type == $lesson->type &&
$this->subtype == $lesson->subtype &&
//$this->teacherchanged == $lesson->teacherchanged &&
$this->text == $lesson->text) { $this->text == $lesson->text) {
if ($this->class != $lesson->class) { if ($this->class != $lesson->class) {
$class1parts = explode("/", $this->class); $class1parts = explode("/", $this->class);

View file

@ -29,7 +29,8 @@ function lesson_in_lessons($obj, $array) {
$obj->teacher == $array[$n]->teacher && $obj->teacher == $array[$n]->teacher &&
$obj->subject == $array[$n]->subject && $obj->subject == $array[$n]->subject &&
$obj->class == $array[$n]->class && $obj->class == $array[$n]->class &&
$obj->room == $array[$n]->room) return true; $obj->room == $array[$n]->room &&
$obj->type == $array[$n]->type) return true;
} }
return false; return false;
} }
@ -113,27 +114,30 @@ class timetable {
$this->monday->sub(new \DateInterval("P".($dayofweek-1)."D")); $this->monday->sub(new \DateInterval("P".($dayofweek-1)."D"));
} }
$this->week = $this->monday->format("W"); $this->week = intval($this->monday->format("W"));
$this->lastday = new \DateTime($this->monday->format('Y-m-d\TH:i:sP')); $this->lastday = new \DateTime($this->monday->format('Y-m-d\TH:i:sP'));
$this->lastday->add(new \DateInterval("P".($this->numdayweek-1)."D")); $this->lastday->add(new \DateInterval("P".($this->numdayweek-1)."D"));
$sql = "$this->type = '$this->name' AND NOT lessonid=0 AND (mid(week, $this->week, 1) = '1')"; $sql = "$this->type = '$this->name' AND NOT lessonid=0 AND (mid(week, $this->week, 1) = '1')";
$result = $DB->get_records_select('timetable_lesson',$sql); $result = $DB->get_records_select('timetable_lesson',$sql);
foreach ($result as $lesson) { foreach ($result as $lesson) {
$lesson->type = "normal";
if (!lesson_in_lessons($lesson, $this->lessons[$lesson->day][$lesson->period])) if (!lesson_in_lessons($lesson, $this->lessons[$lesson->day][$lesson->period]))
$this->lessons[$lesson->day][$lesson->period][] = new lesson($lesson); $this->lessons[$lesson->day][$lesson->period][] = new lesson($lesson);
} }
$sql = "$this->type = '$this->name' AND lessonid=0 AND (mid(week, $this->week, 1) = '1')"; $sql = "$this->type = '$this->name' AND lessonid=0 AND (mid(week, $this->week, 1) = '1')";
$result = $DB->get_records_select('timetable_lesson',$sql); $result = $DB->get_records_select('timetable_lesson',$sql);
foreach ($result as $lesson) { foreach ($result as $lesson) {
if (!lesson_in_lessons($lesson, $this->lessons_event[$lesson->day][$lesson->period])) $lesson->type = "event";
$this->lessons_event[$lesson->day][$lesson->period][] = new lesson($lesson); if (!lesson_in_lessons($lesson, $this->lessons[$lesson->day][$lesson->period]))
$this->lessons[$lesson->day][$lesson->period][] = new lesson($lesson);
} }
$sql = "$this->type = '$this->name' and (mid(week, $this->week, 1) = 'x')"; $sql = "$this->type = '$this->name' and (mid(week, $this->week, 1) = 'x')";
$result = $DB->get_records_select('timetable_lesson',$sql); $result = $DB->get_records_select('timetable_lesson',$sql);
foreach ($result as $lesson) { foreach ($result as $lesson) {
if (!lesson_in_lessons($lesson, $this->lessons_canceled[$lesson->day][$lesson->period])) $lesson->type = "canceled";
$this->lessons_canceled[$lesson->day][$lesson->period][] = new lesson($lesson); if (!lesson_in_lessons($lesson, $this->lessons[$lesson->day][$lesson->period]))
$this->lessons[$lesson->day][$lesson->period][] = new lesson($lesson);
} }
$day = new \DateTime($this->monday->format('Y-m-d\TH:i:sP')); $day = new \DateTime($this->monday->format('Y-m-d\TH:i:sP'));
@ -144,12 +148,6 @@ class timetable {
foreach ($this->lessons[$i+1][$substitution->period] as $lesson) { foreach ($this->lessons[$i+1][$substitution->period] as $lesson) {
$lesson->process_substitution($substitution); $lesson->process_substitution($substitution);
} }
foreach ($this->lessons_canceled[$i+1][$substitution->period] as $lesson) {
$lesson->process_substitution($substitution);
}
foreach ($this->lessons_event[$i+1][$substitution->period] as $lesson) {
$lesson->process_substitution($substitution);
}
} }
$types = array('teacher'=>'L', 'class'=>'K', 'room'=>'R'); $types = array('teacher'=>'L', 'class'=>'K', 'room'=>'R');
@ -157,8 +155,8 @@ class timetable {
$result = $DB->get_records_select('timetable_absence',$sql); $result = $DB->get_records_select('timetable_absence',$sql);
foreach ($result as $absence) { foreach ($result as $absence) {
for ($j=$absence->startperiod; $j<=$absence->endperiod; $j++) { for ($j=$absence->startperiod; $j<=$absence->endperiod; $j++) {
foreach ($this->lessons_event[$i+1][$j] as $lesson) { foreach ($this->lessons[$i+1][$j] as $lesson) {
$lesson->process_absence($absence); if ($lesson->type == 'event') $lesson->process_absence($absence);
} }
} }
} }
@ -168,7 +166,7 @@ class timetable {
for ($i=0; $i<$this->numdayweek; $i++) { for ($i=0; $i<$this->numdayweek; $i++) {
foreach($this->lessons[$i+1] as &$lessons) $lessons = collapse_lessons($lessons); foreach($this->lessons[$i+1] as &$lessons) $lessons = collapse_lessons($lessons);
foreach($this->lessons_canceled[$i+1] as &$lessons) $lessons = collapse_lessons($lessons); // not to be done for events???
} }
if ($this->type == 'teacher') { if ($this->type == 'teacher') {
@ -191,10 +189,6 @@ class timetable {
for ($i=0; $i<$this->numdayweek; $i++) { for ($i=0; $i<$this->numdayweek; $i++) {
foreach($this->lessons[$i+1] as $period => $lessons) foreach($this->lessons[$i+1] as $period => $lessons)
if ($period > $maxperiod && count($lessons)) $maxperiod = $period; if ($period > $maxperiod && count($lessons)) $maxperiod = $period;
foreach($this->lessons_canceled[$i+1] as $period => $lessons)
if ($period > $maxperiod && count($lessons)) $maxperiod = $period;
foreach($this->lessons_event[$i+1] as $period => $lessons)
if ($period > $maxperiod && count($lessons)) $maxperiod = $period;
} }
return $maxperiod; return $maxperiod;
} }
@ -226,40 +220,6 @@ class timetable {
$days[$day] = array(); $days[$day] = array();
$days[$day]['substitutionold'] = ""; $days[$day]['substitutionold'] = "";
$days[$day]['lessons'] = array(); $days[$day]['lessons'] = array();
foreach ($this->lessons_event[$day+1][$period+1] as $lesson) {
$mylesson = array();
$mylesson['class'] = $lesson->class;
$mylesson['teacher'] = $lesson->teacher;
$mylesson['room'] = $lesson->room;
$mylesson['subject'] = $lesson->subject;
$mylesson['classa'] = $lesson->classa;
$mylesson['teachera'] = $lesson->teachera;
$mylesson['rooma'] = $lesson->rooma;
$mylesson['subjecta'] = $lesson->subjecta;
$mylesson['classb'] = property_exists($lesson,'classb') ? $lesson->classb : null;
$mylesson['teacherb'] = property_exists($lesson,'teacherb') ? $lesson->teacherb : null;
$mylesson['roomb'] = property_exists($lesson,'roomb') ? $lesson->roomb : null;
$mylesson['subjectb'] = property_exists($lesson,'subjectb') ? $lesson->subjectb : null;
$mylesson['subjectchanged'] = $lesson->subjectchanged;
$mylesson['teacherchanged'] = $lesson->teacherchanged;
$mylesson['classchanged'] = $lesson->classchanged;
$mylesson['roomchanged'] = $lesson->roomchanged;
$mylesson['substitution'] = $lesson->substitution;
$mylesson['cancel'] = "";
$mylesson['cancel4me'] = "";
$mylesson['event'] = $lesson->reason ? $lesson->reason : "Event";
$mylesson['status'] = "1";
$mylesson['flag'] = "1";
$mylesson['text'] = $lesson->text;
$mylesson['subtype'] = Array();
if ($lesson->type) {
for ($i=0; $i<32; $i++) {
if ($lesson->type & (1<<$i)) $mylesson['subtype'][] = $i+1;
}
}
$days[$day]['substitutionold'] .= $lesson->text;
$days[$day]['lessons'][] = $mylesson;
}
foreach ($this->lessons[$day+1][$period+1] as $lesson) { foreach ($this->lessons[$day+1][$period+1] as $lesson) {
$mylesson = array(); $mylesson = array();
$mylesson['class'] = $lesson->class; $mylesson['class'] = $lesson->class;
@ -286,52 +246,25 @@ class timetable {
$mylesson['flag'] = ""; $mylesson['flag'] = "";
$mylesson['text'] = $lesson->text; $mylesson['text'] = $lesson->text;
$mylesson['subtype'] = Array(); $mylesson['subtype'] = Array();
if ($lesson->type) { if ($lesson->subtype) {
for ($i=0; $i<32; $i++) { for ($i=0; $i<32; $i++) {
if ($lesson->type & (1<<$i)) $mylesson['subtype'][] = $i+1; if ($lesson->subtype & (1<<$i)) $mylesson['subtype'][] = $i+1;
} }
} }
$days[$day]['substitutionold'] .= $lesson->text; $days[$day]['substitutionold'] .= $lesson->text;
$days[$day]['lessons'][] = $mylesson; if ($lesson->type == 'event') {
} $mylesson['event'] = $lesson->reason ? $lesson->reason : "Event";
foreach ($this->lessons_canceled[$day+1][$period+1] as $lesson) { $mylesson['status'] = "1";
$mylesson = array(); $mylesson['flag'] = "1";
$mylesson['class'] = $lesson->class; } elseif ($lesson->type == 'canceled') {
$mylesson['teacher'] = $lesson->teacher;
$mylesson['room'] = $lesson->room;
$mylesson['subject'] = $lesson->subject;
$mylesson['classa'] = $lesson->classa;
$mylesson['teachera'] = $lesson->teachera;
$mylesson['rooma'] = $lesson->rooma;
$mylesson['subjecta'] = $lesson->subjecta;
$mylesson['classb'] = property_exists($lesson,'classb') ? $lesson->classb : null;
$mylesson['teacherb'] = property_exists($lesson,'teacherb') ? $lesson->teacherb : null;
$mylesson['roomb'] = property_exists($lesson,'roomb') ? $lesson->roomb : null;
$mylesson['subjectb'] = property_exists($lesson,'subjectb') ? $lesson->subjectb : null;
$mylesson['substitution'] = $lesson->substitution;
$mylesson['cancel'] = "1"; $mylesson['cancel'] = "1";
$mylesson['cancel4me'] = ""; $mylesson['cancel4me'] = "";
if (($lesson->teacherchanged && $this->type == 'teacher') || if (($lesson->teacherchanged && $this->type == 'teacher') ||
($lesson->classchanged && $this->type == 'class') || ($lesson->classchanged && $this->type == 'class') ||
($lesson->roomchanged && $this->type == 'room')) $mylesson['cancel4me'] = "cancel4me"; ($lesson->roomchanged && $this->type == 'room')) $mylesson['cancel4me'] = "cancel4me";
$mylesson['subjectchanged'] = $lesson->subjectchanged;
$mylesson['teacherchanged'] = $lesson->teacherchanged;
$mylesson['classchanged'] = $lesson->classchanged;
$mylesson['roomchanged'] = $lesson->roomchanged;
#if ((property_exists($lesson,'teacherb') && $this->type == 'teacher') ||
# (property_exists($lesson,'classb') && $this->type == 'class') ||
# (property_exists($lesson,'roomb') && $this->type == 'room')) $mylesson['cancel4me'] = "cancel4me";
$mylesson['event'] = "";
$mylesson['status'] = "1"; $mylesson['status'] = "1";
$mylesson['flag'] = "1"; // status und flag werden vertauscht (im Template bzw. extern-lib.php $mylesson['flag'] = "1"; // status und flag werden vertauscht (im Template bzw. extern-lib.php
$mylesson['text'] = $lesson->text;
$mylesson['subtype'] = Array();
if ($lesson->type) {
for ($i=0; $i<32; $i++) {
if ($lesson->type & (1<<$i)) $mylesson['subtype'][] = $i+1;
} }
}
$days[$day]['substitutionold'] .= $lesson->text;
$days[$day]['lessons'][] = $mylesson; $days[$day]['lessons'][] = $mylesson;
} }
} }

View file

@ -28,6 +28,16 @@ defined('MOODLE_INTERNAL') || die();
$capabilities = array( $capabilities = array(
'mod/timetable:update' => array(
'riskbitmask' => RISK_XSS,
'captype' => 'write',
'contextlevel' => CONTEXT_USER,
'archetypes' => array(
'manager' => CAP_ALLOW
),
),
'mod/timetable:addinstance' => array( 'mod/timetable:addinstance' => array(
'riskbitmask' => RISK_XSS, 'riskbitmask' => RISK_XSS,

View file

@ -40,6 +40,15 @@ $functions = array(
'type' => 'read', 'type' => 'read',
'ajax' => true, 'ajax' => true,
'capabilities' => array(), // capabilities required by the function. 'capabilities' => array(), // capabilities required by the function.
),
'mod_timetable_update' => array(
'classname' => 'mod_timetable_external',
'methodname' => 'update',
'classpath' => 'mod/timetable/externallib.php',
'description' => 'update timetable data',
'type' => 'write',
'ajax' => false,
'capabilities' => array(), // capabilities required by the function.
) )
); );

0
doc/.gitkeep Executable file
View file

BIN
doc/timetable_search.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

BIN
doc/timetable_search_small.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

BIN
doc/timetable_searchresults.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

View file

@ -21,6 +21,7 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/ */
require_once($CFG->libdir . "/externallib.php"); require_once($CFG->libdir . "/externallib.php");
require_once("classes/import.php");
class mod_timetable_external extends external_api { class mod_timetable_external extends external_api {
@ -48,7 +49,8 @@ class mod_timetable_external extends external_api {
//Context validation //Context validation
//OPTIONAL but in most web service it should present //OPTIONAL but in most web service it should present
$context = get_context_instance(CONTEXT_USER, $USER->id); //$context = get_context_instance(CONTEXT_USER, $USER->id);
$context = context_user::instance($USER->id);
self::validate_context($context); self::validate_context($context);
//Capability checking //Capability checking
@ -59,7 +61,6 @@ class mod_timetable_external extends external_api {
$results = array(); $results = array();
//return $params['searchstring'] . $USER->firstname ;
$classes = $DB->get_records_select('timetable_class', 'class like ? OR description like ? LIMIT 10', array ('%'.$params['searchstring'].'%', '%'.$params['searchstring'].'%')); $classes = $DB->get_records_select('timetable_class', 'class like ? OR description like ? LIMIT 10', array ('%'.$params['searchstring'].'%', '%'.$params['searchstring'].'%'));
foreach($classes as $class) { foreach($classes as $class) {
$result = array( $result = array(
@ -87,7 +88,6 @@ class mod_timetable_external extends external_api {
); );
$results[] = $result; $results[] = $result;
} }
//echo var_dump($results);
return $results; return $results;
} }
@ -110,6 +110,70 @@ class mod_timetable_external extends external_api {
/**
* Returns description of method parameters
* @return external_function_parameters
*/
public static function update_parameters() {
return new external_function_parameters(
array(
'files' => new external_multiple_structure(
new external_single_structure(
array(
'name' => new external_value(PARAM_TEXT, 'name of file'),
'content' => new external_value(PARAM_RAW, 'content of file')
)
)
)
)
);
}
/**
* Returns description of method result value
* @return external_description
*/
public static function update_returns() {
return new external_multiple_structure(
new external_single_structure(
array(
'name' => new external_value(PARAM_TEXT, 'name of file'),
'result' => new external_value(PARAM_RAW, 'result message')
)
)
);
}
/**
* Returns description of method result value
* @return external_description
*/
public static function update($files) {
global $USER;
//Context validation
//OPTIONAL but in most web service it should present
$context = context_user::instance($USER->id);
self::validate_context($context);
//$contextmodule = context_module::instance($cm->id);
$usercontext = context_user::instance($USER->id);
//Capability checking
//OPTIONAL but in most web service it should present
if (!has_capability('mod/timetable:update', $usercontext)) {
throw new \moodle_exception('cannotupdatetimetable');
}
$import_data = new \mod_timetable\import_data();
return $import_data->update($files);
}
/** /**
* Returns description of method parameters * Returns description of method parameters
* @return external_function_parameters * @return external_function_parameters
@ -133,14 +197,13 @@ class mod_timetable_external extends external_api {
//Parameter validation //Parameter validation
//REQUIRED //REQUIRED
//echo "Hallo\n";
$params = self::validate_parameters(self::get_parameters(), $params = self::validate_parameters(self::get_parameters(),
array('type' => $type, 'name'=> $name, 'week' => $week)); array('type' => $type, 'name'=> $name, 'week' => $week));
//Context validation //Context validation
//OPTIONAL but in most web service it should present //OPTIONAL but in most web service it should present
$context = get_context_instance(CONTEXT_USER, $USER->id); //$context = get_context_instance(CONTEXT_USER, $USER->id);
$context = context_user::instance($USER->id);
self::validate_context($context); self::validate_context($context);
//$contextmodule = context_module::instance($cm->id); //$contextmodule = context_module::instance($cm->id);

View file

@ -28,6 +28,13 @@ defined('MOODLE_INTERNAL') || die();
$string['pluginname'] = 'Timetable'; $string['pluginname'] = 'Timetable';
$string['modulename'] = 'Timetable'; $string['modulename'] = 'Timetable';
$string['modulenameplural'] = 'Timetables'; $string['modulenameplural'] = 'Timetables';
$string['timetable:addinstance'] = 'add timetable';
$string['timetable:search'] = 'perform timetable search';
$string['timetable:viewclass'] = 'view class timetable';
$string['timetable:viewownclass'] = 'view own class timetable';
$string['timetable:viewroom'] = 'view room timetable';
$string['timetable:viewteacher'] = 'view teacher timetable';
$string['timetable:update'] = 'update timetable data';
$string['timetablename'] = 'Timetable'; $string['timetablename'] = 'Timetable';
$string['timetablename_help'] = 'Timetable help'; $string['timetablename_help'] = 'Timetable help';
$string['timetablefieldset'] = 'Settings'; $string['timetablefieldset'] = 'Settings';

View file

@ -20,7 +20,7 @@
{{#periods}} {{#periods}}
<tr sstyle="border:1px black; padding-top:0rem; padding-bottom:0rem"> <tr sstyle="border:1px black; padding-top:0rem; padding-bottom:0rem">
<td> <td>
<a href="javascript:;" style="color: black;" data-container="body" data-toggle="popover" data-placement="top" data-html="true" data-content="{{number}}. Stunde<br/>Beginn: {{starttime}} Uhr<br/>Ende: {{endtime}} Uhr" title="{{starttime}}-{{endtime}}"> <a href="javascript:;" style="color: black;" data-container="body" data-toggle="popover" data-trigger="hover focus" data-placement="top" data-html="true" data-content="{{number}}. Stunde<br/>Beginn: {{starttime}} Uhr<br/>Ende: {{endtime}} Uhr" title="{{starttime}}-{{endtime}}">
{{number}} {{number}}
<div class="time" id="{{id}}">{{starttime}}-{{endtime}}</div> <div class="time" id="{{id}}">{{starttime}}-{{endtime}}</div>
</a></td> </a></td>
@ -28,7 +28,7 @@
<td style="padding-top:0rem; padding-bottom:0rem; vertical-align:middle; border-left:1px black;"> <td style="padding-top:0rem; padding-bottom:0rem; vertical-align:middle; border-left:1px black;">
{{#lessons}} {{#lessons}}
<div class="lesson {{#substitution}}substitution{{/substitution}} {{cancel4me}} {{#subtype}}subtype_{{.}} {{/subtype}}"> <div class="lesson {{#substitution}}substitution{{/substitution}} {{cancel4me}} {{#subtype}}subtype_{{.}} {{/subtype}}">
<a href="javascript:;" data-container="body" data-toggle="popover" data-placement="top" data-html="true" <a href="javascript:;" data-container="body" data-toggle="popover" data-trigger="hover focus" data-placement="top" data-html="true"
data-content="Fach: {{subject}} data-content="Fach: {{subject}}
{{#subjectchanged}} {{#subjectchanged}}
{{#cancel}}{{#subjectb}} wird ersetzt durch {{subjectb}}{{/subjectb}}{{^subjectb}} entfällt{{/subjectb}}{{/cancel}} {{#cancel}}{{#subjectb}} wird ersetzt durch {{subjectb}}{{/subjectb}}{{^subjectb}} entfällt{{/subjectb}}{{/cancel}}
@ -122,6 +122,8 @@ require([
block_timetable_type = type; block_timetable_type = type;
} }
//$('[data-toggle="popover"]').popover();
//alert("Hi, this is a test"); //alert("Hi, this is a test");
$(".nextweek").click(function() { $(".nextweek").click(function() {
load_timetable($(event.target).data('type'), $(event.target).data('name'), $(event.target).data('week'), $(event.target).data('id')); //.parentNode.parentNode.parentNode.parentNode); load_timetable($(event.target).data('type'), $(event.target).data('name'), $(event.target).data('week'), $(event.target).data('id')); //.parentNode.parentNode.parentNode.parentNode);
@ -156,7 +158,13 @@ require([
select_type(block_timetable_type); select_type(block_timetable_type);
} else { } else {
select_type('subject'); select_type('subject');
} };
$(document).ready(function(){
$('[data-toggle="popover"]').popover();
});
//$('[data-toggle="popover"]').popover();
}); });
{{/ js }} {{/ js }}

View file

@ -25,7 +25,7 @@
defined('MOODLE_INTERNAL') || die(); defined('MOODLE_INTERNAL') || die();
$plugin->component = 'mod_timetable'; $plugin->component = 'mod_timetable';
$plugin->release = '0.1.0'; $plugin->release = '0.2.0';
$plugin->version = 2020112102; $plugin->version = 2020120401;
$plugin->requires = 2020061500; $plugin->requires = 2020061500;
$plugin->maturity = MATURITY_ALPHA; $plugin->maturity = MATURITY_ALPHA;