mirror of
https://github.com/FH-Complete/FHC-Core.git
synced 2026-10-12 15:04:04 +00:00
Added new event details endopint for html preview
This commit is contained in:
@@ -130,6 +130,7 @@ $route['lvplan/ical/download'] = 'LvPlanICALDownload';
|
||||
$route['lvplan/csv/download'] = 'LvPlanCSVDownload';
|
||||
$route['lvplan/excel/download'] = 'LvPlanExcelDownload';
|
||||
$route['lvplan/html/preview'] = 'LvPlanHTMLPreview';
|
||||
$route['lvplan/html/detail'] = 'LvPlanHTMLDetail';
|
||||
|
||||
// load routes from extensions, also look for environment-specific configs
|
||||
$subdirs = ['application/config/extensions', 'application/config/' . ENVIRONMENT . '/extensions'];
|
||||
|
||||
@@ -0,0 +1,333 @@
|
||||
<?php
|
||||
|
||||
if (!defined('BASEPATH'))
|
||||
exit('No direct script access allowed');
|
||||
|
||||
require_once(FHCPATH.'include/functions.inc.php');
|
||||
|
||||
class LvPlanHTMLDetail extends Auth_Controller
|
||||
{
|
||||
const TIMEZONE = 'Europe/Vienna';
|
||||
|
||||
/**
|
||||
* Object initialization.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(array(
|
||||
'index' => array('basis/cis:r')
|
||||
));
|
||||
|
||||
$this->load->model('person/Benutzer_model', 'BenutzerModel');
|
||||
$this->load->model('organisation/Studiengang_model', 'StudiengangModel');
|
||||
$this->load->model('ressource/Ort_model', 'OrtModel');
|
||||
$this->load->model('ressource/Stunde_model', 'StundeModel');
|
||||
$this->loadPhrases(array(
|
||||
'global' => array('termine'),
|
||||
'ui' => array('organisierende', 'teilnehmende')
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Serves details for one hour in the HTML timetable preview.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$type = $this->getType();
|
||||
$datum = $this->getDate();
|
||||
$hour = $this->getHour();
|
||||
|
||||
if ($type === 'verband')
|
||||
$filters = $this->getVerbandFilters();
|
||||
elseif ($type === 'ort')
|
||||
$filters = $this->getRoomFilters();
|
||||
else
|
||||
$filters = $this->getPersonalFilters();
|
||||
|
||||
$this->load->library('LvPlanHTMLDetailLib');
|
||||
$content = $this->lvplanhtmldetaillib->getContent(
|
||||
$datum,
|
||||
$hour,
|
||||
$type,
|
||||
$filters
|
||||
);
|
||||
|
||||
$this->output
|
||||
->set_content_type('text/html', 'UTF-8')
|
||||
->set_header('X-Content-Type-Options: nosniff')
|
||||
->set_output($content);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string Requested timetable type.
|
||||
*/
|
||||
private function getType()
|
||||
{
|
||||
$type = $this->input->get('type', true);
|
||||
|
||||
if (!in_array($type, array('student', 'lektor', 'verband', 'ort'), true))
|
||||
show_error('Ungueltiger Parameter: type', 400);
|
||||
|
||||
return $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string Date in YYYY-MM-DD format.
|
||||
*/
|
||||
private function getDate()
|
||||
{
|
||||
$value = $this->input->get('datum', true);
|
||||
if (!is_string($value) || !preg_match('/^\d{4}-\d{2}-\d{2}$/', $value))
|
||||
show_error('Ungueltiger Parameter: datum', 400);
|
||||
|
||||
$date = DateTime::createFromFormat(
|
||||
'!Y-m-d',
|
||||
$value,
|
||||
new DateTimeZone(self::TIMEZONE)
|
||||
);
|
||||
$errors = DateTime::getLastErrors();
|
||||
if ($date === false
|
||||
|| ($errors !== false
|
||||
&& ($errors['warning_count'] > 0 || $errors['error_count'] > 0))
|
||||
|| $date->format('Y-m-d') !== $value)
|
||||
{
|
||||
show_error('Ungueltiger Parameter: datum', 400);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array Selected timetable hour.
|
||||
*/
|
||||
private function getHour()
|
||||
{
|
||||
$number = $this->getInteger('stunde', false);
|
||||
$this->StundeModel->addSelect('stunde, beginn, ende');
|
||||
$result = $this->StundeModel->load($number);
|
||||
|
||||
if (isError($result))
|
||||
show_error(getError($result), 500);
|
||||
if (!hasData($result))
|
||||
show_error('Ungueltiger Parameter: stunde', 400);
|
||||
|
||||
$hours = getData($result);
|
||||
$hour = reset($hours);
|
||||
$begin = isset($hour->beginn) ? (string)$hour->beginn : '';
|
||||
$end = isset($hour->ende) ? (string)$hour->ende : '';
|
||||
$beginSeconds = $this->timeToSeconds($begin);
|
||||
$endSeconds = $this->timeToSeconds($end);
|
||||
|
||||
if ($beginSeconds === null || $endSeconds === null || $endSeconds <= $beginSeconds)
|
||||
show_error('Ungueltiges Stundenraster', 500);
|
||||
|
||||
return array(
|
||||
'number' => (string)$hour->stunde,
|
||||
'begin' => $begin,
|
||||
'end' => $end
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array Personal timetable filters.
|
||||
*/
|
||||
private function getPersonalFilters()
|
||||
{
|
||||
$uid = $this->input->get('pers_uid', true);
|
||||
if (!is_string($uid) || $uid === '' || !check_utf8($uid))
|
||||
show_error('Ungueltiger Parameter: pers_uid', 400);
|
||||
|
||||
if ($uid !== getAuthUID()
|
||||
&& !$this->permissionlib->isBerechtigt('basis/other_lv_plan'))
|
||||
{
|
||||
show_error('Forbidden', 403);
|
||||
}
|
||||
|
||||
$this->BenutzerModel->addSelect(
|
||||
'tbl_benutzer.uid, tbl_person.titelpre, tbl_person.vorname, '
|
||||
.'tbl_person.nachname, tbl_person.titelpost'
|
||||
);
|
||||
$this->BenutzerModel->addJoin('public.tbl_person', 'person_id', 'LEFT');
|
||||
$result = $this->BenutzerModel->load(array($uid));
|
||||
|
||||
if (isError($result))
|
||||
show_error(getError($result), 500);
|
||||
if (!hasData($result))
|
||||
show_error('Ungueltiger Parameter: pers_uid', 400);
|
||||
|
||||
$users = getData($result);
|
||||
$user = reset($users);
|
||||
$nameParts = array();
|
||||
foreach (array('titelpre', 'vorname', 'nachname', 'titelpost') as $property)
|
||||
{
|
||||
if (isset($user->{$property}) && trim($user->{$property}) !== '')
|
||||
$nameParts[] = trim($user->{$property});
|
||||
}
|
||||
|
||||
return array(
|
||||
'uid' => $uid,
|
||||
'full_name' => implode(' ', $nameParts)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array Room timetable filters.
|
||||
*/
|
||||
private function getRoomFilters()
|
||||
{
|
||||
$ortKurzbz = $this->input->get('ort_kurzbz', true);
|
||||
if (!is_string($ortKurzbz) || $ortKurzbz === '' || !check_utf8($ortKurzbz))
|
||||
show_error('Ungueltiger Parameter: ort_kurzbz', 400);
|
||||
|
||||
$this->OrtModel->addSelect('ort_kurzbz, bezeichnung, content_id');
|
||||
$result = $this->OrtModel->load($ortKurzbz);
|
||||
|
||||
if (isError($result))
|
||||
show_error(getError($result), 500);
|
||||
if (!hasData($result))
|
||||
show_error('Ungueltiger Parameter: ort_kurzbz', 400);
|
||||
|
||||
$rooms = getData($result);
|
||||
$room = reset($rooms);
|
||||
|
||||
return array(
|
||||
'ort_kurzbz' => $ortKurzbz,
|
||||
'bezeichnung' => isset($room->bezeichnung) ? $room->bezeichnung : '',
|
||||
'content_id' => isset($room->content_id) ? $room->content_id : null
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array Lehrverband timetable filters.
|
||||
*/
|
||||
private function getVerbandFilters()
|
||||
{
|
||||
$stgKz = $this->getInteger('stg_kz', true);
|
||||
$semester = $this->getInteger('sem', false, true);
|
||||
$verband = $this->getOptionalFilter('ver');
|
||||
$gruppe = $this->getOptionalFilter('grp');
|
||||
$ortKurzbz = $this->getOptionalRoomFilter();
|
||||
|
||||
$this->StudiengangModel->addSelect(
|
||||
'studiengang_kz, UPPER(typ || kurzbz) AS stg_kurzbz'
|
||||
);
|
||||
$result = $this->StudiengangModel->load($stgKz);
|
||||
|
||||
if (isError($result))
|
||||
show_error(getError($result), 500);
|
||||
if (!hasData($result))
|
||||
show_error('Ungueltiger Parameter: stg_kz', 400);
|
||||
|
||||
$programs = getData($result);
|
||||
$program = reset($programs);
|
||||
|
||||
return array(
|
||||
'stg_kz' => $stgKz,
|
||||
'stg_kurzbz' => isset($program->stg_kurzbz)
|
||||
? $program->stg_kurzbz
|
||||
: '',
|
||||
'sem' => $semester,
|
||||
'ver' => $verband,
|
||||
'grp' => $gruppe,
|
||||
'ort_kurzbz' => $ortKurzbz
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the room selected in a Verband preview cell, if present.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
private function getOptionalRoomFilter()
|
||||
{
|
||||
$ortKurzbz = $this->input->get('ort_kurzbz', true);
|
||||
if ($ortKurzbz === null || $ortKurzbz === '')
|
||||
return null;
|
||||
if (!is_string($ortKurzbz) || !check_utf8($ortKurzbz))
|
||||
show_error('Ungueltiger Parameter: ort_kurzbz', 400);
|
||||
|
||||
$this->OrtModel->addSelect('ort_kurzbz');
|
||||
$result = $this->OrtModel->load($ortKurzbz);
|
||||
|
||||
if (isError($result))
|
||||
show_error(getError($result), 500);
|
||||
if (!hasData($result))
|
||||
show_error('Ungueltiger Parameter: ort_kurzbz', 400);
|
||||
|
||||
return $ortKurzbz;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name GET parameter name.
|
||||
* @param bool $signed Whether negative values are allowed.
|
||||
* @param bool $optional Whether the parameter may be omitted or empty.
|
||||
* @return int|null
|
||||
*/
|
||||
private function getInteger($name, $signed, $optional = false)
|
||||
{
|
||||
$value = $this->input->get($name, true);
|
||||
if ($optional && ($value === null || $value === ''))
|
||||
return null;
|
||||
|
||||
$pattern = $signed ? '/^-?\d+$/' : '/^\d+$/';
|
||||
if (!is_string($value) || !preg_match($pattern, $value))
|
||||
show_error('Ungueltiger Parameter: '.$name, 400);
|
||||
|
||||
$isNegative = $signed && substr($value, 0, 1) === '-';
|
||||
$digits = $isNegative ? substr($value, 1) : $value;
|
||||
$digits = ltrim($digits, '0');
|
||||
if ($digits === '')
|
||||
$digits = '0';
|
||||
$normalizedValue = $isNegative && $digits !== '0' ? '-'.$digits : $digits;
|
||||
|
||||
$integer = filter_var($normalizedValue, FILTER_VALIDATE_INT);
|
||||
if ($integer === false || (!$signed && $integer < 0))
|
||||
show_error('Ungueltiger Parameter: '.$name, 400);
|
||||
|
||||
return $integer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns null for the legacy wildcard values "" and "0".
|
||||
*
|
||||
* @param string $name GET parameter name.
|
||||
* @return string|null
|
||||
*/
|
||||
private function getOptionalFilter($name)
|
||||
{
|
||||
$value = $this->input->get($name, true);
|
||||
if ($value === null || $value === '' || $value === '0')
|
||||
return null;
|
||||
|
||||
if (!is_string($value)
|
||||
|| !check_utf8($value)
|
||||
|| mb_strlen($value) > 20
|
||||
|| !preg_match('/^[[:alnum:]_-]+$/u', $value))
|
||||
{
|
||||
show_error('Ungueltiger Parameter: '.$name, 400);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $time PostgreSQL time value.
|
||||
* @return int|null
|
||||
*/
|
||||
private function timeToSeconds($time)
|
||||
{
|
||||
if (!preg_match('/^(\d{1,2}):(\d{2})(?::(\d{2})(?:\.\d+)?)?$/', $time, $matches))
|
||||
return null;
|
||||
|
||||
$hours = (int)$matches[1];
|
||||
$minutes = (int)$matches[2];
|
||||
$seconds = isset($matches[3]) ? (int)$matches[3] : 0;
|
||||
|
||||
if ($hours > 23 || $minutes > 59 || $seconds > 59)
|
||||
return null;
|
||||
|
||||
return $hours * 3600 + $minutes * 60 + $seconds;
|
||||
}
|
||||
}
|
||||
@@ -52,10 +52,18 @@ class KalenderLib
|
||||
tbl_kalender.typ,
|
||||
tbl_kalender.von,
|
||||
tbl_kalender.bis,
|
||||
tbl_kalender.insertvon AS created_by_uid,
|
||||
kalender_ersteller_person.titelpre AS created_by_titelpre,
|
||||
kalender_ersteller_person.titelpost AS created_by_titelpost,
|
||||
kalender_ersteller_person.vorname AS created_by_vorname,
|
||||
kalender_ersteller_person.nachname AS created_by_nachname,
|
||||
tbl_kalender_ort.ort_kurzbz,
|
||||
tbl_kalender_ort.ort_kurzbz as ko_ort_kurzbz,
|
||||
tbl_kalender_ort.location as ko_location,
|
||||
kalender_ort.bezeichnung AS ko_ort_bezeichnung,
|
||||
kalender_ort.content_id AS ko_ort_content_id,
|
||||
tbl_lehreinheit.lehreinheit_id,
|
||||
tbl_lehreinheit.unr,
|
||||
tbl_lehreinheit.lehrveranstaltung_id,
|
||||
tbl_lehreinheit.lehrfach_id,
|
||||
tbl_lehreinheit.lehrform_kurzbz,
|
||||
@@ -64,9 +72,12 @@ class KalenderLib
|
||||
lehrfach.bezeichnung AS lehrfach_bezeichnung,
|
||||
lehrfach.farbe,
|
||||
COALESCE(organisator.uid, tbl_lehreinheitmitarbeiter.mitarbeiter_uid) as mitarbeiter_uid,
|
||||
COALESCE(reservierung_person.titelpre, tbl_person.titelpre) as titelpre,
|
||||
COALESCE(reservierung_person.titelpost, tbl_person.titelpost) as titelpost,
|
||||
COALESCE(reservierung_person.vorname, tbl_person.vorname) as vorname,
|
||||
COALESCE(reservierung_person.nachname, tbl_person.nachname) as nachname,
|
||||
COALESCE(reservierung_ma.kurzbz, tbl_mitarbeiter.kurzbz) AS ma_kurzbz,
|
||||
COALESCE(reservierung_ma.personalnummer, tbl_mitarbeiter.personalnummer) AS personalnummer,
|
||||
teilnehmergruppe.gruppe_kurzbz as teilnehmerg_grp,
|
||||
teilnehmergruppe.bezeichnung as teilnehmerg_grp_bezeichnung,
|
||||
COALESCE (
|
||||
@@ -78,6 +89,8 @@ class KalenderLib
|
||||
tbl_kalender_event.beschreibung,
|
||||
tbl_kalender_event.titel,
|
||||
teilmitarbeiter.kurzbz as teilnehmer_kurzbz,
|
||||
teilperson.titelpre as teilnehmer_titelpre,
|
||||
teilperson.titelpost as teilnehmer_titelpost,
|
||||
teilperson.vorname as teilnehmer_vorname,
|
||||
teilperson.nachname as teilnehmer_nachname,
|
||||
teilbenutzer.uid as teilnehmer_uid,
|
||||
@@ -103,6 +116,12 @@ class KalenderLib
|
||||
|
||||
$this->_ci->KalenderModel->addJoin('lehre.tbl_kalender_lehreinheit', 'tbl_kalender.kalender_id = tbl_kalender_lehreinheit.kalender_id', 'LEFT');
|
||||
$this->_ci->KalenderModel->addJoin('lehre.tbl_kalender_event', 'tbl_kalender.kalender_id = tbl_kalender_event.kalender_id', 'LEFT');
|
||||
$this->_ci->KalenderModel->addJoin('public.tbl_benutzer kalender_ersteller', 'tbl_kalender.insertvon = kalender_ersteller.uid', 'LEFT');
|
||||
$this->_ci->KalenderModel->addJoin(
|
||||
'public.tbl_person kalender_ersteller_person',
|
||||
'kalender_ersteller.person_id = kalender_ersteller_person.person_id',
|
||||
'LEFT'
|
||||
);
|
||||
|
||||
$this->_ci->KalenderModel->addJoin('lehre.tbl_kalender_event_teilnehmer organisator', 'tbl_kalender_event.kalender_id = organisator.kalender_id AND organisator.rolle_kurzbz = \'organisator\'', 'LEFT');
|
||||
$this->_ci->KalenderModel->addJoin('lehre.tbl_kalender_event_teilnehmer teilnehmer', 'tbl_kalender_event.kalender_id = teilnehmer.kalender_id AND teilnehmer.rolle_kurzbz = \'teilnehmer\'', 'LEFT');
|
||||
@@ -124,6 +143,7 @@ class KalenderLib
|
||||
$this->_ci->KalenderModel->addJoin('lehre.tbl_lehrveranstaltung', 'tbl_lehreinheit.lehrveranstaltung_id = tbl_lehrveranstaltung.lehrveranstaltung_id', 'LEFT');
|
||||
$this->_ci->KalenderModel->addJoin('lehre.tbl_lehrveranstaltung lehrfach', 'tbl_lehreinheit.lehrfach_id = lehrfach.lehrveranstaltung_id', 'LEFT');
|
||||
$this->_ci->KalenderModel->addJoin('lehre.tbl_kalender_ort', 'tbl_kalender.kalender_id = tbl_kalender_ort.kalender_id', 'LEFT');
|
||||
$this->_ci->KalenderModel->addJoin('public.tbl_ort kalender_ort', 'tbl_kalender_ort.ort_kurzbz = kalender_ort.ort_kurzbz', 'LEFT');
|
||||
$this->_ci->KalenderModel->addJoin('lehre.tbl_lehreinheitmitarbeiter', 'tbl_lehreinheit.lehreinheit_id = tbl_lehreinheitmitarbeiter.lehreinheit_id', 'LEFT');
|
||||
|
||||
$this->_ci->KalenderModel->addJoin('public.tbl_mitarbeiter', 'tbl_mitarbeiter.mitarbeiter_uid = tbl_lehreinheitmitarbeiter.mitarbeiter_uid', 'LEFT');
|
||||
@@ -131,8 +151,12 @@ class KalenderLib
|
||||
$this->_ci->KalenderModel->addJoin('public.tbl_person', 'tbl_person.person_id = tbl_benutzer.person_id', 'LEFT');
|
||||
|
||||
$this->_ci->KalenderModel->addJoin('public.tbl_mitarbeiter reservierung_ma', 'reservierung_ma.mitarbeiter_uid = organisator.uid', 'LEFT');
|
||||
$this->_ci->KalenderModel->addJoin('public.tbl_benutzer resevierung_benutzer', 'reservierung_ma.mitarbeiter_uid = resevierung_benutzer.uid', 'LEFT');
|
||||
$this->_ci->KalenderModel->addJoin('public.tbl_person reservierung_person', 'reservierung_person.person_id = resevierung_benutzer.person_id', 'LEFT');
|
||||
$this->_ci->KalenderModel->addJoin('public.tbl_benutzer reservierung_benutzer', 'organisator.uid = reservierung_benutzer.uid', 'LEFT');
|
||||
$this->_ci->KalenderModel->addJoin(
|
||||
'public.tbl_person reservierung_person',
|
||||
'reservierung_person.person_id = reservierung_benutzer.person_id',
|
||||
'LEFT'
|
||||
);
|
||||
|
||||
$this->_ci->KalenderModel->addJoin('lehre.tbl_lehreinheitgruppe', 'tbl_lehreinheit.lehreinheit_id = tbl_lehreinheitgruppe.lehreinheit_id', 'LEFT');
|
||||
$this->_ci->KalenderModel->addJoin('public.tbl_gruppe le_gruppe', 'tbl_lehreinheitgruppe.gruppe_kurzbz = le_gruppe.gruppe_kurzbz', 'LEFT');
|
||||
@@ -179,19 +203,32 @@ class KalenderLib
|
||||
'tooltip' => 'tip',
|
||||
'status_kurzbz' => $row->status_kurzbz,
|
||||
'ort_kurzbz' => [],
|
||||
'ort_details' => [],
|
||||
'locations' => [],
|
||||
'ko_ort_kurzbz' => isset($row->ko_ort_kurzbz) ? $row->ko_ort_kurzbz : '',
|
||||
'ko_location' => isset($row->ko_location) ? $row->ko_location : '',
|
||||
'lehrform' => isset($row->lehrform_kurzbz) ? $row->lehrform_kurzbz : '',
|
||||
'lehrfach' => isset($row->lehrfach_kurzbz) ? $row->lehrfach_kurzbz : '',
|
||||
'lehrfach_bez' => isset($row->lehrfach_bezeichnung) ? $row->lehrfach_bezeichnung : '',
|
||||
'lehrfach_details' => [],
|
||||
'farbe' => isset($row->farbe) ? $row->farbe : '',
|
||||
'lehrveranstaltung_id' => $row->lehrveranstaltung_id,
|
||||
'organisationseinheit' => isset($row->oe_kurzbz) ? $row->oe_kurzbz : '',
|
||||
'lehreinheit_id' => [],
|
||||
'unr' => [],
|
||||
'lektor' => [],
|
||||
'teilnehmer_gruppe' => [],
|
||||
'teilnehmer_person' => [],
|
||||
'gruppe' => [],
|
||||
'created_by' => isset($row->created_by_uid) && $row->created_by_uid !== ''
|
||||
? [
|
||||
'uid' => $row->created_by_uid,
|
||||
'titelpre' => $row->created_by_titelpre,
|
||||
'titelpost' => $row->created_by_titelpost,
|
||||
'vorname' => $row->created_by_vorname,
|
||||
'nachname' => $row->created_by_nachname,
|
||||
]
|
||||
: null,
|
||||
'titel' => isset($row->titel) ? $row->titel : '',
|
||||
'beschreibung' => isset($row->beschreibung) ? $row->beschreibung : '',
|
||||
'topic' => [],
|
||||
@@ -204,9 +241,58 @@ class KalenderLib
|
||||
if ($row->lehreinheit_id && !in_array($row->lehreinheit_id, $events[$id]->lehreinheit_id))
|
||||
$events[$id]->lehreinheit_id[] = $row->lehreinheit_id;
|
||||
|
||||
if (isset($row->unr) && $row->unr !== null && $row->unr !== ''
|
||||
&& !in_array($row->unr, $events[$id]->unr))
|
||||
{
|
||||
$events[$id]->unr[] = $row->unr;
|
||||
}
|
||||
|
||||
if (isset($row->ort_kurzbz) && $row->ort_kurzbz !== '' && !in_array($row->ort_kurzbz, $events[$id]->ort_kurzbz))
|
||||
$events[$id]->ort_kurzbz[] = $row->ort_kurzbz;
|
||||
|
||||
if (isset($row->ort_kurzbz) && $row->ort_kurzbz !== ''
|
||||
&& !in_array(
|
||||
$row->ort_kurzbz,
|
||||
array_column($events[$id]->ort_details, 'ort_kurzbz')
|
||||
))
|
||||
{
|
||||
$events[$id]->ort_details[] = [
|
||||
'ort_kurzbz' => $row->ort_kurzbz,
|
||||
'bezeichnung' => isset($row->ko_ort_bezeichnung)
|
||||
? $row->ko_ort_bezeichnung
|
||||
: '',
|
||||
'content_id' => isset($row->ko_ort_content_id)
|
||||
? $row->ko_ort_content_id
|
||||
: null,
|
||||
];
|
||||
}
|
||||
|
||||
if (isset($row->ko_location) && $row->ko_location !== ''
|
||||
&& !in_array($row->ko_location, $events[$id]->locations))
|
||||
{
|
||||
$events[$id]->locations[] = $row->ko_location;
|
||||
}
|
||||
|
||||
if (isset($row->lehrfach_id) && $row->lehrfach_id
|
||||
&& !in_array(
|
||||
$row->lehrfach_id,
|
||||
array_column($events[$id]->lehrfach_details, 'lehrfach_id')
|
||||
))
|
||||
{
|
||||
$events[$id]->lehrfach_details[] = [
|
||||
'lehrfach_id' => $row->lehrfach_id,
|
||||
'kurzbz' => isset($row->lehrfach_kurzbz)
|
||||
? $row->lehrfach_kurzbz
|
||||
: '',
|
||||
'bezeichnung' => isset($row->lehrfach_bezeichnung)
|
||||
? $row->lehrfach_bezeichnung
|
||||
: '',
|
||||
'lehrform' => isset($row->lehrform_kurzbz)
|
||||
? $row->lehrform_kurzbz
|
||||
: '',
|
||||
];
|
||||
}
|
||||
|
||||
$topic = trim((isset($row->lehrfach_kurzbz) ? $row->lehrfach_kurzbz : '').' '.(isset($row->lehrform_kurzbz) ? $row->lehrform_kurzbz : ''));
|
||||
if ($topic !== '' && !in_array($topic, $events[$id]->topic))
|
||||
$events[$id]->topic[] = $topic;
|
||||
@@ -217,16 +303,19 @@ class KalenderLib
|
||||
{
|
||||
$events[$id]->lektor[] = [
|
||||
'mitarbeiter_uid' => $row->mitarbeiter_uid,
|
||||
'titelpre' => $row->titelpre,
|
||||
'titelpost' => $row->titelpost,
|
||||
'vorname' => $row->vorname,
|
||||
'nachname' => $row->nachname,
|
||||
'kurzbz' => $row->ma_kurzbz,
|
||||
'personalnummer' => $row->personalnummer,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
if ($row->verband_grp)
|
||||
{
|
||||
if (!in_array($row->teilnehmerg_grp, array_column($events[$id]->teilnehmer_gruppe, 'gruppe_kurzbz')))
|
||||
if (!in_array($row->verband_grp, array_column($events[$id]->teilnehmer_gruppe, 'gruppe_kurzbz')))
|
||||
{
|
||||
$events[$id]->teilnehmer_gruppe[] = [
|
||||
'gruppe_kurzbz' => $row->verband_grp,
|
||||
@@ -240,7 +329,7 @@ class KalenderLib
|
||||
{
|
||||
$events[$id]->teilnehmer_gruppe[] = [
|
||||
'gruppe_kurzbz' => $row->teilnehmerg_grp,
|
||||
'bezeichnung' => 222,
|
||||
'bezeichnung' => $row->teilnehmerg_grp_bezeichnung,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -267,6 +356,8 @@ class KalenderLib
|
||||
{
|
||||
$events[$id]->teilnehmer_person[] = [
|
||||
'uid' => $row->teilnehmer_uid,
|
||||
'titelpre' => $row->teilnehmer_titelpre,
|
||||
'titelpost' => $row->teilnehmer_titelpost,
|
||||
'vorname' => $row->teilnehmer_vorname,
|
||||
'nachname' => $row->teilnehmer_nachname,
|
||||
'kurzbz' => $row->teilnehmer_kurzbz,
|
||||
|
||||
@@ -0,0 +1,776 @@
|
||||
<?php
|
||||
|
||||
if (!defined('BASEPATH'))
|
||||
exit('No direct script access allowed');
|
||||
|
||||
require_once(FHCPATH.'include/functions.inc.php');
|
||||
require_once(FHCPATH.'include/phrasen.class.php');
|
||||
|
||||
class LvPlanHTMLDetailLib
|
||||
{
|
||||
const TIMEZONE = 'Europe/Vienna';
|
||||
|
||||
private $ci;
|
||||
private $legacyPhrases;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->ci =& get_instance();
|
||||
$this->legacyPhrases = new phrasen(getSprache());
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a timetable detail document for one date and hour.
|
||||
*
|
||||
* @param string $datum Date in YYYY-MM-DD format.
|
||||
* @param array $hour Selected timetable hour.
|
||||
* @param string $type Timetable type.
|
||||
* @param array $filters Type-specific filters.
|
||||
* @return string
|
||||
*/
|
||||
public function getContent($datum, array $hour, $type, array $filters)
|
||||
{
|
||||
if (!in_array($type, array('student', 'lektor', 'verband', 'ort'), true))
|
||||
throw new InvalidArgumentException('Unsupported timetable type');
|
||||
foreach (array('number', 'begin', 'end') as $property)
|
||||
{
|
||||
if (!isset($hour[$property]) || !is_scalar($hour[$property]))
|
||||
throw new InvalidArgumentException('Invalid timetable hour');
|
||||
}
|
||||
|
||||
$events = $this->loadEvents($datum, $type, $filters);
|
||||
$events = $this->filterEventsByHour($events, $datum, $hour);
|
||||
if ($type === 'verband'
|
||||
&& isset($filters['ort_kurzbz'])
|
||||
&& $filters['ort_kurzbz'] !== '')
|
||||
{
|
||||
$events = $this->filterEventsByRoom(
|
||||
$events,
|
||||
$filters['ort_kurzbz']
|
||||
);
|
||||
}
|
||||
$sections = array(
|
||||
'teaching' => array(),
|
||||
'reservations' => array(),
|
||||
'events' => array()
|
||||
);
|
||||
|
||||
foreach ($events as $event)
|
||||
{
|
||||
if ($event->type === 'lehreinheit')
|
||||
$sections['teaching'][] = $event;
|
||||
elseif ($event->type === 'reservierung')
|
||||
$sections['reservations'][] = $event;
|
||||
else
|
||||
$sections['events'][] = $event;
|
||||
}
|
||||
|
||||
return $this->renderDocument($datum, $hour, $sections);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the same published calendar data used by the HTML preview.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function loadEvents($datum, $type, array $filters)
|
||||
{
|
||||
$uid = isset($filters['uid']) && is_string($filters['uid'])
|
||||
? $filters['uid']
|
||||
: getAuthUID();
|
||||
$this->ci->load->library('KalenderLib', array('uid' => $uid));
|
||||
|
||||
if ($type === 'verband')
|
||||
{
|
||||
$events = $this->ci->kalenderlib->getPlanForVerband(
|
||||
$datum,
|
||||
$datum,
|
||||
$filters['stg_kz'],
|
||||
$filters['sem'],
|
||||
isset($filters['ver']) ? $filters['ver'] : null,
|
||||
isset($filters['grp']) ? $filters['grp'] : null
|
||||
);
|
||||
}
|
||||
elseif ($type === 'ort')
|
||||
{
|
||||
$events = $this->ci->kalenderlib->getPlanForRoom(
|
||||
$datum,
|
||||
$datum,
|
||||
$filters['ort_kurzbz']
|
||||
);
|
||||
}
|
||||
elseif ($type === 'lektor')
|
||||
{
|
||||
$events = $this->ci->kalenderlib->getPlanForLecturerByLecturer(
|
||||
$datum,
|
||||
$datum,
|
||||
$filters['uid']
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
$events = $this->ci->kalenderlib->getPlanForStudentByStudent(
|
||||
$datum,
|
||||
$datum,
|
||||
$filters['uid']
|
||||
);
|
||||
}
|
||||
|
||||
return is_array($events) ? $events : array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Keeps events that overlap the selected timetable hour.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function filterEventsByHour(array $events, $datum, array $hour)
|
||||
{
|
||||
$timezone = new DateTimeZone(self::TIMEZONE);
|
||||
$hourStart = DateTime::createFromFormat(
|
||||
'!Y-m-d H:i:s',
|
||||
$datum.' '.$this->normalizeTime($hour['begin']),
|
||||
$timezone
|
||||
);
|
||||
$hourEnd = DateTime::createFromFormat(
|
||||
'!Y-m-d H:i:s',
|
||||
$datum.' '.$this->normalizeTime($hour['end']),
|
||||
$timezone
|
||||
);
|
||||
|
||||
if ($hourStart === false || $hourEnd === false || $hourEnd <= $hourStart)
|
||||
throw new InvalidArgumentException('Invalid timetable hour range');
|
||||
|
||||
$matches = array();
|
||||
foreach ($events as $event)
|
||||
{
|
||||
$start = $this->getEventDateTime($event, 'isostart', 'datum', 'beginn');
|
||||
$end = $this->getEventDateTime($event, 'isoend', 'datum', 'ende');
|
||||
|
||||
if ($start === null || $end === null || $end <= $start)
|
||||
continue;
|
||||
if ($start < $hourEnd && $end > $hourStart)
|
||||
{
|
||||
$matches[] = array(
|
||||
'event' => $event,
|
||||
'start' => $start,
|
||||
'end' => $end
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
usort($matches, function ($first, $second) {
|
||||
$comparison = $first['start']->getTimestamp()
|
||||
<=> $second['start']->getTimestamp();
|
||||
if ($comparison !== 0)
|
||||
return $comparison;
|
||||
|
||||
$firstId = isset($first['event']->kalender_id)
|
||||
? (int)$first['event']->kalender_id
|
||||
: 0;
|
||||
$secondId = isset($second['event']->kalender_id)
|
||||
? (int)$second['event']->kalender_id
|
||||
: 0;
|
||||
return $firstId <=> $secondId;
|
||||
});
|
||||
|
||||
return array_map(function ($match) {
|
||||
return $match['event'];
|
||||
}, $matches);
|
||||
}
|
||||
|
||||
/**
|
||||
* Keeps Verband events assigned to the room selected in the preview cell.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function filterEventsByRoom(array $events, $ortKurzbz)
|
||||
{
|
||||
$matches = array();
|
||||
foreach ($events as $event)
|
||||
{
|
||||
$rooms = isset($event->ort_kurzbz)
|
||||
? $event->ort_kurzbz
|
||||
: array();
|
||||
if (!is_array($rooms))
|
||||
$rooms = array($rooms);
|
||||
|
||||
foreach ($rooms as $room)
|
||||
{
|
||||
if (is_scalar($room) && (string)$room === (string)$ortKurzbz)
|
||||
{
|
||||
$matches[] = $event;
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($event->ort_details) || !is_array($event->ort_details))
|
||||
continue;
|
||||
|
||||
foreach ($event->ort_details as $room)
|
||||
{
|
||||
if ($this->getNestedValue($room, 'ort_kurzbz') === (string)$ortKurzbz)
|
||||
{
|
||||
$matches[] = $event;
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $matches;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the complete HTML document.
|
||||
*/
|
||||
private function renderDocument($datum, array $hour, array $sections)
|
||||
{
|
||||
$title = $this->phrase('lvplan', 'lehrveranstaltungsplanDetails');
|
||||
$html = '<!DOCTYPE html><html lang="de"><head><meta charset="UTF-8">';
|
||||
$html .= '<meta name="viewport" content="width=device-width, initial-scale=1">';
|
||||
$html .= '<title>'.$this->escape($title).'</title>';
|
||||
$html .= '<link rel="stylesheet" href="'
|
||||
.$this->escape($this->getAppRoot().'skin/style.css.php')
|
||||
.'" type="text/css">';
|
||||
$html .= '<style>'
|
||||
.'.stdplan td{vertical-align:top}.detail-lines{white-space:normal}'
|
||||
.'.detail-empty{color:#666}.stdplan{margin-bottom:1em}'
|
||||
.'</style></head><body id="inhalt">';
|
||||
$html .= '<h2>'.$this->escape($this->phrase('lvplan', 'lehrveranstaltungsplan'))
|
||||
.' ⇒ '.$this->escape($this->phrase('abgabetool', 'details')).'</h2>';
|
||||
$html .= $this->escape($this->phrase('abgabetool', 'datum')).': '
|
||||
.$this->escape($this->formatDate($datum)).'<br>';
|
||||
$html .= $this->escape($this->phrase('global', 'stunde')).': '
|
||||
.$this->escape($hour['number']).' ('
|
||||
.$this->escape(substr((string)$hour['begin'], 0, 5)).'–'
|
||||
.$this->escape(substr((string)$hour['end'], 0, 5)).')<br><br>';
|
||||
|
||||
if (!empty($sections['teaching']))
|
||||
$html .= $this->renderTeachingTable($sections['teaching']);
|
||||
if (!empty($sections['reservations']))
|
||||
$html .= $this->renderReservationTable($sections['reservations']);
|
||||
if (!empty($sections['events']))
|
||||
$html .= $this->renderEventTable($sections['events']);
|
||||
|
||||
if (empty($sections['teaching'])
|
||||
&& empty($sections['reservations'])
|
||||
&& empty($sections['events']))
|
||||
{
|
||||
$html .= '<p class="detail-empty">0 '
|
||||
.$this->escape($this->phrase('global', 'termine')).'</p>';
|
||||
}
|
||||
|
||||
if (defined('MAIL_LVPLAN'))
|
||||
{
|
||||
$html .= '<p>'.$this->phrase(
|
||||
'lvplan',
|
||||
'FragenZuLvPlan',
|
||||
array(constant('MAIL_LVPLAN'))
|
||||
).'</p>';
|
||||
}
|
||||
|
||||
return $html.'</body></html>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders teaching-unit details.
|
||||
*/
|
||||
private function renderTeachingTable(array $events)
|
||||
{
|
||||
$html = '<table class="stdplan"><thead><tr>';
|
||||
foreach (array(
|
||||
array('lvplan', 'unr'),
|
||||
array('lvaliste', 'lektor'),
|
||||
array('lvplan', 'ort'),
|
||||
array('lvaliste', 'lehrfach'),
|
||||
array('global', 'bezeichnung'),
|
||||
array('global', 'verband'),
|
||||
array('lvplan', 'einheit'),
|
||||
array('lvplan', 'info')
|
||||
) as $heading)
|
||||
{
|
||||
$html .= '<th>'.$this->escape($this->phrase($heading[0], $heading[1])).'</th>';
|
||||
}
|
||||
$html .= '</tr></thead><tbody>';
|
||||
|
||||
foreach ($events as $index => $event)
|
||||
{
|
||||
$html .= '<tr class="liste'.(($index + 1) % 2).'">';
|
||||
$html .= $this->cell($this->renderScalarLines(
|
||||
isset($event->unr) ? $event->unr : array()
|
||||
));
|
||||
$html .= $this->cell($this->renderPeople(
|
||||
isset($event->lektor) ? $event->lektor : array(),
|
||||
'profile'
|
||||
));
|
||||
$html .= $this->cell($this->renderRooms($event));
|
||||
$html .= $this->cell($this->renderSubjectValues($event, 'kurzbz'));
|
||||
$html .= $this->cell($this->renderSubjectValues($event, 'bezeichnung'));
|
||||
$html .= $this->cell($this->renderTeachingGroups($event, false));
|
||||
$html .= $this->cell($this->renderTeachingGroups($event, true));
|
||||
$html .= $this->cell($this->renderDescription($event));
|
||||
$html .= '</tr>';
|
||||
}
|
||||
|
||||
return $html.'</tbody></table>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders reservation details.
|
||||
*/
|
||||
private function renderReservationTable(array $events)
|
||||
{
|
||||
$html = '<h2>'.$this->escape($this->phrase('lvplan', 'reservierungen')).'</h2>';
|
||||
$html .= '<table class="stdplan"><thead><tr>';
|
||||
foreach (array(
|
||||
array('global', 'titel'),
|
||||
array('lvplan', 'ort'),
|
||||
array('global', 'person'),
|
||||
array('global', 'beschreibung'),
|
||||
array('lvplan', 'reserviertVon')
|
||||
) as $heading)
|
||||
{
|
||||
$html .= '<th>'.$this->escape($this->phrase($heading[0], $heading[1])).'</th>';
|
||||
}
|
||||
$html .= '</tr></thead><tbody>';
|
||||
|
||||
foreach ($events as $index => $event)
|
||||
{
|
||||
$html .= '<tr class="liste'.(($index + 1) % 2).'">';
|
||||
$html .= $this->cell($this->escape($this->getScalar($event, 'titel')));
|
||||
$html .= $this->cell($this->renderRooms($event));
|
||||
$html .= $this->cell($this->renderParticipants($event));
|
||||
$html .= $this->cell($this->renderText(
|
||||
$this->getScalar($event, 'beschreibung')
|
||||
));
|
||||
$html .= $this->cell($this->renderCreator($event));
|
||||
$html .= '</tr>';
|
||||
}
|
||||
|
||||
return $html.'</tbody></table>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders non-teaching, non-reservation calendar events.
|
||||
*/
|
||||
private function renderEventTable(array $events)
|
||||
{
|
||||
$html = '<h2>'.$this->escape($this->phrase('global', 'termine')).'</h2>';
|
||||
$html .= '<table class="stdplan"><thead><tr>';
|
||||
foreach (array(
|
||||
array('global', 'titel'),
|
||||
array('lvplan', 'ort'),
|
||||
array('ui', 'organisierende'),
|
||||
array('ui', 'teilnehmende'),
|
||||
array('global', 'beschreibung')
|
||||
) as $heading)
|
||||
{
|
||||
$html .= '<th>'.$this->escape($this->phrase($heading[0], $heading[1])).'</th>';
|
||||
}
|
||||
$html .= '</tr></thead><tbody>';
|
||||
|
||||
foreach ($events as $index => $event)
|
||||
{
|
||||
$html .= '<tr class="liste'.(($index + 1) % 2).'">';
|
||||
$html .= $this->cell($this->escape($this->getEventTitle($event)));
|
||||
$html .= $this->cell($this->renderRooms($event));
|
||||
$html .= $this->cell($this->renderPeople(
|
||||
isset($event->lektor) ? $event->lektor : array(),
|
||||
'mail'
|
||||
));
|
||||
$html .= $this->cell($this->renderParticipants($event));
|
||||
$html .= $this->cell($this->renderText(
|
||||
$this->getScalar($event, 'beschreibung')
|
||||
));
|
||||
$html .= '</tr>';
|
||||
}
|
||||
|
||||
return $html.'</tbody></table>';
|
||||
}
|
||||
|
||||
private function renderSubjectValues($event, $property)
|
||||
{
|
||||
$values = array();
|
||||
if (isset($event->lehrfach_details) && is_array($event->lehrfach_details))
|
||||
{
|
||||
foreach ($event->lehrfach_details as $subject)
|
||||
{
|
||||
$value = $this->getNestedValue($subject, $property);
|
||||
if ($value !== '')
|
||||
$values[] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($values))
|
||||
{
|
||||
$fallback = $property === 'kurzbz'
|
||||
? $this->getScalar($event, 'lehrfach')
|
||||
: $this->getScalar($event, 'lehrfach_bez');
|
||||
if ($fallback !== '')
|
||||
$values[] = $fallback;
|
||||
}
|
||||
|
||||
return $this->renderScalarLines($values);
|
||||
}
|
||||
|
||||
private function renderTeachingGroups($event, $specialGroups)
|
||||
{
|
||||
$values = array();
|
||||
if (isset($event->gruppe) && is_array($event->gruppe))
|
||||
{
|
||||
foreach ($event->gruppe as $group)
|
||||
{
|
||||
$groupCode = $this->getNestedValue($group, 'gruppe_kurzbz');
|
||||
if ($specialGroups && $groupCode !== '')
|
||||
$values[] = $groupCode;
|
||||
elseif (!$specialGroups && $groupCode === '')
|
||||
{
|
||||
$designation = $this->getNestedValue($group, 'bezeichnung');
|
||||
if ($designation !== '')
|
||||
$values[] = $designation;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->renderGroupLinks($values);
|
||||
}
|
||||
|
||||
private function renderParticipants($event)
|
||||
{
|
||||
$parts = array();
|
||||
$people = $this->renderPeople(
|
||||
isset($event->teilnehmer_person) ? $event->teilnehmer_person : array(),
|
||||
'mail'
|
||||
);
|
||||
if ($people !== '')
|
||||
$parts[] = $people;
|
||||
|
||||
$groups = array();
|
||||
if (isset($event->teilnehmer_gruppe) && is_array($event->teilnehmer_gruppe))
|
||||
{
|
||||
foreach ($event->teilnehmer_gruppe as $group)
|
||||
{
|
||||
$value = $this->getNestedValue($group, 'bezeichnung');
|
||||
if ($value === '')
|
||||
$value = $this->getNestedValue($group, 'gruppe_kurzbz');
|
||||
if ($value !== '')
|
||||
$groups[] = $value;
|
||||
}
|
||||
}
|
||||
$groupLinks = $this->renderGroupLinks($groups);
|
||||
if ($groupLinks !== '')
|
||||
$parts[] = $groupLinks;
|
||||
|
||||
return implode('<br>', $parts);
|
||||
}
|
||||
|
||||
private function renderCreator($event)
|
||||
{
|
||||
if (isset($event->created_by) && (is_array($event->created_by) || is_object($event->created_by)))
|
||||
return $this->renderPeople(array($event->created_by), 'plain');
|
||||
|
||||
return $this->renderPeople(
|
||||
isset($event->lektor) ? $event->lektor : array(),
|
||||
'plain'
|
||||
);
|
||||
}
|
||||
|
||||
private function renderPeople(array $people, $linkType)
|
||||
{
|
||||
$values = array();
|
||||
$seen = array();
|
||||
foreach ($people as $person)
|
||||
{
|
||||
$uid = $this->getNestedValue($person, 'mitarbeiter_uid');
|
||||
if ($uid === '')
|
||||
$uid = $this->getNestedValue($person, 'uid');
|
||||
|
||||
$nameParts = array();
|
||||
foreach (array('titelpre', 'vorname', 'nachname', 'titelpost') as $property)
|
||||
{
|
||||
$value = trim($this->getNestedValue($person, $property));
|
||||
if ($value !== '')
|
||||
$nameParts[] = $value;
|
||||
}
|
||||
$name = implode(' ', $nameParts);
|
||||
if ($name === '')
|
||||
$name = $uid !== '' ? $uid : $this->getNestedValue($person, 'kurzbz');
|
||||
if ($name === '')
|
||||
continue;
|
||||
|
||||
$key = $uid !== '' ? $uid : $name;
|
||||
if (isset($seen[$key]))
|
||||
continue;
|
||||
$seen[$key] = true;
|
||||
|
||||
$label = $this->escape($name);
|
||||
if ($linkType === 'profile' && $uid !== '')
|
||||
{
|
||||
$personalNumber = $this->getNestedValue($person, 'personalnummer');
|
||||
$profileAllowed = $personalNumber === ''
|
||||
|| !is_numeric($personalNumber)
|
||||
|| (int)$personalNumber >= 0;
|
||||
if ($profileAllowed)
|
||||
$label = $this->link($this->getProfileUrl($uid), $label);
|
||||
}
|
||||
elseif ($linkType === 'mail' && $uid !== '' && defined('DOMAIN'))
|
||||
{
|
||||
$label = $this->link(
|
||||
'mailto:'.$uid.'@'.constant('DOMAIN'),
|
||||
$label
|
||||
);
|
||||
}
|
||||
|
||||
$values[] = $label;
|
||||
}
|
||||
|
||||
return implode('<br>', $values);
|
||||
}
|
||||
|
||||
private function renderRooms($event)
|
||||
{
|
||||
$values = array();
|
||||
$seen = array();
|
||||
if (isset($event->ort_details) && is_array($event->ort_details))
|
||||
{
|
||||
foreach ($event->ort_details as $room)
|
||||
{
|
||||
$code = $this->getNestedValue($room, 'ort_kurzbz');
|
||||
if ($code === '' || isset($seen[$code]))
|
||||
continue;
|
||||
$seen[$code] = true;
|
||||
|
||||
$label = $this->escape($code);
|
||||
$contentId = $this->getNestedValue($room, 'content_id');
|
||||
$title = $this->getNestedValue($room, 'bezeichnung');
|
||||
if ($contentId !== '')
|
||||
$label = $this->link($this->getRoomUrl($contentId), $label, $title);
|
||||
elseif ($title !== '')
|
||||
$label = '<span title="'.$this->escape($title).'">'.$label.'</span>';
|
||||
|
||||
$values[] = $label;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($event->ort_kurzbz) && is_array($event->ort_kurzbz))
|
||||
{
|
||||
foreach ($event->ort_kurzbz as $code)
|
||||
{
|
||||
$code = is_scalar($code) ? (string)$code : '';
|
||||
if ($code === '' || isset($seen[$code]))
|
||||
continue;
|
||||
$seen[$code] = true;
|
||||
$values[] = $this->escape($code);
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($event->locations) && is_array($event->locations))
|
||||
{
|
||||
foreach ($event->locations as $location)
|
||||
{
|
||||
$location = is_scalar($location) ? trim((string)$location) : '';
|
||||
if ($location !== '' && !isset($seen['location:'.$location]))
|
||||
{
|
||||
$seen['location:'.$location] = true;
|
||||
$values[] = $this->escape($location);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return implode('<br>', $values);
|
||||
}
|
||||
|
||||
private function renderGroupLinks(array $groups)
|
||||
{
|
||||
$values = array();
|
||||
foreach ($this->uniqueScalarValues($groups) as $group)
|
||||
{
|
||||
$label = $this->escape($group);
|
||||
if (defined('DOMAIN'))
|
||||
{
|
||||
$label = $this->link(
|
||||
'mailto:'.mb_strtolower($group).'@'.constant('DOMAIN'),
|
||||
$label
|
||||
);
|
||||
}
|
||||
$values[] = $label;
|
||||
}
|
||||
|
||||
return implode('<br>', $values);
|
||||
}
|
||||
|
||||
private function renderScalarLines($values)
|
||||
{
|
||||
if (!is_array($values))
|
||||
$values = array($values);
|
||||
|
||||
$escaped = array_map(array($this, 'escape'), $this->uniqueScalarValues($values));
|
||||
return implode('<br>', $escaped);
|
||||
}
|
||||
|
||||
private function uniqueScalarValues(array $values)
|
||||
{
|
||||
$result = array();
|
||||
$seen = array();
|
||||
foreach ($values as $value)
|
||||
{
|
||||
if (!is_scalar($value))
|
||||
continue;
|
||||
$value = trim((string)$value);
|
||||
if ($value === '' || isset($seen[$value]))
|
||||
continue;
|
||||
$seen[$value] = true;
|
||||
$result[] = $value;
|
||||
}
|
||||
|
||||
sort($result, SORT_STRING | SORT_FLAG_CASE);
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function renderDescription($event)
|
||||
{
|
||||
$values = array();
|
||||
foreach (array('titel', 'beschreibung') as $property)
|
||||
{
|
||||
$value = trim($this->getScalar($event, $property));
|
||||
if ($value !== '')
|
||||
$values[] = $this->renderText($value);
|
||||
}
|
||||
|
||||
return implode('<br>', array_unique($values));
|
||||
}
|
||||
|
||||
private function renderText($value)
|
||||
{
|
||||
return nl2br($this->escape($value), false);
|
||||
}
|
||||
|
||||
private function getEventTitle($event)
|
||||
{
|
||||
foreach (array('titel', 'lehrfach_bez', 'lehrfach') as $property)
|
||||
{
|
||||
$value = trim($this->getScalar($event, $property));
|
||||
if ($value !== '')
|
||||
return $value;
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
private function getEventDateTime($event, $isoProperty, $dateProperty, $timeProperty)
|
||||
{
|
||||
$value = isset($event->{$isoProperty}) ? $event->{$isoProperty} : null;
|
||||
if (($value === null || $value === '')
|
||||
&& isset($event->{$dateProperty})
|
||||
&& isset($event->{$timeProperty}))
|
||||
{
|
||||
$value = $event->{$dateProperty}.' '.$event->{$timeProperty};
|
||||
}
|
||||
|
||||
if ($value === null || $value === '')
|
||||
return null;
|
||||
|
||||
try
|
||||
{
|
||||
$date = is_numeric($value)
|
||||
? new DateTime('@'.(int)$value)
|
||||
: new DateTime($value, new DateTimeZone(self::TIMEZONE));
|
||||
$date->setTimezone(new DateTimeZone(self::TIMEZONE));
|
||||
return $date;
|
||||
}
|
||||
catch (Exception $exception)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private function normalizeTime($time)
|
||||
{
|
||||
$time = (string)$time;
|
||||
if (preg_match('/^(\d{1,2}:\d{2}:\d{2})(?:\.\d+)?$/', $time, $matches))
|
||||
return $matches[1];
|
||||
if (preg_match('/^\d{1,2}:\d{2}$/', $time))
|
||||
return $time.':00';
|
||||
|
||||
return $time;
|
||||
}
|
||||
|
||||
private function formatDate($datum)
|
||||
{
|
||||
$date = DateTime::createFromFormat(
|
||||
'!Y-m-d',
|
||||
$datum,
|
||||
new DateTimeZone(self::TIMEZONE)
|
||||
);
|
||||
return $date === false ? $datum : $date->format('d.m.Y');
|
||||
}
|
||||
|
||||
private function getScalar($object, $property)
|
||||
{
|
||||
return isset($object->{$property}) && is_scalar($object->{$property})
|
||||
? (string)$object->{$property}
|
||||
: '';
|
||||
}
|
||||
|
||||
private function getNestedValue($value, $property)
|
||||
{
|
||||
if (is_array($value) && isset($value[$property]) && is_scalar($value[$property]))
|
||||
return (string)$value[$property];
|
||||
if (is_object($value) && isset($value->{$property}) && is_scalar($value->{$property}))
|
||||
return (string)$value->{$property};
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
private function cell($content)
|
||||
{
|
||||
return '<td class="detail-lines">'.$content.'</td>';
|
||||
}
|
||||
|
||||
private function link($url, $escapedLabel, $title = '')
|
||||
{
|
||||
$html = '<a href="'.$this->escape($url).'"';
|
||||
if ($title !== '')
|
||||
$html .= ' title="'.$this->escape($title).'"';
|
||||
return $html.'>'.$escapedLabel.'</a>';
|
||||
}
|
||||
|
||||
private function getProfileUrl($uid)
|
||||
{
|
||||
return $this->getAppRoot().'cis/private/profile/index.php?'
|
||||
.http_build_query(array('uid' => $uid), '', '&', PHP_QUERY_RFC3986);
|
||||
}
|
||||
|
||||
private function getRoomUrl($contentId)
|
||||
{
|
||||
return $this->getAppRoot().'cms/content.php?'
|
||||
.http_build_query(
|
||||
array('content_id' => $contentId),
|
||||
'',
|
||||
'&',
|
||||
PHP_QUERY_RFC3986
|
||||
);
|
||||
}
|
||||
|
||||
private function phrase($category, $phrase, array $parameters = array())
|
||||
{
|
||||
if (($category === 'global' && $phrase === 'termine')
|
||||
|| ($category === 'ui'
|
||||
&& in_array($phrase, array('organisierende', 'teilnehmende'), true)))
|
||||
{
|
||||
return $this->ci->p->t($category, $phrase, $parameters);
|
||||
}
|
||||
|
||||
return $this->legacyPhrases->t($category.'/'.$phrase, $parameters);
|
||||
}
|
||||
|
||||
private function escape($value)
|
||||
{
|
||||
return htmlspecialchars((string)$value, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
|
||||
}
|
||||
|
||||
private function getAppRoot()
|
||||
{
|
||||
return defined('APP_ROOT') ? rtrim(APP_ROOT, '/').'/' : '/';
|
||||
}
|
||||
}
|
||||
@@ -9,8 +9,6 @@ class LvPlanHTMLLib
|
||||
const DETAIL_WINDOW_NAME = 'Details';
|
||||
const DETAIL_WINDOW_OPTIONS = 'height=320,width=550,left=0,top=0,hotkeys=0,resizable=yes,status=no,scrollbars=no,toolbar=no,location=no,menubar=no,dependent=yes';
|
||||
|
||||
const ICON_EXAM = '📝';
|
||||
|
||||
private $ci;
|
||||
|
||||
public function __construct()
|
||||
@@ -188,9 +186,6 @@ class LvPlanHTMLLib
|
||||
$title = $this->getScalar($event, 'titel');
|
||||
} else {
|
||||
$title = $this->joinValue(isset($event->topic) ? $event->topic : '');
|
||||
|
||||
if ($title !== '' && strtoupper($event->lehrform) === 'EXAM')
|
||||
$title = $title . ' ' . self::ICON_EXAM;
|
||||
}
|
||||
|
||||
if ($title === '')
|
||||
@@ -542,7 +537,7 @@ class LvPlanHTMLLib
|
||||
'ort_kurzbz' => $room
|
||||
);
|
||||
|
||||
return $this->getAppRoot().'cis/private/lvplan/stpl_detail.php?'
|
||||
return $this->getAppRoot().'index.ci.php/lvplan/html/detail?'
|
||||
.http_build_query($parameters, '', '&', PHP_QUERY_RFC3986);
|
||||
}
|
||||
|
||||
|
||||
@@ -593,7 +593,6 @@ class wochenplan extends basis_db
|
||||
echo ' <A href="'.APP_ROOT.'index.ci.php/lvplan/excel/download?'.htmlspecialchars($kal_link_new_ws, ENT_QUOTES, 'UTF-8').'" title="excel-new">excel-new</A> '.$this->crlf;
|
||||
echo ' <A href="'.APP_ROOT.'index.ci.php/lvplan/csv/download?'.htmlspecialchars($kal_link_new_ws, ENT_QUOTES, 'UTF-8').'" title="CSV-new">CSV-new</A> '.$this->crlf;
|
||||
echo ' <A href="'.APP_ROOT.'index.ci.php/lvplan/csv/download?'.htmlspecialchars($kal_link_new_ws, ENT_QUOTES, 'UTF-8').'&target=outlook" title="CSV-Outlook-new">CSV-Outlook-new</A> '.$this->crlf;
|
||||
echo ' <A href="'.APP_ROOT.'index.ci.php/lvplan/ical/download?'.htmlspecialchars($kal_link_new_ws, ENT_QUOTES, 'UTF-8').'&version=1" title="iCal Version 1.0-new">iCal1-new</A> '.$this->crlf;
|
||||
echo ' <A href="'.APP_ROOT.'index.ci.php/lvplan/ical/download?'.htmlspecialchars($kal_link_new_ws, ENT_QUOTES, 'UTF-8').'&version=2" title="iCal Version 2.0-new">iCal2-new</A>'.$this->crlf;
|
||||
}
|
||||
}
|
||||
@@ -614,7 +613,6 @@ class wochenplan extends basis_db
|
||||
echo ' <A href="'.APP_ROOT.'index.ci.php/lvplan/excel/download?'.htmlspecialchars($kal_link_new_ss, ENT_QUOTES, 'UTF-8').'" title="excel-new">excel-new</A> '.$this->crlf;
|
||||
echo ' <A href="'.APP_ROOT.'index.ci.php/lvplan/csv/download?'.htmlspecialchars($kal_link_new_ss, ENT_QUOTES, 'UTF-8').'" title="CSV-new">CSV-new</A> '.$this->crlf;
|
||||
echo ' <A href="'.APP_ROOT.'index.ci.php/lvplan/csv/download?'.htmlspecialchars($kal_link_new_ss, ENT_QUOTES, 'UTF-8').'&target=outlook" title="CSV-Outlook-new">CSV-Outlook-new</A> '.$this->crlf;
|
||||
echo ' <A href="'.APP_ROOT.'index.ci.php/lvplan/ical/download?'.htmlspecialchars($kal_link_new_ss, ENT_QUOTES, 'UTF-8').'&version=1" title="iCal Version 1.0-new">iCal1-new</A> '.$this->crlf;
|
||||
echo ' <A href="'.APP_ROOT.'index.ci.php/lvplan/ical/download?'.htmlspecialchars($kal_link_new_ss, ENT_QUOTES, 'UTF-8').'&version=2" title="iCal Version 2.0-new">iCal2-new</A>'.$this->crlf;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user