mirror of
https://github.com/FH-Complete/FHC-Core.git
synced 2026-07-26 09:04:28 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a78fc177a5 | ||
|
|
4c1d88a054 | ||
|
|
280df46d6d | ||
|
|
3e17e99ce9 | ||
|
|
790d0d99ec | ||
|
|
5499c522cb | ||
|
|
ac5478f176 |
@@ -119,6 +119,10 @@ $route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/prestudent/(:num)'] = 'a
|
||||
// // (studiensemester_kurzbz)/person/(person_id)
|
||||
$route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/person/(:num)'] = 'api/frontend/v1/stv/Students/getPerson/$1/$2';
|
||||
|
||||
|
||||
$route['lvplan/caldav'] = 'LvPlanCalDAV';
|
||||
$route['lvplan/caldav/.*'] = 'LvPlanCalDAV';
|
||||
|
||||
// load routes from extensions, also look for environment-specific configs
|
||||
$subdirs = ['application/config/extensions', 'application/config/' . ENVIRONMENT . '/extensions'];
|
||||
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
if (! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
|
||||
/**
|
||||
*/
|
||||
class LvPlanCalDAV extends FHC_Controller
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->load->library('sabredav/SabreDAVAuthLib');
|
||||
$this->load->library('sabredav/SabreDAVCalDAVLib');
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
// Public methods
|
||||
public function index()
|
||||
{
|
||||
|
||||
$authBackend = new SabreDAVAuthLib();
|
||||
$principalBackend = new SabreDAVACLPrincipalBackend($authBackend);
|
||||
$calendarBackend = new SabreDAVCalDAVBackend($authBackend);
|
||||
|
||||
$tree = array(
|
||||
new \Sabre\CalDAV\Principal\Collection($principalBackend),
|
||||
new \Sabre\CalDAV\CalendarRoot($principalBackend, $calendarBackend)
|
||||
);
|
||||
|
||||
$server = new \Sabre\DAV\Server($tree);
|
||||
|
||||
$baseUri = '/' . implode('/', array_filter([
|
||||
trim(BASE_LOCATION, '/'),
|
||||
trim($this->config->item('index_page'), '/'),
|
||||
'lvplan',
|
||||
'caldav'
|
||||
]));
|
||||
$server->setBaseUri($baseUri);
|
||||
|
||||
$authBackend->setRealm('SabreDAV');
|
||||
$authPlugin = new \Sabre\DAV\Auth\Plugin($authBackend);
|
||||
$server->addPlugin($authPlugin);
|
||||
|
||||
$caldavPlugin = new \Sabre\CalDAV\Plugin();
|
||||
$server->addPlugin($caldavPlugin);
|
||||
|
||||
$aclPlugin = new \Sabre\DAVACL\Plugin();
|
||||
$server->addPlugin($aclPlugin);
|
||||
|
||||
$browser = new \Sabre\DAV\Browser\Plugin();
|
||||
$server->addPlugin($browser);
|
||||
|
||||
$server->exec();
|
||||
}
|
||||
}
|
||||
@@ -38,8 +38,8 @@ class Kalender extends FHCAPI_Controller
|
||||
|
||||
$this->_ci->load->library('LogLib');
|
||||
$this->_ci->load->library('form_validation');
|
||||
$this->_ci->load->library('KalenderLib');
|
||||
$this->_ci->load->library('RaumvorschlagLib');
|
||||
$this->_ci->load->library('KalenderLib', ["uid" => getAuthUID()]);
|
||||
$this->_ci->load->library('RaumvorschlagLib', ["uid" => getAuthUID()]);
|
||||
$this->loadPhrases([
|
||||
'ui'
|
||||
]);
|
||||
|
||||
@@ -18,8 +18,8 @@ class OperationalResourceToCalenderAPI extends FHCAPI_Controller
|
||||
$this->load->model('ressource/Betriebsmittel_model', 'BetriebsmittelModel');
|
||||
$this->load->model('ressource/Kalender_model', 'KalenderModel');
|
||||
|
||||
$this->load->library('CollisionChecker');
|
||||
$this->load->library('KalenderLib');
|
||||
$this->_ci->load->library('CollisionChecker', ["uid" => getAuthUID()]);
|
||||
$this->_ci->load->library('KalenderLib', ["uid" => getAuthUID()]);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -22,7 +22,7 @@ class Reservierung extends FHCAPI_Controller
|
||||
|
||||
$this->_ci->load->library('LogLib');
|
||||
$this->_ci->load->library('form_validation');
|
||||
$this->_ci->load->library('KalenderLib');
|
||||
$this->_ci->load->library('KalenderLib', ["uid" => getAuthUID()]);
|
||||
|
||||
$this->_ci->load->model('ressource/Ort_model', 'OrtModel');
|
||||
$this->_ci->load->model('ressource/Kalender_Event_Rolle_model', 'KalenderEventRolleModel');
|
||||
|
||||
@@ -13,7 +13,7 @@ class TempusJob extends JOB_Controller
|
||||
$this->_ci =& get_instance();
|
||||
|
||||
$this->_ci->load->helper('hlp_sancho_helper');
|
||||
$this->_ci->load->library('KalenderLib');
|
||||
$this->_ci->load->library('KalenderLib', ["uid" => null]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -9,16 +9,23 @@ class CollisionChecker
|
||||
private $_checks = [];
|
||||
|
||||
private $_ci;
|
||||
private $_uid;
|
||||
|
||||
public function __construct()
|
||||
public function __construct($params)
|
||||
{
|
||||
$this->_ci =& get_instance();
|
||||
|
||||
$this->_ci->load->library('collision/checks/RoomCollisionCheck');
|
||||
$this->_ci->load->library('collision/checks/LectureCollisionCheck');
|
||||
$this->_ci->load->library('collision/checks/VerbandCollisionCheck');
|
||||
$this->_ci->load->library('collision/checks/StudentCollisionCheck');
|
||||
$this->_ci->load->library('collision/checks/ResourcesCollisionCheck');
|
||||
if (isset($params['uid']) && !isEmptyString($params['uid'])){
|
||||
$this->_uid = $params['uid'];
|
||||
} else {
|
||||
show_error('uid of logged user not passed!');
|
||||
}
|
||||
|
||||
$this->_ci->load->library('collision/checks/RoomCollisionCheck', ['uid' => $this->_uid]);
|
||||
$this->_ci->load->library('collision/checks/LectureCollisionCheck', ['uid' => $this->_uid]);
|
||||
$this->_ci->load->library('collision/checks/VerbandCollisionCheck', ['uid' => $this->_uid]);
|
||||
$this->_ci->load->library('collision/checks/StudentCollisionCheck', ['uid' => $this->_uid]);
|
||||
$this->_ci->load->library('collision/checks/ResourcesCollisionCheck', ['uid' => $this->_uid]);
|
||||
$this->register($this->_ci->roomcollisioncheck);
|
||||
$this->register($this->_ci->lecturecollisioncheck);
|
||||
$this->register($this->_ci->verbandcollisioncheck);
|
||||
@@ -64,4 +71,4 @@ class CollisionChecker
|
||||
|
||||
return $results;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,9 +5,17 @@ if (! defined("BASEPATH")) exit("No direct script access allowed");
|
||||
class KalenderLib
|
||||
{
|
||||
private $_ci;
|
||||
public function __construct()
|
||||
private $_uid;
|
||||
|
||||
public function __construct($params)
|
||||
{
|
||||
$this->_ci =& get_instance();
|
||||
|
||||
if (isset($params['uid']) && !isEmptyString($params['uid'])){
|
||||
$this->_uid = $params['uid'];
|
||||
} else {
|
||||
show_error('uid of logged user not passed!');
|
||||
}
|
||||
|
||||
$this->_ci->load->model('ressource/Kalender_model', 'KalenderModel');
|
||||
$this->_ci->load->model('ressource/Kalender_Lehreinheit_model', 'KalenderLehreinheitModel');
|
||||
@@ -22,7 +30,7 @@ class KalenderLib
|
||||
$this->_ci->load->model('organisation/gruppe_model', 'GruppeModel');
|
||||
$this->_ci->load->model('organisation/Lehrverband_model', 'LehrverbandModel');
|
||||
|
||||
$this->_ci->load->library('CollisionChecker');
|
||||
$this->_ci->load->library('CollisionChecker', ['uid' => $this->_uid]);
|
||||
$this->_ci->load->library('PhrasesLib', array('ui'));
|
||||
|
||||
}
|
||||
@@ -38,6 +46,8 @@ class KalenderLib
|
||||
tbl_kalender.von,
|
||||
tbl_kalender.bis,
|
||||
tbl_kalender_ort.ort_kurzbz,
|
||||
tbl_kalender_ort.ort_kurzbz as ko_ort_kurzbz,
|
||||
tbl_kalender_ort.location as ko_location,
|
||||
tbl_lehreinheit.lehreinheit_id,
|
||||
tbl_lehreinheit.lehrveranstaltung_id,
|
||||
tbl_lehreinheit.lehrfach_id,
|
||||
@@ -165,6 +175,8 @@ class KalenderLib
|
||||
'tooltip' => 'tip',
|
||||
'status_kurzbz' => $row->status_kurzbz,
|
||||
'ort_kurzbz' => isset($row->ort_kurzbz) ? $row->ort_kurzbz : '',
|
||||
'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 : '',
|
||||
@@ -180,7 +192,8 @@ class KalenderLib
|
||||
'beschreibung' => isset($row->beschreibung) ? $row->beschreibung : '',
|
||||
'topic' => (isset($row->lehrfach_kurzbz) ? $row->lehrfach_kurzbz : '').' '.(isset($row->lehrform_kurzbz) ? $row->lehrform_kurzbz : ''),
|
||||
'collisions' => false,
|
||||
'has_assigned_resources' => isset($row->has_assigned_resources) ? $row->has_assigned_resources : false
|
||||
'has_assigned_resources' => isset($row->has_assigned_resources) ? $row->has_assigned_resources : false,
|
||||
'updateamum' => isset($row->updateamum) ? $row->updateamum : null,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -376,6 +389,131 @@ class KalenderLib
|
||||
return $this->_mapEvents($data);
|
||||
}
|
||||
|
||||
public function getPlanForStudentByStudent($start_date, $end_date, $userUID)
|
||||
{
|
||||
$this->_getBasePlan($start_date, $end_date);
|
||||
|
||||
$escapedUserUID = $this->_ci->KalenderModel->db->escape($userUID);
|
||||
|
||||
$benutzerExists = "EXISTS (
|
||||
SELECT 1
|
||||
FROM public.tbl_benutzer student_benutzer
|
||||
WHERE student_benutzer.uid = $escapedUserUID
|
||||
)";
|
||||
|
||||
$directEventTeilnehmerExists = "EXISTS (
|
||||
SELECT 1
|
||||
FROM lehre.tbl_kalender_event_teilnehmer event_teilnehmer
|
||||
WHERE event_teilnehmer.kalender_id = tbl_kalender.kalender_id
|
||||
AND event_teilnehmer.uid = $escapedUserUID
|
||||
)";
|
||||
|
||||
$eventBenutzergruppeExists = "EXISTS (
|
||||
SELECT 1
|
||||
FROM lehre.tbl_kalender_event_teilnehmer event_gruppe
|
||||
JOIN public.tbl_benutzergruppe event_benutzergruppe
|
||||
ON event_benutzergruppe.gruppe_kurzbz = event_gruppe.gruppe_kurzbz
|
||||
AND (
|
||||
event_gruppe.studiensemester_kurzbz IS NULL
|
||||
OR event_benutzergruppe.studiensemester_kurzbz = event_gruppe.studiensemester_kurzbz
|
||||
)
|
||||
WHERE event_gruppe.kalender_id = tbl_kalender.kalender_id
|
||||
AND event_gruppe.gruppe_kurzbz IS NOT NULL
|
||||
AND event_benutzergruppe.uid = $escapedUserUID
|
||||
)";
|
||||
|
||||
$eventStudentlehrverbandExists = "EXISTS (
|
||||
SELECT 1
|
||||
FROM lehre.tbl_kalender_event_teilnehmer event_lehrverband
|
||||
JOIN public.tbl_studentlehrverband event_studentlehrverband
|
||||
ON event_studentlehrverband.student_uid = $escapedUserUID
|
||||
AND event_studentlehrverband.studiengang_kz = event_lehrverband.studiengang_kz
|
||||
AND (
|
||||
event_lehrverband.studiensemester_kurzbz IS NULL
|
||||
OR event_studentlehrverband.studiensemester_kurzbz = event_lehrverband.studiensemester_kurzbz
|
||||
)
|
||||
AND (
|
||||
event_lehrverband.semester IS NULL
|
||||
OR event_studentlehrverband.semester = event_lehrverband.semester
|
||||
)
|
||||
AND (
|
||||
event_lehrverband.verband = event_studentlehrverband.verband
|
||||
OR event_lehrverband.verband IS NULL
|
||||
OR btrim(event_lehrverband.verband::text) = ''
|
||||
OR event_studentlehrverband.verband IS NULL
|
||||
)
|
||||
AND (
|
||||
event_lehrverband.gruppe = event_studentlehrverband.gruppe
|
||||
OR event_lehrverband.gruppe IS NULL
|
||||
OR btrim(event_lehrverband.gruppe::text) = ''
|
||||
OR event_studentlehrverband.gruppe IS NULL
|
||||
)
|
||||
WHERE event_lehrverband.kalender_id = tbl_kalender.kalender_id
|
||||
AND event_lehrverband.gruppe_kurzbz IS NULL
|
||||
AND event_lehrverband.studiengang_kz IS NOT NULL
|
||||
)";
|
||||
|
||||
$lehreinheitBenutzergruppeExists = "EXISTS (
|
||||
SELECT 1
|
||||
FROM lehre.tbl_kalender_lehreinheit student_kalender_lehreinheit
|
||||
JOIN lehre.tbl_lehreinheit student_lehreinheit
|
||||
ON student_lehreinheit.lehreinheit_id = student_kalender_lehreinheit.lehreinheit_id
|
||||
JOIN lehre.tbl_lehreinheitgruppe student_lehreinheitgruppe
|
||||
ON student_lehreinheitgruppe.lehreinheit_id = student_lehreinheit.lehreinheit_id
|
||||
JOIN public.tbl_gruppe student_gruppe
|
||||
ON student_gruppe.studiengang_kz = student_lehreinheitgruppe.studiengang_kz
|
||||
AND student_gruppe.semester = student_lehreinheitgruppe.semester
|
||||
AND student_gruppe.gruppe_kurzbz = student_lehreinheitgruppe.gruppe_kurzbz
|
||||
JOIN public.tbl_benutzergruppe student_benutzergruppe
|
||||
ON student_benutzergruppe.gruppe_kurzbz = student_gruppe.gruppe_kurzbz
|
||||
AND student_benutzergruppe.studiensemester_kurzbz = student_lehreinheit.studiensemester_kurzbz
|
||||
WHERE student_kalender_lehreinheit.kalender_id = tbl_kalender.kalender_id
|
||||
AND student_lehreinheitgruppe.gruppe_kurzbz IS NOT NULL
|
||||
AND student_benutzergruppe.uid = $escapedUserUID
|
||||
)";
|
||||
|
||||
$lehreinheitStudentlehrverbandExists = "EXISTS (
|
||||
SELECT 1
|
||||
FROM lehre.tbl_kalender_lehreinheit student_kalender_lehreinheit
|
||||
JOIN lehre.tbl_lehreinheit student_lehreinheit
|
||||
ON student_lehreinheit.lehreinheit_id = student_kalender_lehreinheit.lehreinheit_id
|
||||
JOIN lehre.tbl_lehreinheitgruppe student_lehreinheitgruppe
|
||||
ON student_lehreinheitgruppe.lehreinheit_id = student_lehreinheit.lehreinheit_id
|
||||
JOIN public.tbl_studentlehrverband student_lehrverband
|
||||
ON student_lehrverband.student_uid = $escapedUserUID
|
||||
AND student_lehrverband.studiengang_kz = student_lehreinheitgruppe.studiengang_kz
|
||||
AND student_lehrverband.semester = student_lehreinheitgruppe.semester
|
||||
AND student_lehrverband.studiensemester_kurzbz = student_lehreinheit.studiensemester_kurzbz
|
||||
AND (
|
||||
student_lehreinheitgruppe.verband = student_lehrverband.verband
|
||||
OR student_lehreinheitgruppe.verband IS NULL
|
||||
OR btrim(student_lehreinheitgruppe.verband::text) = ''
|
||||
OR student_lehrverband.verband IS NULL
|
||||
)
|
||||
AND (
|
||||
student_lehreinheitgruppe.gruppe = student_lehrverband.gruppe
|
||||
OR student_lehreinheitgruppe.gruppe IS NULL
|
||||
OR btrim(student_lehreinheitgruppe.gruppe::text) = ''
|
||||
OR student_lehrverband.gruppe IS NULL
|
||||
)
|
||||
WHERE student_kalender_lehreinheit.kalender_id = tbl_kalender.kalender_id
|
||||
AND student_lehreinheitgruppe.gruppe_kurzbz IS NULL
|
||||
)";
|
||||
|
||||
$this->_ci->KalenderModel->db->where('status_kurzbz', 'live');
|
||||
$this->_ci->KalenderModel->db->where($benutzerExists, null, false);
|
||||
$this->_ci->KalenderModel->db->group_start();
|
||||
$this->_ci->KalenderModel->db->where($directEventTeilnehmerExists, null, false);
|
||||
$this->_ci->KalenderModel->db->or_where($eventBenutzergruppeExists, null, false);
|
||||
$this->_ci->KalenderModel->db->or_where($eventStudentlehrverbandExists, null, false);
|
||||
$this->_ci->KalenderModel->db->or_where($lehreinheitBenutzergruppeExists, null, false);
|
||||
$this->_ci->KalenderModel->db->or_where($lehreinheitStudentlehrverbandExists, null, false);
|
||||
$this->_ci->KalenderModel->db->group_end();
|
||||
|
||||
$data = $this->_ci->KalenderModel->load();
|
||||
|
||||
return $this->_mapEvents($data);
|
||||
}
|
||||
|
||||
public function getPlanForLecturer($start_date, $end_date)
|
||||
{
|
||||
@@ -395,6 +533,57 @@ class KalenderLib
|
||||
|
||||
return $this->_mapEvents($data);
|
||||
}
|
||||
|
||||
public function getPlanForLecturerByLecturer($start_date, $end_date, $userUID)
|
||||
{
|
||||
$this->_getBasePlan($start_date, $end_date);
|
||||
|
||||
$escapedUserUID = $this->_ci->KalenderModel->db->escape($userUID);
|
||||
|
||||
$lehreinheitMitarbeiterExists = "EXISTS (
|
||||
SELECT 1
|
||||
FROM lehre.tbl_kalender_lehreinheit lecturer_kalender_lehreinheit
|
||||
JOIN lehre.tbl_lehreinheit lecturer_lehreinheit
|
||||
ON lecturer_lehreinheit.lehreinheit_id = lecturer_kalender_lehreinheit.lehreinheit_id
|
||||
JOIN lehre.tbl_lehreinheitmitarbeiter lecturer_lehreinheitmitarbeiter
|
||||
ON lecturer_lehreinheitmitarbeiter.lehreinheit_id = lecturer_lehreinheit.lehreinheit_id
|
||||
WHERE lecturer_kalender_lehreinheit.kalender_id = tbl_kalender.kalender_id
|
||||
AND lecturer_lehreinheitmitarbeiter.mitarbeiter_uid = $escapedUserUID
|
||||
)";
|
||||
|
||||
$eventTeilnehmerExists = "EXISTS (
|
||||
SELECT 1
|
||||
FROM lehre.tbl_kalender_event_teilnehmer lecturer_event_teilnehmer
|
||||
WHERE lecturer_event_teilnehmer.kalender_id = tbl_kalender.kalender_id
|
||||
AND lecturer_event_teilnehmer.uid = $escapedUserUID
|
||||
)";
|
||||
|
||||
$eventBenutzergruppeExists = "EXISTS (
|
||||
SELECT 1
|
||||
FROM lehre.tbl_kalender_event_teilnehmer lecturer_event_gruppe
|
||||
JOIN public.tbl_benutzergruppe lecturer_benutzergruppe
|
||||
ON lecturer_benutzergruppe.gruppe_kurzbz = lecturer_event_gruppe.gruppe_kurzbz
|
||||
AND (
|
||||
lecturer_event_gruppe.studiensemester_kurzbz IS NULL
|
||||
OR lecturer_benutzergruppe.studiensemester_kurzbz = lecturer_event_gruppe.studiensemester_kurzbz
|
||||
)
|
||||
WHERE lecturer_event_gruppe.kalender_id = tbl_kalender.kalender_id
|
||||
AND lecturer_event_gruppe.gruppe_kurzbz IS NOT NULL
|
||||
AND lecturer_benutzergruppe.uid = $escapedUserUID
|
||||
)";
|
||||
|
||||
$this->_ci->KalenderModel->db->where('tbl_kalender.status_kurzbz', 'live');
|
||||
$this->_ci->KalenderModel->db->group_start();
|
||||
$this->_ci->KalenderModel->db->where($lehreinheitMitarbeiterExists, null, false);
|
||||
$this->_ci->KalenderModel->db->or_where($eventTeilnehmerExists, null, false);
|
||||
$this->_ci->KalenderModel->db->or_where($eventBenutzergruppeExists, null, false);
|
||||
$this->_ci->KalenderModel->db->group_end();
|
||||
|
||||
$data = $this->_ci->KalenderModel->load();
|
||||
|
||||
return $this->_mapEvents($data);
|
||||
}
|
||||
|
||||
public function getZeitsperren($start_date, $end_date, $emp)
|
||||
{
|
||||
$db = new DB_Model();
|
||||
@@ -593,6 +782,7 @@ class KalenderLib
|
||||
'bis' => $end_date,
|
||||
'typ' => 'reservierung',
|
||||
'status_kurzbz' => 'live',
|
||||
'eindeutige_gruppen_id' => $this->_ci->KalenderModel->generateUniqueGroupId(),
|
||||
'insertvon' => getAuthUID(),
|
||||
'insertamum' => date('Y-m-d H:i:s')
|
||||
)
|
||||
|
||||
@@ -7,10 +7,18 @@ use CI3_Events as Events;
|
||||
class RaumvorschlagLib
|
||||
{
|
||||
private $_ci;
|
||||
public function __construct()
|
||||
private $_uid;
|
||||
|
||||
public function __construct($params)
|
||||
{
|
||||
$this->_ci =& get_instance();
|
||||
|
||||
if (isset($params['uid']) && !isEmptyString($params['uid'])){
|
||||
$this->_uid = $params['uid'];
|
||||
} else {
|
||||
show_error('uid of logged user not passed!');
|
||||
}
|
||||
|
||||
$this->_ci->load->model('ressource/Kalender_model', 'KalenderModel');
|
||||
$this->_ci->load->model('ressource/Kalender_Lehreinheit_model', 'KalenderLehreinheitModel');
|
||||
$this->_ci->load->model('ressource/Kalender_Event_model', 'KalenderEventModel');
|
||||
@@ -26,8 +34,8 @@ class RaumvorschlagLib
|
||||
$this->_ci->load->model('education/Lehreinheitgruppe_model', 'LehreinheitgruppeModel');
|
||||
$this->_ci->load->model('education/Lehreinheitgruppe_model', 'LehreinheitgruppeModel');
|
||||
|
||||
$this->_ci->load->library('CollisionChecker');
|
||||
$this->_ci->load->library('KalenderLib');
|
||||
$this->_ci->load->library('CollisionChecker', ["uid" => getAuthUID()]);
|
||||
$this->_ci->load->library('KalenderLib', ["uid" => getAuthUID()]);
|
||||
$this->_ci->load->library('PhrasesLib', array('ui'));
|
||||
}
|
||||
|
||||
|
||||
@@ -14,9 +14,9 @@ class VariableLib
|
||||
/**
|
||||
* VariableLib constructor.
|
||||
* Loads variable of logged in user.
|
||||
* @param $loggeduid
|
||||
* @param $params
|
||||
*/
|
||||
public function __construct($loggeduid)
|
||||
public function __construct($params)
|
||||
{
|
||||
$this->_ci =& get_instance();
|
||||
|
||||
@@ -25,8 +25,8 @@ class VariableLib
|
||||
$this->_ci->load->model('system/Variable_model', 'VariableModel');
|
||||
$this->_ci->load->model('organisation/studiensemester_model', 'StudiensemesterModel');
|
||||
|
||||
if (isset($loggeduid['uid']) && !isEmptyString($loggeduid['uid']))
|
||||
$this->_setVariables($loggeduid['uid']);
|
||||
if (isset($params['uid']) && !isEmptyString($params['uid']))
|
||||
$this->_setVariables($params['uid']);
|
||||
else
|
||||
{
|
||||
show_error('uid of logged user not passed!');
|
||||
|
||||
@@ -4,13 +4,21 @@ class LectureCollisionCheck implements ICollisionCheck
|
||||
{
|
||||
|
||||
private $_ci;
|
||||
private $_uid;
|
||||
|
||||
public function __construct()
|
||||
public function __construct($params)
|
||||
{
|
||||
$this->_ci =& get_instance();
|
||||
|
||||
if (isset($params['uid']) && !isEmptyString($params['uid'])){
|
||||
$this->_uid = $params['uid'];
|
||||
} else {
|
||||
show_error('uid of logged user not passed!');
|
||||
}
|
||||
|
||||
$this->_ci->load->model('ressource/Kalender_model', 'KalenderModel');
|
||||
$this->_ci->load->model('ressource/zeitsperre_model', 'ZeitsperreModel');
|
||||
$this->_ci->load->library('VariableLib', array('uid' => getAuthUID()));
|
||||
$this->_ci->load->library('VariableLib', ['uid' => $this->_uid]);
|
||||
$this->_ci->load->library('PhrasesLib', array('ui'));
|
||||
|
||||
}
|
||||
@@ -255,4 +263,4 @@ class LectureCollisionCheck implements ICollisionCheck
|
||||
}, getData($result));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,12 +4,20 @@ class ResourcesCollisionCheck implements ICollisionCheck
|
||||
{
|
||||
|
||||
private $_ci;
|
||||
private $_uid;
|
||||
|
||||
public function __construct()
|
||||
public function __construct($params)
|
||||
{
|
||||
$this->_ci =& get_instance();
|
||||
|
||||
if (isset($params['uid']) && !isEmptyString($params['uid'])){
|
||||
$this->_uid = $params['uid'];
|
||||
} else {
|
||||
show_error('uid of logged user not passed!');
|
||||
}
|
||||
|
||||
$this->_ci->load->model('ressource/Kalender_model', 'KalenderModel');
|
||||
$this->_ci->load->library('VariableLib', array('uid' => getAuthUID()));
|
||||
$this->_ci->load->library('VariableLib', array('uid' => $this->_uid));
|
||||
$this->_ci->load->library('PhrasesLib', array('ui'));
|
||||
}
|
||||
|
||||
@@ -82,4 +90,4 @@ class ResourcesCollisionCheck implements ICollisionCheck
|
||||
|
||||
return $grouped;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,12 +4,20 @@ class RoomCollisionCheck implements ICollisionCheck
|
||||
{
|
||||
|
||||
private $_ci;
|
||||
private $_uid;
|
||||
|
||||
public function __construct()
|
||||
public function __construct($params)
|
||||
{
|
||||
$this->_ci =& get_instance();
|
||||
|
||||
if (isset($params['uid']) && !isEmptyString($params['uid'])){
|
||||
$this->_uid = $params['uid'];
|
||||
} else {
|
||||
show_error('uid of logged user not passed!');
|
||||
}
|
||||
|
||||
$this->_ci->load->model('ressource/Kalender_model', 'KalenderModel');
|
||||
$this->_ci->load->library('VariableLib', array('uid' => getAuthUID()));
|
||||
$this->_ci->load->library('VariableLib', array('uid' => $this->_uid));
|
||||
$this->_ci->load->library('PhrasesLib', array('ui'));
|
||||
}
|
||||
|
||||
@@ -77,4 +85,4 @@ class RoomCollisionCheck implements ICollisionCheck
|
||||
|
||||
return $grouped;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,12 +3,20 @@
|
||||
class StudentCollisionCheck implements ICollisionCheck
|
||||
{
|
||||
private $_ci;
|
||||
private $_uid;
|
||||
|
||||
public function __construct()
|
||||
public function __construct($params)
|
||||
{
|
||||
$this->_ci =& get_instance();
|
||||
|
||||
if (isset($params['uid']) && !isEmptyString($params['uid'])){
|
||||
$this->_uid = $params['uid'];
|
||||
} else {
|
||||
show_error('uid of logged user not passed!');
|
||||
}
|
||||
|
||||
$this->_ci->load->model('ressource/Kalender_model', 'KalenderModel');
|
||||
$this->_ci->load->library('VariableLib', array('uid' => getAuthUID()));
|
||||
$this->_ci->load->library('VariableLib', array('uid' => $this->_uid));
|
||||
$this->_ci->load->library('PhrasesLib', array('ui'));
|
||||
}
|
||||
|
||||
@@ -244,4 +252,4 @@ class StudentCollisionCheck implements ICollisionCheck
|
||||
|
||||
return $grouped;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,12 +4,20 @@ class VerbandCollisionCheck implements ICollisionCheck
|
||||
{
|
||||
|
||||
private $_ci;
|
||||
private $_uid;
|
||||
|
||||
public function __construct()
|
||||
public function __construct($params)
|
||||
{
|
||||
$this->_ci =& get_instance();
|
||||
|
||||
if (isset($params['uid']) && !isEmptyString($params['uid'])){
|
||||
$this->_uid = $params['uid'];
|
||||
} else {
|
||||
show_error('uid of logged user not passed!');
|
||||
}
|
||||
|
||||
$this->_ci->load->model('ressource/Kalender_model', 'KalenderModel');
|
||||
$this->_ci->load->library('VariableLib', array('uid' => getAuthUID()));
|
||||
$this->_ci->load->library('VariableLib', array('uid' => $this->_uid));
|
||||
$this->_ci->load->library('PhrasesLib', array('ui'));
|
||||
|
||||
}
|
||||
@@ -359,4 +367,4 @@ class VerbandCollisionCheck implements ICollisionCheck
|
||||
return $grouped;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
class SabreDAVAuthLib extends \Sabre\DAV\Auth\Backend\AbstractBasic
|
||||
{
|
||||
private $_ci;
|
||||
protected $currentUser = null;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->_ci =& get_instance();
|
||||
|
||||
$this->_ci->load->library('AuthLib', array(false));
|
||||
$this->_ci->load->helper('hlp_authentication');
|
||||
}
|
||||
|
||||
public function getCurrentUser()
|
||||
{
|
||||
if ($this->currentUser)
|
||||
return $this->currentUser;
|
||||
|
||||
if (isLogged())
|
||||
return getAuthUID();
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected function validateUserPass($username, $password)
|
||||
{
|
||||
if (isSuccess($this->_ci->authlib->checkUserAuthByUsernamePassword($username, $password)))
|
||||
{
|
||||
$this->currentUser = $username;
|
||||
return true;
|
||||
}
|
||||
|
||||
$this->currentUser = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__.'/caldav/SabreDAVACLPrincipalBackend.php';
|
||||
require_once __DIR__.'/caldav/SabreDAVCalDAVBackend.php';
|
||||
|
||||
/**
|
||||
* Loads the SabreDAV CalDAV classes for the LVPlan calendar endpoint.
|
||||
*/
|
||||
class SabreDAVCalDAVLib
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* PDO principal backend
|
||||
*
|
||||
* This is a simple principal backend that maps exactly to the users table, as
|
||||
* used by Sabre_DAV_Auth_Backend_PDO.
|
||||
*
|
||||
* It assumes all principals are in a single collection. The default collection
|
||||
* is 'principals/', but this can be overriden.
|
||||
*
|
||||
* @package Sabre
|
||||
* @subpackage DAVACL
|
||||
* @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
|
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/)
|
||||
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
|
||||
*/
|
||||
class SabreDAVACLPrincipalBackend implements \Sabre\DAVACL\PrincipalBackend\BackendInterface
|
||||
{
|
||||
/**
|
||||
* PDO table name for 'principals'
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $tableName;
|
||||
|
||||
/**
|
||||
* PDO table name for 'group members'
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $groupMembersTableName;
|
||||
|
||||
protected $result_ma;
|
||||
protected $auth;
|
||||
/**
|
||||
* Sets up the backend.
|
||||
*
|
||||
* @param PDO $pdo
|
||||
* @param string $tableName
|
||||
*/
|
||||
public function __construct($auth)
|
||||
{
|
||||
$this->auth = $auth;
|
||||
|
||||
/*
|
||||
$ma = new mitarbeiter();
|
||||
$this->result_ma = $ma->getMitarbeiter(null,null,null);
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den eingeloggten User
|
||||
*/
|
||||
function getUser()
|
||||
{
|
||||
return $this->auth->getCurrentUser();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a list of principals based on a prefix.
|
||||
*
|
||||
* This prefix will often contain something like 'principals'. You are only
|
||||
* expected to return principals that are in this base path.
|
||||
*
|
||||
* You are expected to return at least a 'uri' for every user, you can
|
||||
* return any additional properties if you wish so. Common properties are:
|
||||
* {DAV:}displayname
|
||||
* {http://sabredav.org/ns}email-address - This is a custom SabreDAV
|
||||
* field that's actualy injected in a number of other properties. If
|
||||
* you have an email address, use this property.
|
||||
*
|
||||
* @param string $prefixPath
|
||||
* @return array
|
||||
*/
|
||||
public function getPrincipalsByPrefix($prefixPath)
|
||||
{
|
||||
//$prefixPath = principals
|
||||
//error_log('Principal.php/getPrincipalsByPrefix('.$prefixPath.')');
|
||||
$principals = array();
|
||||
$user = $this->getUser();
|
||||
|
||||
if($prefixPath=='principals')
|
||||
{
|
||||
|
||||
$principals[] = array(
|
||||
'id' => $user,
|
||||
'uri' => 'principals/'.$user,
|
||||
'{DAV:}displayname' => $user,
|
||||
'{http://sabredav.org/ns}email-address' => $user.'@example.com',
|
||||
);
|
||||
}
|
||||
|
||||
return $principals;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a specific principal, specified by it's path.
|
||||
* The returned structure should be the exact same as from
|
||||
* getPrincipalsByPrefix.
|
||||
*
|
||||
* @param string $path
|
||||
* @return array
|
||||
*/
|
||||
public function getPrincipalByPath($path)
|
||||
{
|
||||
$user = mb_substr($path,11);
|
||||
|
||||
$result = array(
|
||||
'id' => $user,
|
||||
'uri' => 'principals/'.$user,
|
||||
'{DAV:}displayname' => $user,
|
||||
'{http://sabredav.org/ns}email-address' => $user.'@example.com',
|
||||
);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of members for a group-principal
|
||||
*
|
||||
* @param string $principal
|
||||
* @return array
|
||||
*/
|
||||
public function getGroupMemberSet($principal)
|
||||
{
|
||||
$result = array();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of groups a principal is a member of
|
||||
*
|
||||
* @param string $principal
|
||||
* @return array
|
||||
*/
|
||||
public function getGroupMembership($principal)
|
||||
{
|
||||
$result = array();
|
||||
if(preg_match('/^principals\/[0-9A-Za-z\-]*$/',$principal))
|
||||
{
|
||||
$user = mb_substr($principal,11);
|
||||
}
|
||||
return $result;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the list of group members for a group principal.
|
||||
*
|
||||
* The principals should be passed as a list of uri's.
|
||||
*
|
||||
* @param string $principal
|
||||
* @param array $members
|
||||
* @return void
|
||||
*/
|
||||
public function setGroupMemberSet($principal, array $members)
|
||||
{
|
||||
throw new \Sabre\DAV\Exception('Not implemented');
|
||||
}
|
||||
|
||||
public function updatePrincipal($path, \Sabre\DAV\PropPatch $propPatch)
|
||||
{
|
||||
$propPatch->setRemainingResultCode(403);
|
||||
}
|
||||
|
||||
public function searchPrincipals($prefixPath, array $searchProperties, $test = 'allof')
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
public function findByUri($uri, $principalPrefix)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,575 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* CalDAV backend
|
||||
*/
|
||||
class SabreDAVCalDAVBackend extends \Sabre\CalDAV\Backend\AbstractBackend
|
||||
{
|
||||
protected $auth;
|
||||
|
||||
protected $CI;
|
||||
|
||||
CONST CALENDAR_NAME = 'LVPlan';
|
||||
CONST CAL_CATEGORY_STUNDENPLAN = 'Stundenplan';
|
||||
CONST CAL_CATEGORY_STUNDENPLAN_EXAM = 'StundenplanExam';
|
||||
CONST CAL_CATEGORY_STUNDENPLAN_REMOTE = 'StundenplanRemote';
|
||||
|
||||
CONST CAL_CATEGORY_STUNDENPLAN_EXAM_ICON = '📝';
|
||||
CONST CAL_CATEGORY_STUNDENPLAN_ON_SITE_ICON = '🏫';
|
||||
CONST CAL_CATEGORY_STUNDENPLAN_REMOTE_ICON = '📍';
|
||||
CONST CAL_CATEGORY_RESERVATION_ICON = '📌';
|
||||
/**
|
||||
* Creates the backend
|
||||
*
|
||||
* @param AuthBackend $auth
|
||||
*/
|
||||
public function __construct($auth)
|
||||
{
|
||||
$this->auth = $auth;
|
||||
|
||||
$this->CI =& get_instance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den eingeloggten User
|
||||
*/
|
||||
function getUser()
|
||||
{
|
||||
return $this->auth->getCurrentUser();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of calendars for a principal.
|
||||
*
|
||||
* Every project is an array with the following keys:
|
||||
* * id, a unique id that will be used by other functions to modify the
|
||||
* calendar. This can be the same as the uri or a database key.
|
||||
* * uri, which the basename of the uri with which the calendar is
|
||||
* accessed.
|
||||
* * principalUri. The owner of the calendar. Almost always the same as
|
||||
* principalUri passed to this method.
|
||||
*
|
||||
* Furthermore it can contain webdav properties in clark notation. A very
|
||||
* common one is '{DAV:}displayname'.
|
||||
*
|
||||
* @param string $principalUri
|
||||
* @return array
|
||||
*/
|
||||
public function getCalendarsForUser($principalUri)
|
||||
{
|
||||
$user = mb_substr($principalUri,11);
|
||||
$calendars = array();
|
||||
$calendar = array(
|
||||
'id' => $user,
|
||||
'uri' => self::CALENDAR_NAME.'-'.$user,
|
||||
'principaluri' => 'principals/'.$user,
|
||||
'{' . \Sabre\CalDAV\Plugin::NS_CALENDARSERVER . '}getctag' => $this->buildCalendarCtag($user),
|
||||
'{' . \Sabre\CalDAV\Plugin::NS_CALDAV . '}supported-calendar-component-set' => new \Sabre\CalDAV\Xml\Property\SupportedCalendarComponentSet(array('VEVENT')),
|
||||
'{DAV:}displayname' => self::CALENDAR_NAME,
|
||||
'{urn:ietf:params:xml:ns:caldav}calendar-description' => 'description comes here',
|
||||
'{urn:ietf:params:xml:ns:caldav}calendar-timezone' => 'Europe/Vienna',
|
||||
'{http://apple.com/ns/ical/}calendar-order' => '1',
|
||||
'{http://apple.com/ns/ical/}calendar-color' => '#FF0000',
|
||||
'{http://sabredav.org/ns}read-only' => 1
|
||||
);
|
||||
$calendars[] = $calendar;
|
||||
|
||||
return $calendars;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new calendar for a principal.
|
||||
*
|
||||
* If the creation was a success, an id must be returned that can be used to reference
|
||||
* this calendar in other methods, such as updateCalendar
|
||||
*
|
||||
* @param string $principalUri
|
||||
* @param string $calendarUri
|
||||
* @param array $properties
|
||||
*/
|
||||
public function createCalendar($principalUri,$calendarUri, array $properties)
|
||||
{
|
||||
return $calendarUri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates properties for a calendar.
|
||||
*
|
||||
* The mutations array uses the propertyName in clark-notation as key,
|
||||
* and the array value for the property value. In the case a property
|
||||
* should be deleted, the property value will be null.
|
||||
*
|
||||
* This method must be atomic. If one property cannot be changed, the
|
||||
* entire operation must fail.
|
||||
*
|
||||
* If the operation was successful, true can be returned.
|
||||
* If the operation failed, false can be returned.
|
||||
*
|
||||
* Deletion of a non-existant property is always succesful.
|
||||
*
|
||||
* Lastly, it is optional to return detailed information about any
|
||||
* failures. In this case an array should be returned with the following
|
||||
* structure:
|
||||
*
|
||||
* array(
|
||||
* 403 => array(
|
||||
* '{DAV:}displayname' => null,
|
||||
* ),
|
||||
* 424 => array(
|
||||
* '{DAV:}owner' => null,
|
||||
* )
|
||||
* )
|
||||
*
|
||||
* In this example it was forbidden to update {DAV:}displayname.
|
||||
* (403 Forbidden), which in turn also caused {DAV:}owner to fail
|
||||
* (424 Failed Dependency) because the request needs to be atomic.
|
||||
*
|
||||
* @param string $calendarId
|
||||
* @param array $mutations
|
||||
* @return bool|array
|
||||
*/
|
||||
public function updateCalendar($calendarId, \Sabre\DAV\PropPatch $propPatch)
|
||||
{
|
||||
$propPatch->setRemainingResultCode(200);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a calendar and all it's objects
|
||||
*
|
||||
* @param string $calendarId
|
||||
* @return void
|
||||
*/
|
||||
public function deleteCalendar($calendarId)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public function getCalendarData($userUID, $objectUri=null)
|
||||
{
|
||||
$this->CI->load->model("ressource/Mitarbeiter_model", "MitarbeiterModel");
|
||||
$this->CI->load->model("person/Benutzer_model", "BenutzerModel");
|
||||
|
||||
$user = $this->CI->BenutzerModel->loadWhere(array("uid" => $userUID));
|
||||
if(!$user)
|
||||
die('User invalid');
|
||||
|
||||
$this->CI->load->library('KalenderLib', ['uid' => $userUID]);
|
||||
|
||||
$isUserEmployeeResult = $this->CI->MitarbeiterModel->isMitarbeiter($userUID);
|
||||
if (isError($isUserEmployeeResult)) {
|
||||
return;
|
||||
}
|
||||
$isUserEmployee = getData($isUserEmployeeResult);
|
||||
|
||||
$startDate = date('Y-m-d', mktime(0,0,0,date('m'),date('d')-14,date('Y')));
|
||||
$endDate = date('Y-m-d', mktime(0,0,0,date('m')+6,date('d'),date('Y')));
|
||||
|
||||
$data = [];
|
||||
|
||||
if ($isUserEmployee) {
|
||||
$data = $this->CI->kalenderlib->getPlanForLecturerByLecturer($startDate, $endDate, $userUID);
|
||||
} else {
|
||||
$data = $this->CI->kalenderlib->getPlanForStudentByStudent($startDate, $endDate, $userUID);
|
||||
}
|
||||
|
||||
if(!is_array($data))
|
||||
$data = array();
|
||||
|
||||
foreach($data as $item)
|
||||
{
|
||||
$item->calendarDataFragment = $this->buildCalendarDataFragment($item);
|
||||
}
|
||||
|
||||
if (is_null($objectUri))
|
||||
{
|
||||
return $data;
|
||||
}
|
||||
|
||||
$normalizedObjectUri = $this->normalizeObjectUri($objectUri);
|
||||
foreach($data as $row)
|
||||
{
|
||||
if(md5($row->eindeutige_gruppen_id) == $normalizedObjectUri)
|
||||
{
|
||||
return $row;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function makeCal($event)
|
||||
{
|
||||
return $this->buildICalLine('BEGIN', 'VCALENDAR')
|
||||
.$this->buildICalLine('VERSION', '2.0')
|
||||
.$this->buildICalTextLine('PRODID', 'FH Technikum Wien')
|
||||
.$this->buildICalLine('BEGIN', 'VTIMEZONE')
|
||||
.$this->buildICalLine('TZID', 'Europe/Vienna')
|
||||
.$this->buildICalLine('BEGIN', 'DAYLIGHT')
|
||||
.$this->buildICalLine('TZOFFSETFROM', '+0100')
|
||||
.$this->buildICalLine('RRULE', 'FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU')
|
||||
.$this->buildICalLine('DTSTART', '19810329T020000')
|
||||
.$this->buildICalLine('TZNAME', 'GMT+02:00')
|
||||
.$this->buildICalLine('TZOFFSETTO', '+0200')
|
||||
.$this->buildICalLine('END', 'DAYLIGHT')
|
||||
.$this->buildICalLine('BEGIN', 'STANDARD')
|
||||
.$this->buildICalLine('TZOFFSETFROM', '+0200')
|
||||
.$this->buildICalLine('RRULE', 'FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU')
|
||||
.$this->buildICalLine('DTSTART', '19961027T030000')
|
||||
.$this->buildICalLine('TZNAME', 'GMT+01:00')
|
||||
.$this->buildICalLine('TZOFFSETTO', '+0100')
|
||||
.$this->buildICalLine('END', 'STANDARD')
|
||||
.$this->buildICalLine('END', 'VTIMEZONE')
|
||||
.$event
|
||||
.$this->buildICalLine('END', 'VCALENDAR');
|
||||
}
|
||||
|
||||
protected function buildCalendarDataFragment($item)
|
||||
{
|
||||
$summaryIcon = '';
|
||||
$summary = $item->type == 'reservierung' ? $item->titel : $item->topic;
|
||||
|
||||
$description = "";
|
||||
if ($item->type == 'reservierung') {
|
||||
$description = $item->beschreibung;
|
||||
} else {
|
||||
$description = $item->lehrfach_bez . "\r\n";
|
||||
|
||||
if (isset($item->lektor) && is_array($item->lektor) && count($item->lektor) > 0) {
|
||||
$description .= "Lektor*in: " . join(", ", array_map(function($teacher) { return $teacher["kurzbz"]; }, $item->lektor)) . "\r\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$category = self::CAL_CATEGORY_STUNDENPLAN;
|
||||
if ($item->type === 'lehreinheit') {
|
||||
if ($item->lehrform === 'EXAM') {
|
||||
$summaryIcon = self::CAL_CATEGORY_STUNDENPLAN_EXAM_ICON;
|
||||
$category = self::CAL_CATEGORY_STUNDENPLAN_EXAM;
|
||||
} else if (!isset($item->ko_ort_kurzbz) || $item->ko_ort_kurzbz === '') {
|
||||
$summaryIcon = self::CAL_CATEGORY_STUNDENPLAN_REMOTE_ICON;
|
||||
$category = self::CAL_CATEGORY_STUNDENPLAN_REMOTE;
|
||||
}
|
||||
} else if ($item->type === 'reservierung' && (!isset($item->ko_ort_kurzbz) || $item->ko_ort_kurzbz === '')) {
|
||||
$summaryIcon = self::CAL_CATEGORY_RESERVATION_ICON;
|
||||
$category = self::CAL_CATEGORY_STUNDENPLAN_REMOTE;
|
||||
}
|
||||
|
||||
if ($summaryIcon !== '') {
|
||||
$summary = $summaryIcon . ' ' . $summary;
|
||||
}
|
||||
|
||||
$parsedStartDate = $this->formatICalLocalDateTime($item->isostart);
|
||||
$parsedEndDate = $this->formatICalLocalDateTime($item->isoend);
|
||||
$lastModified = $this->formatICalUtcDateTime(isset($item->updateamum) ? $item->updateamum : null);
|
||||
$dtStamp = $lastModified ?: $this->formatICalUtcDateTime($item->isostart);
|
||||
|
||||
if($dtStamp === null)
|
||||
$dtStamp = '19700101T000000Z';
|
||||
|
||||
$fragment = $this->buildICalLine('BEGIN', 'VEVENT')
|
||||
.$this->buildICalTextLine('UID', $item->eindeutige_gruppen_id)
|
||||
.$this->buildICalLine('SEQUENCE', (int)$item->kalender_id)
|
||||
.$this->buildICalTextLine('SUMMARY', $summary)
|
||||
.$this->buildICalTextLine('DESCRIPTION', $description)
|
||||
.$this->buildICalTextLine('LOCATION', isset($item->ort_kurzbz) ? $item->ort_kurzbz : '')
|
||||
.$this->buildICalTextLine('CATEGORIES', $category)
|
||||
.$this->buildICalLine('DTSTART', $parsedStartDate, array('TZID' => 'Europe/Vienna'))
|
||||
.$this->buildICalLine('DTEND', $parsedEndDate, array('TZID' => 'Europe/Vienna'));
|
||||
|
||||
if($lastModified !== null)
|
||||
$fragment .= $this->buildICalLine('LAST-MODIFIED', $lastModified);
|
||||
|
||||
return $fragment
|
||||
.$this->buildICalLine('DTSTAMP', $dtStamp)
|
||||
.$this->buildICalLine('END', 'VEVENT');
|
||||
}
|
||||
|
||||
protected function buildCalendarCtag($userUID)
|
||||
{
|
||||
$data = $this->getCalendarData($userUID);
|
||||
if(!is_array($data))
|
||||
$data = array();
|
||||
|
||||
$fragments = array();
|
||||
foreach($data as $row)
|
||||
{
|
||||
$lastModified = isset($row->updateamum) ? $this->getLastModifiedTimestamp($row->updateamum) : null;
|
||||
$calendarData = isset($row->calendarDataFragment) ? $this->makeCal($row->calendarDataFragment) : '';
|
||||
$fragments[] = $this->getObjectUri($row).':'.$lastModified.':'.md5($calendarData);
|
||||
}
|
||||
|
||||
sort($fragments, SORT_STRING);
|
||||
return self::CALENDAR_NAME.'-'.$userUID.'-'.md5(implode('|', $fragments));
|
||||
}
|
||||
|
||||
protected function buildICalTextLine($name, $value, array $parameters = array())
|
||||
{
|
||||
return $this->buildICalLine($name, $this->escapeICalText($value), $parameters);
|
||||
}
|
||||
|
||||
protected function buildICalLine($name, $value, array $parameters = array())
|
||||
{
|
||||
$line = strtoupper($name);
|
||||
|
||||
foreach($parameters as $parameterName => $parameterValue)
|
||||
{
|
||||
$parameterValues = is_array($parameterValue) ? $parameterValue : array($parameterValue);
|
||||
$escapedValues = array();
|
||||
|
||||
foreach($parameterValues as $singleParameterValue)
|
||||
$escapedValues[] = $this->escapeICalParameterValue($singleParameterValue);
|
||||
|
||||
$line .= ';'.strtoupper($parameterName).'='.implode(',', $escapedValues);
|
||||
}
|
||||
|
||||
return $this->foldICalLine($line.':'.(string)$value);
|
||||
}
|
||||
|
||||
protected function foldICalLine($line)
|
||||
{
|
||||
$line = (string)$line;
|
||||
$folded = '';
|
||||
|
||||
while(strlen($line) > 75)
|
||||
{
|
||||
$part = mb_strcut($line, 0, 75, 'UTF-8');
|
||||
$folded .= $part."\r\n";
|
||||
$line = ' '.mb_strcut($line, strlen($part), strlen($line) - strlen($part), 'UTF-8');
|
||||
}
|
||||
|
||||
return $folded.$line."\r\n";
|
||||
}
|
||||
|
||||
protected function escapeICalText($value)
|
||||
{
|
||||
$value = (string)$value;
|
||||
$value = str_replace('\\', '\\\\', $value);
|
||||
$value = str_replace(array("\r\n", "\r", "\n"), '\n', $value);
|
||||
return str_replace(array(';', ','), array('\;', '\,'), $value);
|
||||
}
|
||||
|
||||
protected function escapeICalParameterValue($value)
|
||||
{
|
||||
$value = (string)$value;
|
||||
$value = str_replace(array('\\', '"', "\r", "\n"), array('\\\\', '\"', '', ''), $value);
|
||||
|
||||
if(preg_match('/[;:,]/', $value))
|
||||
return '"'.$value.'"';
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
protected function formatICalLocalDateTime($dateTime)
|
||||
{
|
||||
$dateTime = $this->createDateTime($dateTime);
|
||||
if($dateTime === null)
|
||||
return null;
|
||||
|
||||
$dateTime->setTimezone(new DateTimeZone('Europe/Vienna'));
|
||||
return $dateTime->format('Ymd\THis');
|
||||
}
|
||||
|
||||
protected function formatICalUtcDateTime($dateTime)
|
||||
{
|
||||
$dateTime = $this->createDateTime($dateTime);
|
||||
if($dateTime === null)
|
||||
return null;
|
||||
|
||||
$dateTime->setTimezone(new DateTimeZone('UTC'));
|
||||
return $dateTime->format('Ymd\THis\Z');
|
||||
}
|
||||
|
||||
protected function createDateTime($dateTime)
|
||||
{
|
||||
if($dateTime instanceof DateTime)
|
||||
return clone $dateTime;
|
||||
|
||||
if($dateTime === null || $dateTime === '')
|
||||
return null;
|
||||
|
||||
try
|
||||
{
|
||||
if(is_numeric($dateTime))
|
||||
return new DateTime('@'.(int)$dateTime);
|
||||
|
||||
return new DateTime($dateTime);
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected function getObjectUri($row)
|
||||
{
|
||||
return md5($row->eindeutige_gruppen_id).'.ics';
|
||||
}
|
||||
|
||||
protected function normalizeObjectUri($objectUri)
|
||||
{
|
||||
$normalizedObjectUri = (string)$objectUri;
|
||||
|
||||
if(substr($normalizedObjectUri, -4) === '.ics')
|
||||
$normalizedObjectUri = substr($normalizedObjectUri, 0, -4);
|
||||
|
||||
if(mb_strpos($normalizedObjectUri, '@') !== false)
|
||||
$normalizedObjectUri = mb_substr($normalizedObjectUri, mb_strpos($normalizedObjectUri, '@') + 1);
|
||||
|
||||
if($this->hasObjectUriDatePrefix($normalizedObjectUri))
|
||||
return mb_substr($normalizedObjectUri, mb_strpos($normalizedObjectUri, '-') + 1);
|
||||
|
||||
return $normalizedObjectUri;
|
||||
}
|
||||
|
||||
protected function hasObjectUriDatePrefix($objectUri)
|
||||
{
|
||||
$hyphenPosition = mb_strpos($objectUri, '-');
|
||||
if($hyphenPosition !== 15)
|
||||
return false;
|
||||
|
||||
return preg_match('/^\d{8}T\d{6}$/', mb_substr($objectUri, 0, 15)) === 1;
|
||||
}
|
||||
|
||||
protected function buildCalendarObject($row, $calendarId)
|
||||
{
|
||||
$calendarData = $this->makeCal($row->calendarDataFragment);
|
||||
|
||||
return array(
|
||||
"id"=>$row->eindeutige_gruppen_id,
|
||||
"calendardata"=>$calendarData,
|
||||
"uri"=>$this->getObjectUri($row),
|
||||
"lastmodified"=>$this->getLastModifiedTimestamp($row->updateamum),
|
||||
"etag"=>'"'.md5($calendarData).'"',
|
||||
"calendarid"=>$calendarId,
|
||||
"size"=>strlen($calendarData),
|
||||
"component"=>'vevent'
|
||||
);
|
||||
}
|
||||
|
||||
protected function getLastModifiedTimestamp($lastModified)
|
||||
{
|
||||
if($lastModified === null || $lastModified === '')
|
||||
return null;
|
||||
|
||||
if(is_numeric($lastModified))
|
||||
return (int)$lastModified;
|
||||
|
||||
$timestamp = strtotime($lastModified);
|
||||
if($timestamp === false)
|
||||
return null;
|
||||
|
||||
return $timestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all calendar objects within a calendar.
|
||||
*
|
||||
* Every item contains an array with the following keys:
|
||||
* * id - unique identifier which will be used for subsequent updates
|
||||
* * calendardata - The iCalendar-compatible calnedar data
|
||||
* * uri - a unique key which will be used to construct the uri. This can be any arbitrary string.
|
||||
* * lastmodified - a timestamp of the last modification time
|
||||
* * etag - An arbitrary string, surrounded by double-quotes. (e.g.:
|
||||
* ' "abcdef"')
|
||||
* * calendarid - The calendarid as it was passed to this function.
|
||||
*
|
||||
* Note that the etag is optional, but it's highly encouraged to return for
|
||||
* speed reasons.
|
||||
*
|
||||
* The calendardata is also optional. If it's not returned
|
||||
* 'getCalendarObject' will be called later, which *is* expected to return
|
||||
* calendardata.
|
||||
*
|
||||
* @param string $calendarId
|
||||
* @return array
|
||||
*/
|
||||
public function getCalendarObjects($calendarId)
|
||||
{
|
||||
//$user = $this->getUser();
|
||||
$user = $calendarId;
|
||||
$data = $this->getCalendarData($user);
|
||||
|
||||
//error_log("Caldav_Backend.php/getCalendarObjects($calendarId) ");
|
||||
$return = array();
|
||||
|
||||
if(!is_array($data))
|
||||
return $return;
|
||||
|
||||
foreach($data as $row)
|
||||
{
|
||||
$return[] = $this->buildCalendarObject($row, $calendarId);
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information from a single calendar object, based on it's object
|
||||
* uri.
|
||||
*
|
||||
* The returned array must have the same keys as getCalendarObjects. The
|
||||
* 'calendardata' object is required here though, while it's not required
|
||||
* for getCalendarObjects.
|
||||
*
|
||||
* @param string $calendarId
|
||||
* @param string $objectUri
|
||||
* @return array
|
||||
*/
|
||||
public function getCalendarObject($calendarId,$objectUri)
|
||||
{
|
||||
$user = $calendarId;
|
||||
$data = $this->getCalendarData($user,$objectUri);
|
||||
|
||||
if(empty($data))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
elseif(is_object($data))
|
||||
{
|
||||
$ret = $this->buildCalendarObject($data, $calendarId);
|
||||
}
|
||||
|
||||
return isset($ret) ? $ret : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new calendar object.
|
||||
*
|
||||
* @param string $calendarId
|
||||
* @param string $objectUri
|
||||
* @param string $calendarData
|
||||
* @return void
|
||||
*/
|
||||
public function createCalendarObject($calendarId,$objectUri,$calendarData)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates an existing calendarobject, based on it's uri.
|
||||
*
|
||||
* @param string $calendarId
|
||||
* @param string $objectUri
|
||||
* @param string $calendarData
|
||||
* @return void
|
||||
*/
|
||||
public function updateCalendarObject($calendarId,$objectUri,$calendarData)
|
||||
{
|
||||
if(is_resource($calendarData))
|
||||
$calendarData = stream_get_contents($calendarData);
|
||||
|
||||
return '"'.md5((string)$calendarData).'"';
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes an existing calendar object.
|
||||
*
|
||||
* @param string $calendarId
|
||||
* @param string $objectUri
|
||||
* @return void
|
||||
*/
|
||||
public function deleteCalendarObject($calendarId,$objectUri)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
class SabreDAVReadOnlyACL
|
||||
{
|
||||
public static function getAcl($principalUri, $includeFreeBusy = false)
|
||||
{
|
||||
$acl = array(
|
||||
array(
|
||||
'privilege' => '{DAV:}read',
|
||||
'principal' => $principalUri,
|
||||
'protected' => true,
|
||||
),
|
||||
array(
|
||||
'privilege' => '{DAV:}read',
|
||||
'principal' => $principalUri.'/calendar-proxy-read',
|
||||
'protected' => true,
|
||||
),
|
||||
);
|
||||
|
||||
if($includeFreeBusy)
|
||||
{
|
||||
$acl[] = array(
|
||||
'privilege' => '{'.\Sabre\CalDAV\Plugin::NS_CALDAV.'}read-free-busy',
|
||||
'principal' => '{DAV:}authenticated',
|
||||
'protected' => true,
|
||||
);
|
||||
}
|
||||
|
||||
return $acl;
|
||||
}
|
||||
|
||||
public static function ignoreWrite()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
class SabreDAVReadOnlyCalendar extends \Sabre\CalDAV\Calendar
|
||||
{
|
||||
protected $readOnlyCaldavBackend;
|
||||
protected $readOnlyCalendarInfo;
|
||||
|
||||
public function __construct(\Sabre\CalDAV\Backend\BackendInterface $caldavBackend, $calendarInfo)
|
||||
{
|
||||
parent::__construct($caldavBackend, $calendarInfo);
|
||||
$this->readOnlyCaldavBackend = $caldavBackend;
|
||||
$this->readOnlyCalendarInfo = $calendarInfo;
|
||||
}
|
||||
|
||||
public function getChild($name)
|
||||
{
|
||||
$obj = $this->readOnlyCaldavBackend->getCalendarObject($this->readOnlyCalendarInfo['id'], $name);
|
||||
|
||||
if(!$obj)
|
||||
throw new \Sabre\DAV\Exception\NotFound('Calendar object not found');
|
||||
|
||||
$obj['acl'] = $this->getCalendarObjectAcl();
|
||||
|
||||
return new SabreDAVReadOnlyCalendarObject($this->readOnlyCaldavBackend, $this->readOnlyCalendarInfo, $obj);
|
||||
}
|
||||
|
||||
public function getChildren()
|
||||
{
|
||||
$objs = $this->readOnlyCaldavBackend->getCalendarObjects($this->readOnlyCalendarInfo['id']);
|
||||
$children = array();
|
||||
|
||||
foreach($objs as $obj)
|
||||
{
|
||||
$obj['acl'] = $this->getCalendarObjectAcl();
|
||||
$children[] = new SabreDAVReadOnlyCalendarObject($this->readOnlyCaldavBackend, $this->readOnlyCalendarInfo, $obj);
|
||||
}
|
||||
|
||||
return $children;
|
||||
}
|
||||
|
||||
public function createFile($name, $calendarData = null)
|
||||
{
|
||||
return SabreDAVReadOnlyACL::ignoreWrite();
|
||||
}
|
||||
|
||||
public function createDirectory($name)
|
||||
{
|
||||
return SabreDAVReadOnlyACL::ignoreWrite();
|
||||
}
|
||||
|
||||
public function delete()
|
||||
{
|
||||
return SabreDAVReadOnlyACL::ignoreWrite();
|
||||
}
|
||||
|
||||
public function setName($newName)
|
||||
{
|
||||
return SabreDAVReadOnlyACL::ignoreWrite();
|
||||
}
|
||||
|
||||
public function updateProperties($mutations)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function propPatch(\Sabre\DAV\PropPatch $propPatch)
|
||||
{
|
||||
$propPatch->setRemainingResultCode(200);
|
||||
}
|
||||
|
||||
public function getACL()
|
||||
{
|
||||
return SabreDAVReadOnlyACL::getAcl($this->getOwner(), true);
|
||||
}
|
||||
|
||||
protected function getCalendarObjectAcl()
|
||||
{
|
||||
return SabreDAVReadOnlyACL::getAcl($this->getOwner());
|
||||
}
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
class SabreDAVReadOnlyCalendarHome extends \Sabre\CalDAV\CalendarHome
|
||||
{
|
||||
protected $readOnlyCaldavBackend;
|
||||
protected $readOnlyPrincipalInfo;
|
||||
|
||||
public function __construct(\Sabre\CalDAV\Backend\BackendInterface $caldavBackend, $principalInfo)
|
||||
{
|
||||
parent::__construct($caldavBackend, $principalInfo);
|
||||
$this->readOnlyCaldavBackend = $caldavBackend;
|
||||
$this->readOnlyPrincipalInfo = $principalInfo;
|
||||
}
|
||||
|
||||
public function getChildren()
|
||||
{
|
||||
$calendars = $this->readOnlyCaldavBackend->getCalendarsForUser($this->readOnlyPrincipalInfo['uri']);
|
||||
$objs = array();
|
||||
|
||||
foreach($calendars as $calendar)
|
||||
{
|
||||
$objs[] = new SabreDAVReadOnlyCalendar($this->readOnlyCaldavBackend, $calendar);
|
||||
}
|
||||
|
||||
return $objs;
|
||||
}
|
||||
|
||||
public function createExtendedCollection($name, \Sabre\DAV\MkCol $mkCol)
|
||||
{
|
||||
return SabreDAVReadOnlyACL::ignoreWrite();
|
||||
}
|
||||
|
||||
public function createFile($filename, $data = null)
|
||||
{
|
||||
return SabreDAVReadOnlyACL::ignoreWrite();
|
||||
}
|
||||
|
||||
public function createDirectory($filename)
|
||||
{
|
||||
return SabreDAVReadOnlyACL::ignoreWrite();
|
||||
}
|
||||
|
||||
public function delete()
|
||||
{
|
||||
return SabreDAVReadOnlyACL::ignoreWrite();
|
||||
}
|
||||
|
||||
public function setName($name)
|
||||
{
|
||||
return SabreDAVReadOnlyACL::ignoreWrite();
|
||||
}
|
||||
|
||||
public function getACL()
|
||||
{
|
||||
return SabreDAVReadOnlyACL::getAcl($this->readOnlyPrincipalInfo['uri']);
|
||||
}
|
||||
}
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
class SabreDAVReadOnlyCalendarObject extends \Sabre\CalDAV\CalendarObject
|
||||
{
|
||||
protected $readOnlyCalendarInfo;
|
||||
|
||||
public function __construct(\Sabre\CalDAV\Backend\BackendInterface $caldavBackend, array $calendarInfo, array $objectData)
|
||||
{
|
||||
parent::__construct($caldavBackend, $calendarInfo, $objectData);
|
||||
$this->readOnlyCalendarInfo = $calendarInfo;
|
||||
}
|
||||
|
||||
public function put($calendarData)
|
||||
{
|
||||
return $this->getCurrentETag();
|
||||
}
|
||||
|
||||
public function getETag()
|
||||
{
|
||||
if($this->isWriteRequest())
|
||||
{
|
||||
$ifMatch = isset($_SERVER['HTTP_IF_MATCH']) ? trim($_SERVER['HTTP_IF_MATCH']) : '';
|
||||
if($ifMatch !== '' && $ifMatch !== '*')
|
||||
{
|
||||
$requestedEtags = explode(',', $ifMatch);
|
||||
foreach($requestedEtags as $requestedEtag)
|
||||
{
|
||||
$requestedEtag = trim($requestedEtag);
|
||||
if($requestedEtag !== '')
|
||||
return $requestedEtag;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return parent::getETag();
|
||||
}
|
||||
|
||||
public function getLastModified()
|
||||
{
|
||||
if($this->isWriteRequest())
|
||||
{
|
||||
$ifUnmodifiedSince = isset($_SERVER['HTTP_IF_UNMODIFIED_SINCE']) ? trim($_SERVER['HTTP_IF_UNMODIFIED_SINCE']) : '';
|
||||
if($ifUnmodifiedSince !== '')
|
||||
{
|
||||
$timestamp = strtotime($ifUnmodifiedSince);
|
||||
if($timestamp !== false)
|
||||
return max(0, $timestamp - 1);
|
||||
}
|
||||
}
|
||||
|
||||
return parent::getLastModified();
|
||||
}
|
||||
|
||||
public function delete()
|
||||
{
|
||||
return SabreDAVReadOnlyACL::ignoreWrite();
|
||||
}
|
||||
|
||||
public function setName($name)
|
||||
{
|
||||
return SabreDAVReadOnlyACL::ignoreWrite();
|
||||
}
|
||||
|
||||
public function getACL()
|
||||
{
|
||||
return SabreDAVReadOnlyACL::getAcl($this->readOnlyCalendarInfo['principaluri']);
|
||||
}
|
||||
|
||||
protected function isWriteRequest()
|
||||
{
|
||||
if(!isset($_SERVER['REQUEST_METHOD']))
|
||||
return false;
|
||||
|
||||
return in_array(strtoupper($_SERVER['REQUEST_METHOD']), array('PUT', 'DELETE', 'PROPPATCH', 'MOVE', 'COPY', 'PATCH'), true);
|
||||
}
|
||||
|
||||
protected function getCurrentETag()
|
||||
{
|
||||
if(isset($this->objectData['etag']) && $this->objectData['etag'] !== '')
|
||||
return $this->objectData['etag'];
|
||||
|
||||
return parent::getETag();
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
class SabreDAVReadOnlyCalendarRoot extends \Sabre\CalDAV\CalendarRoot
|
||||
{
|
||||
protected $readOnlyCaldavBackend;
|
||||
|
||||
public function __construct(\Sabre\DAVACL\PrincipalBackend\BackendInterface $principalBackend, \Sabre\CalDAV\Backend\BackendInterface $caldavBackend, $principalPrefix = 'principals')
|
||||
{
|
||||
parent::__construct($principalBackend, $caldavBackend, $principalPrefix);
|
||||
$this->readOnlyCaldavBackend = $caldavBackend;
|
||||
}
|
||||
|
||||
public function getChildForPrincipal(array $principal)
|
||||
{
|
||||
return new SabreDAVReadOnlyCalendarHome($this->readOnlyCaldavBackend, $principal);
|
||||
}
|
||||
}
|
||||
+3
-1
@@ -431,7 +431,7 @@
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.6.40",
|
||||
"php": ">=7.0.0",
|
||||
|
||||
"afarkas/html5shiv": "3.7.*",
|
||||
"alvaro-prieto/colresizable": "1.6",
|
||||
@@ -492,6 +492,8 @@
|
||||
|
||||
"rmariuzzo/jquery-checkboxes": "1.0.7",
|
||||
|
||||
"sabre/dav": "4.0.3",
|
||||
"sabre/event": "5.0.3",
|
||||
"scottjehl/respond": "1.4.2",
|
||||
|
||||
"tapmodo/jcrop": "2.0.4",
|
||||
|
||||
@@ -479,7 +479,6 @@ export default {
|
||||
class="fhc-calendar-base-grid"
|
||||
style="display:grid;width:100%;height:100%;overflow:auto"
|
||||
:style="'grid-template-' + axisRow + 's:auto' + (allDayEvents ? ' auto ' : ' ') + '1fr;grid-template-' + axisCol + 's:auto ' + styleGridCols"
|
||||
data-cy="calendar-base-grid"
|
||||
>
|
||||
<div
|
||||
class="grid-header"
|
||||
@@ -557,8 +556,6 @@ export default {
|
||||
<div
|
||||
v-for="(part, i) in axisPartsSave"
|
||||
:key="i"
|
||||
data-cy="calendar-grid-part"
|
||||
:data-drop-index="index * axisPartsSave.length + i + 1"
|
||||
class="part-body"
|
||||
style="position:relative"
|
||||
:style="'grid-' + axisCol + ':' + (1+index) + ';grid-' + axisRow + ':ps_' + i + '/pe_' + i"
|
||||
@@ -600,4 +597,4 @@ export default {
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
}
|
||||
}
|
||||
@@ -116,7 +116,6 @@ export default {
|
||||
v-draggable:move.noimage="draggable ? dragKalenderCollection : {}"
|
||||
v-cal-click:event="isHeaderOrFooter ? event : event.orig"
|
||||
@contextmenu.prevent="onRightClick"
|
||||
data-cy="calendar-event"
|
||||
>
|
||||
<div
|
||||
v-if="resizable"
|
||||
|
||||
@@ -19,7 +19,6 @@ export default {
|
||||
class="fhc-calendar-base-grid-line-event event"
|
||||
v-draggable:move.noimage="dragKalenderCollection"
|
||||
style="border:1px"
|
||||
data-cy="calendar-event"
|
||||
>
|
||||
<div class="title">
|
||||
{{ event.orig.topic || event.orig.titel || event.orig.lehrfach }}
|
||||
|
||||
@@ -360,7 +360,6 @@ export default {
|
||||
:title="node.data.studiengang_kz"
|
||||
v-drag-click="() => toggleTreeNode(node)"
|
||||
v-drop:link-strict.student-collection="(evt, students) => dropStudents(node, students)"
|
||||
data-cy="course-tree-row"
|
||||
>
|
||||
{{ node.data.name }}
|
||||
</span>
|
||||
@@ -369,7 +368,6 @@ export default {
|
||||
:data-tree-item-key="node.key"
|
||||
:title="node.data.studiengang_kz"
|
||||
v-drag-click="() => toggleTreeNode(node)"
|
||||
data-cy="course-tree-row"
|
||||
>
|
||||
{{ node.data.name }}
|
||||
</span>
|
||||
|
||||
@@ -81,7 +81,7 @@ export default {
|
||||
</div>
|
||||
<div class="event-text" v-tooltip="tooltipString">
|
||||
<span class="event-topic">{{ event.topic }}</span>
|
||||
<span data-cy="calendar-event-room" class="event-place">{{ event.ort_kurzbz }}</span>
|
||||
<span class="event-place">{{ event.ort_kurzbz }}</span>
|
||||
<span
|
||||
v-for="(lektor,index) in event.lektor.slice(0, 3)"
|
||||
class="event-lectors"
|
||||
|
||||
@@ -86,7 +86,7 @@ export default {
|
||||
>
|
||||
... +{{ event.lektor.length - 3 }}
|
||||
</span>
|
||||
<span data-cy="calendar-event-room" class="event-place">{{ event.ort_kurzbz }}</span>
|
||||
<span class="event-place">{{ event.ort_kurzbz }}</span>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
|
||||
@@ -25,12 +25,4 @@ DECLARE res varchar(32);
|
||||
SELECT studiensemester_kurzbz into res FROM public.tbl_studiensemester WHERE start<=now() AND ende>=now() ORDER BY start DESC LIMIT 1;
|
||||
return res;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
CREATE OR REPLACE FUNCTION LastActiveSemester() RETURNS varchar(32) AS $$
|
||||
DECLARE res varchar(32);
|
||||
BEGIN
|
||||
SELECT studiensemester_kurzbz into res FROM public.tbl_studiensemester WHERE start<=now() ORDER BY start DESC LIMIT 1;
|
||||
return res;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
$$ LANGUAGE plpgsql;
|
||||
@@ -122,7 +122,7 @@ INSERT INTO lehre.tbl_studienplan_semester (studienplan_id, studiensemester_kurz
|
||||
|
||||
|
||||
INSERT INTO lehre.tbl_lehreinheit (lehreinheit_id, lehrveranstaltung_id, studiensemester_kurzbz, lehrfach_id_old, lehrform_kurzbz, stundenblockung, wochenrythmus, start_kw, raumtyp, raumtypalternativ, sprache, lehre, anmerkung, unr, lvnr, updateamum, updatevon, insertamum, insertvon, ext_id, lehrfach_id, gewicht)
|
||||
VALUES(51001, 5221, COALESCE(CurrentSemester(), LastActiveSemester()), NULL, 'VO', 2, 1, NULL, 'Dummy', 'Dummy', 'German', true, NULL, 5221, NULL, '2023-08-24 14:54:43.000', 'oesi', '2023-08-24 14:54:43.000', 'oesi', NULL, 5221, 1);
|
||||
VALUES(51001, 5221, CurrentSemester(), NULL, 'VO', 2, 1, NULL, 'Dummy', 'Dummy', 'German', true, NULL, 5221, NULL, '2023-08-24 14:54:43.000', 'oesi', '2023-08-24 14:54:43.000', 'oesi', NULL, 5221, 1);
|
||||
|
||||
INSERT INTO lehre.tbl_lehreinheitgruppe
|
||||
(lehreinheit_id, studiengang_kz, semester, verband, gruppe, gruppe_kurzbz, updateamum, updatevon, insertamum, insertvon, ext_id)
|
||||
@@ -137,7 +137,7 @@ INSERT INTO lehre.tbl_lehreinheitmitarbeiter
|
||||
VALUES(51001, 'demolektor1', 'Lektor', 0, NULL, 1.00, NULL, true, NULL, NULL, '2023-08-24 14:58:40.000', 'oesi', NULL, 0.00, NULL, NULL);
|
||||
|
||||
INSERT INTO lehre.tbl_lehreinheit (lehreinheit_id, lehrveranstaltung_id, studiensemester_kurzbz, lehrfach_id_old, lehrform_kurzbz, stundenblockung, wochenrythmus, start_kw, raumtyp, raumtypalternativ, sprache, lehre, anmerkung, unr, lvnr, updateamum, updatevon, insertamum, insertvon, ext_id, lehrfach_id, gewicht)
|
||||
VALUES(51002, 5121, COALESCE(CurrentSemester(), LastActiveSemester()), NULL, 'VO', 2, 1, NULL, 'Dummy', 'Dummy', 'German', true, NULL, 5121, NULL, '2023-08-24 14:54:43.000', 'oesi', '2023-08-24 14:54:43.000', 'oesi', NULL, 5121, 1);
|
||||
VALUES(51002, 5121, CurrentSemester(), NULL, 'VO', 2, 1, NULL, 'Dummy', 'Dummy', 'German', true, NULL, 5121, NULL, '2023-08-24 14:54:43.000', 'oesi', '2023-08-24 14:54:43.000', 'oesi', NULL, 5121, 1);
|
||||
|
||||
INSERT INTO lehre.tbl_lehreinheitgruppe
|
||||
(lehreinheit_id, studiengang_kz, semester, verband, gruppe, gruppe_kurzbz, updateamum, updatevon, insertamum, insertvon, ext_id)
|
||||
@@ -148,7 +148,7 @@ INSERT INTO lehre.tbl_lehreinheitmitarbeiter
|
||||
VALUES(51002, 'demolektor2', 'Lektor', 0, NULL, 1.00, NULL, true, NULL, NULL, '2023-08-24 14:58:40.000', 'oesi', NULL, 0.00, NULL, NULL);
|
||||
|
||||
INSERT INTO lehre.tbl_lehreinheit (lehreinheit_id, lehrveranstaltung_id, studiensemester_kurzbz, lehrfach_id_old, lehrform_kurzbz, stundenblockung, wochenrythmus, start_kw, raumtyp, raumtypalternativ, sprache, lehre, anmerkung, unr, lvnr, updateamum, updatevon, insertamum, insertvon, ext_id, lehrfach_id, gewicht)
|
||||
VALUES(51003, 5141, COALESCE(CurrentSemester(), LastActiveSemester()), NULL, 'VO', 2, 1, NULL, 'Dummy', 'Dummy', 'German', true, NULL, 5141, NULL, '2023-08-24 14:54:43.000', 'oesi', '2023-08-24 14:54:43.000', 'oesi', NULL, 5141, 1);
|
||||
VALUES(51003, 5141, CurrentSemester(), NULL, 'VO', 2, 1, NULL, 'Dummy', 'Dummy', 'German', true, NULL, 5141, NULL, '2023-08-24 14:54:43.000', 'oesi', '2023-08-24 14:54:43.000', 'oesi', NULL, 5141, 1);
|
||||
|
||||
INSERT INTO lehre.tbl_lehreinheitgruppe
|
||||
(lehreinheit_id, studiengang_kz, semester, verband, gruppe, gruppe_kurzbz, updateamum, updatevon, insertamum, insertvon, ext_id)
|
||||
@@ -159,7 +159,7 @@ INSERT INTO lehre.tbl_lehreinheitmitarbeiter
|
||||
VALUES(51003, 'demolektor3', 'Lektor', 0, NULL, 1.00, NULL, true, NULL, NULL, '2023-08-24 14:58:40.000', 'oesi', NULL, 0.00, NULL, NULL);
|
||||
|
||||
INSERT INTO lehre.tbl_lehreinheit (lehreinheit_id, lehrveranstaltung_id, studiensemester_kurzbz, lehrfach_id_old, lehrform_kurzbz, stundenblockung, wochenrythmus, start_kw, raumtyp, raumtypalternativ, sprache, lehre, anmerkung, unr, lvnr, updateamum, updatevon, insertamum, insertvon, ext_id, lehrfach_id, gewicht)
|
||||
VALUES(51004, 5211, COALESCE(CurrentSemester(), LastActiveSemester()), NULL, 'VO', 2, 1, NULL, 'Dummy', 'Dummy', 'German', true, NULL, 5211, NULL, '2023-08-24 14:54:43.000', 'oesi', '2023-08-24 14:54:43.000', 'oesi', NULL, 5211, 1);
|
||||
VALUES(51004, 5211, CurrentSemester(), NULL, 'VO', 2, 1, NULL, 'Dummy', 'Dummy', 'German', true, NULL, 5211, NULL, '2023-08-24 14:54:43.000', 'oesi', '2023-08-24 14:54:43.000', 'oesi', NULL, 5211, 1);
|
||||
|
||||
INSERT INTO lehre.tbl_lehreinheitgruppe
|
||||
(lehreinheit_id, studiengang_kz, semester, verband, gruppe, gruppe_kurzbz, updateamum, updatevon, insertamum, insertvon, ext_id)
|
||||
@@ -170,7 +170,7 @@ INSERT INTO lehre.tbl_lehreinheitmitarbeiter
|
||||
VALUES(51004, 'demolektor4', 'Lektor', 0, NULL, 1.00, NULL, true, NULL, NULL, '2023-08-24 14:58:40.000', 'oesi', NULL, 0.00, NULL, NULL);
|
||||
|
||||
INSERT INTO lehre.tbl_lehreinheit (lehreinheit_id, lehrveranstaltung_id, studiensemester_kurzbz, lehrfach_id_old, lehrform_kurzbz, stundenblockung, wochenrythmus, start_kw, raumtyp, raumtypalternativ, sprache, lehre, anmerkung, unr, lvnr, updateamum, updatevon, insertamum, insertvon, ext_id, lehrfach_id, gewicht)
|
||||
VALUES(51005, 5311, COALESCE(CurrentSemester(), LastActiveSemester()), NULL, 'VO', 2, 1, NULL, 'Dummy', 'Dummy', 'German', true, NULL, 5311, NULL, '2023-08-24 14:54:43.000', 'oesi', '2023-08-24 14:54:43.000', 'oesi', NULL, 5311, 1);
|
||||
VALUES(51005, 5311, CurrentSemester(), NULL, 'VO', 2, 1, NULL, 'Dummy', 'Dummy', 'German', true, NULL, 5311, NULL, '2023-08-24 14:54:43.000', 'oesi', '2023-08-24 14:54:43.000', 'oesi', NULL, 5311, 1);
|
||||
|
||||
INSERT INTO lehre.tbl_lehreinheitgruppe
|
||||
(lehreinheit_id, studiengang_kz, semester, verband, gruppe, gruppe_kurzbz, updateamum, updatevon, insertamum, insertvon, ext_id)
|
||||
@@ -181,7 +181,7 @@ INSERT INTO lehre.tbl_lehreinheitmitarbeiter
|
||||
VALUES(51005, 'demolektor4', 'Lektor', 0, NULL, 1.00, NULL, true, NULL, NULL, '2023-08-24 14:58:40.000', 'oesi', NULL, 0.00, NULL, NULL);
|
||||
|
||||
INSERT INTO lehre.tbl_lehreinheit (lehreinheit_id, lehrveranstaltung_id, studiensemester_kurzbz, lehrfach_id_old, lehrform_kurzbz, stundenblockung, wochenrythmus, start_kw, raumtyp, raumtypalternativ, sprache, lehre, anmerkung, unr, lvnr, updateamum, updatevon, insertamum, insertvon, ext_id, lehrfach_id, gewicht)
|
||||
VALUES(51006, 5321, COALESCE(CurrentSemester(), LastActiveSemester()), NULL, 'VO', 2, 1, NULL, 'Dummy', 'Dummy', 'German', true, NULL, 5321, NULL, '2023-08-24 14:54:43.000', 'oesi', '2023-08-24 14:54:43.000', 'oesi', NULL, 5321, 1);
|
||||
VALUES(51006, 5321, CurrentSemester(), NULL, 'VO', 2, 1, NULL, 'Dummy', 'Dummy', 'German', true, NULL, 5321, NULL, '2023-08-24 14:54:43.000', 'oesi', '2023-08-24 14:54:43.000', 'oesi', NULL, 5321, 1);
|
||||
|
||||
INSERT INTO lehre.tbl_lehreinheitgruppe
|
||||
(lehreinheit_id, studiengang_kz, semester, verband, gruppe, gruppe_kurzbz, updateamum, updatevon, insertamum, insertvon, ext_id)
|
||||
@@ -210,7 +210,7 @@ VALUES(510021, 31002, 31002, 5, 1, 'B', '', NULL, 'demolektor1', 'EG04', '2025-0
|
||||
|
||||
INSERT INTO public.tbl_studentlehrverband
|
||||
(student_uid, studiensemester_kurzbz, studiengang_kz, semester, verband, gruppe, updateamum, updatevon, insertamum, insertvon, ext_id)
|
||||
VALUES('s125b101', LastActiveSemester(), 5, 2, ' ', ' ', NULL, NULL, '2026-06-11 14:33:58.403', 'auto', NULL);
|
||||
VALUES('s125b101', 'SS2026', 5, 2, ' ', ' ', NULL, NULL, '2026-06-11 14:33:58.403', 'auto', NULL);
|
||||
|
||||
INSERT INTO public.tbl_gruppe (gruppe_kurzbz, studiengang_kz, semester, bezeichnung, beschreibung, sichtbar, lehre, aktiv, sort, mailgrp, generiert, updateamum, updatevon, insertamum, insertvon, ext_id, orgform_kurzbz, content_visible, gesperrt, direktinskription, zutrittssystem, aufnahmegruppe) VALUES
|
||||
('GRP_51003', 5, 2, 'BS5 2 ENG', null, false, false, true, NULL, false, false, now(), 'demoadmin', now(), 'demoadmin', NULL, NULL, true, false, true, false, false),
|
||||
@@ -229,3 +229,4 @@ INSERT INTO public.tbl_benutzergruppe (uid, gruppe_kurzbz, updateamum, updatevon
|
||||
('s125b101', 'GRP_51003', now(), 'demoadmin', now(), 'demoadmin', NULL, NULL),
|
||||
('s125b101', 'GRP_51004', now(), 'demoadmin', now(), 'demoadmin', NULL, NULL)
|
||||
;
|
||||
|
||||
@@ -177,9 +177,9 @@ VALUES
|
||||
(51006, 31),
|
||||
(51004, 32);
|
||||
|
||||
-- INSERT INTO public.tbl_variablenname
|
||||
-- (name, defaultwert)
|
||||
-- VALUES('ignore_resources_collisions', 'false');
|
||||
INSERT INTO public.tbl_variablenname
|
||||
(name, defaultwert)
|
||||
VALUES('ignore_resources_collisions', 'false');
|
||||
|
||||
INSERT INTO public.tbl_variable
|
||||
(name, uid, wert)
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
node_modules
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
/cypress/screenshots
|
||||
/cypress/videos
|
||||
!.env.example
|
||||
@@ -1,34 +1,68 @@
|
||||
import { tempusApi } from "../../../../support/api/tempusApi";
|
||||
import { getDateForDay } from "../../../../support/helpers/date";
|
||||
import {
|
||||
getTempusTestSemester,
|
||||
TEMPUS_TEST_STUDY_PLAN_SHORT_CODE,
|
||||
} from "../../../../support/helpers/tempusTestData";
|
||||
|
||||
let TEMPUS_TEST_SEMESTER;
|
||||
const TARGETED_STUDY_PLAN_SHORT_CODE = "STG5";
|
||||
|
||||
const resetEventsBeforeTest = () => {
|
||||
tempusApi
|
||||
.getPlannerEvents(getDateForDay("monday"), getDateForDay("monday"))
|
||||
.then((events) => {
|
||||
events.forEach((event) => {
|
||||
tempusApi.deleteKalenderEvent(event.kalender_id);
|
||||
});
|
||||
});
|
||||
tempusApi
|
||||
.getPlannerEvents(getDateForDay("tuesday"), getDateForDay("tuesday"))
|
||||
.then((events) => {
|
||||
events.forEach((event) => {
|
||||
if (
|
||||
event.type === "lehreinheit" &&
|
||||
event.beginn === "20:15:00" &&
|
||||
event.ende === "21:00:00"
|
||||
) {
|
||||
tempusApi.updateKalenderEvent(
|
||||
event.kalender_id,
|
||||
`${event.datum} 19:30`,
|
||||
`${event.datum} 20:15`,
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
tempusApi
|
||||
.getPlannerEvents(getDateForDay("sunday"), getDateForDay("sunday"))
|
||||
.then((events) => {
|
||||
events.forEach((event) => {
|
||||
if (
|
||||
event.type === "lehreinheit" &&
|
||||
event.beginn === "18:35:00" &&
|
||||
event.ende === "19:20:00" &&
|
||||
event.lektor.some((lector) => lector.kurzbz === "DemoLKT1")
|
||||
) {
|
||||
tempusApi.updateKalenderEvent(
|
||||
event.kalender_id,
|
||||
`${event.datum} 17:50`,
|
||||
`${event.datum} 18:35`,
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
describe("Tempus Kalender API", () => {
|
||||
before(() => {
|
||||
cy.login();
|
||||
getTempusTestSemester().then((semester) => {
|
||||
TEMPUS_TEST_SEMESTER = semester;
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.login();
|
||||
tempusApi.resetTempusScenario();
|
||||
resetEventsBeforeTest();
|
||||
});
|
||||
|
||||
it("event creation works for non collision case", () => {
|
||||
tempusApi.getStudyPlansTree().then((stgTree) => {
|
||||
let studyPlan = stgTree.find((plan) =>
|
||||
plan.name.includes(TEMPUS_TEST_STUDY_PLAN_SHORT_CODE),
|
||||
plan.name.includes(TARGETED_STUDY_PLAN_SHORT_CODE),
|
||||
);
|
||||
expect(studyPlan, "study plan for test event creation").to.exist;
|
||||
|
||||
tempusApi
|
||||
.getCoursesByStudyPlan(studyPlan.studiengang_kz, TEMPUS_TEST_SEMESTER)
|
||||
.getCoursesByStudyPlan(studyPlan.studiengang_kz, "SS2026")
|
||||
.then((courses) => {
|
||||
let course = courses.find((course) => course.lehrfach === "MAT");
|
||||
expect(course, "course for test event creation").to.exist;
|
||||
@@ -60,12 +94,12 @@ describe("Tempus Kalender API", () => {
|
||||
it("prohibited event creation due to zeitsperre collision", () => {
|
||||
tempusApi.getStudyPlansTree().then((stgTree) => {
|
||||
let studyPlan = stgTree.find((plan) =>
|
||||
plan.name.includes(TEMPUS_TEST_STUDY_PLAN_SHORT_CODE),
|
||||
plan.name.includes(TARGETED_STUDY_PLAN_SHORT_CODE),
|
||||
);
|
||||
expect(studyPlan, "study plan for test event creation").to.exist;
|
||||
|
||||
tempusApi
|
||||
.getCoursesByStudyPlan(studyPlan.studiengang_kz, TEMPUS_TEST_SEMESTER)
|
||||
.getCoursesByStudyPlan(studyPlan.studiengang_kz, "SS2026")
|
||||
.then((courses) => {
|
||||
let course = courses.find((course) =>
|
||||
course.lektoren.some((lector) => lector.kurzbz === "DemoLKT1"),
|
||||
@@ -108,12 +142,12 @@ describe("Tempus Kalender API", () => {
|
||||
it("prohibited event creation due to student group collision", () => {
|
||||
tempusApi.getStudyPlansTree().then((stgTree) => {
|
||||
let studyPlan = stgTree.find((plan) =>
|
||||
plan.name.includes(TEMPUS_TEST_STUDY_PLAN_SHORT_CODE),
|
||||
plan.name.includes(TARGETED_STUDY_PLAN_SHORT_CODE),
|
||||
);
|
||||
expect(studyPlan, "study plan for test event creation").to.exist;
|
||||
|
||||
tempusApi
|
||||
.getCoursesByStudyPlan(studyPlan.studiengang_kz, TEMPUS_TEST_SEMESTER)
|
||||
.getCoursesByStudyPlan(studyPlan.studiengang_kz, "SS2026")
|
||||
.then((courses) => {
|
||||
let course = courses.find(
|
||||
(course) =>
|
||||
@@ -160,12 +194,12 @@ describe("Tempus Kalender API", () => {
|
||||
|
||||
tempusApi.getStudyPlansTree().then((stgTree) => {
|
||||
let studyPlan = stgTree.find((plan) =>
|
||||
plan.name.includes(TEMPUS_TEST_STUDY_PLAN_SHORT_CODE),
|
||||
plan.name.includes(TARGETED_STUDY_PLAN_SHORT_CODE),
|
||||
);
|
||||
expect(studyPlan, "study plan for test event creation").to.exist;
|
||||
|
||||
tempusApi
|
||||
.getCoursesByStudyPlan(studyPlan.studiengang_kz, TEMPUS_TEST_SEMESTER)
|
||||
.getCoursesByStudyPlan(studyPlan.studiengang_kz, "SS2026")
|
||||
.then((courses) => {
|
||||
let course = courses.find(
|
||||
(course) =>
|
||||
@@ -218,12 +252,12 @@ describe("Tempus Kalender API", () => {
|
||||
it("prohibited event creation due to lector collision", () => {
|
||||
tempusApi.getStudyPlansTree().then((stgTree) => {
|
||||
let studyPlan = stgTree.find((plan) =>
|
||||
plan.name.includes(TEMPUS_TEST_STUDY_PLAN_SHORT_CODE),
|
||||
plan.name.includes(TARGETED_STUDY_PLAN_SHORT_CODE),
|
||||
);
|
||||
expect(studyPlan, "study plan for test event creation").to.exist;
|
||||
|
||||
tempusApi
|
||||
.getCoursesByStudyPlan(studyPlan.studiengang_kz, TEMPUS_TEST_SEMESTER)
|
||||
.getCoursesByStudyPlan(studyPlan.studiengang_kz, "SS2026")
|
||||
.then((courses) => {
|
||||
let course = courses.find((course) =>
|
||||
course.lektoren.some((lector) => lector.kurzbz === "DemoLKT4"),
|
||||
|
||||
@@ -1,9 +1,19 @@
|
||||
import { waitForOk } from "../../../../support/helpers/network";
|
||||
import { getDateForDay } from "../../../../support/helpers/date";
|
||||
import { tempusPage } from "../../../../support/pages/tempus.po";
|
||||
import { tempusApi } from "../../../../support/api/tempusApi";
|
||||
|
||||
const TARGETED_STUDY_PLAN_SHORT_CODE = "STG5";
|
||||
|
||||
const deleteMondayEvents = () =>
|
||||
tempusApi
|
||||
.getPlannerEvents(getDateForDay("monday"), getDateForDay("monday"))
|
||||
.then((events) => {
|
||||
events.forEach((event) => {
|
||||
tempusApi.deleteKalenderEvent(event.kalender_id);
|
||||
});
|
||||
});
|
||||
|
||||
context("Tempus course picker tests", () => {
|
||||
before(() => {
|
||||
tempusPage.visitAndWaitForPlanner();
|
||||
@@ -51,7 +61,7 @@ context("Tempus course picker tests", () => {
|
||||
});
|
||||
|
||||
it("can drag and drop one course event into the calendar", () => {
|
||||
tempusApi.deletePlannerEventsForDay("monday");
|
||||
deleteMondayEvents();
|
||||
tempusPage.getCalendarSection().should("exist");
|
||||
tempusPage.waitForCalendarToFinishLoading();
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { waitForOk } from "../../../../support/helpers/network";
|
||||
import { getDateForDay } from "../../../../support/helpers/date";
|
||||
import { tempusApi } from "../../../../support/api/tempusApi";
|
||||
import {
|
||||
LEKTOR,
|
||||
@@ -12,7 +13,13 @@ context("Tempus event mutation tests", () => {
|
||||
beforeEach(() => {
|
||||
tempusPage.visitAndWaitForPlanner();
|
||||
|
||||
tempusApi.deletePlannerEventsForDay("monday");
|
||||
tempusApi
|
||||
.getPlannerEvents(getDateForDay("monday"), getDateForDay("monday"))
|
||||
.then((events) => {
|
||||
events.forEach((event) => {
|
||||
tempusApi.deleteKalenderEvent(event.kalender_id);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("room change on planner preview updates planner event, but keeps original room on other previews", () => {
|
||||
@@ -44,16 +51,52 @@ context("Tempus event mutation tests", () => {
|
||||
|
||||
tempusPage.expectCalendarEventRoom(eventId, originalRoom);
|
||||
|
||||
tempusPage.changeEventRoom(eventId, originalRoom).then((result) => {
|
||||
const { newRoom, updatedEventId } = result;
|
||||
tempusPage
|
||||
.getCalendarEventById(eventId)
|
||||
.should("be.visible")
|
||||
.rightclick();
|
||||
tempusPage.getEventContextMenuOption("Raumauswahl").click({ force: true });
|
||||
waitForOk("@fetchRoomSuggestions");
|
||||
|
||||
tempusPage.expectCalendarEventRoom(updatedEventId, newRoom);
|
||||
tempusPage
|
||||
.getRaumauswahlRoomOptions()
|
||||
.should("have.length.greaterThan", 0)
|
||||
.then(($roomOptions) => {
|
||||
const roomOption = [...$roomOptions].find((option) => {
|
||||
const room = option.innerText.trim();
|
||||
|
||||
tempusPage.selectRoleAndWait(LEKTOR);
|
||||
tempusPage.expectCalendarEventRoom(eventId, originalRoom);
|
||||
return room && room !== originalRoom;
|
||||
});
|
||||
|
||||
tempusPage.selectRoleAndWait(STUDENT);
|
||||
tempusPage.expectCalendarEventRoom(eventId, originalRoom);
|
||||
expect(roomOption, "different room suggestion").to.exist;
|
||||
|
||||
cy.wrap(roomOption.innerText.trim()).as("newRoom");
|
||||
cy.wrap(roomOption).click();
|
||||
});
|
||||
|
||||
cy.wait("@updateCalendarEvent").then((interception) => {
|
||||
expect(interception.response.statusCode).to.eq(200);
|
||||
|
||||
const updatedEventId = tempusPage.getUpdatedKalenderId(interception);
|
||||
expect(updatedEventId, "updated planner event id").to.exist;
|
||||
|
||||
cy.wrap(updatedEventId).as("updatedEventId");
|
||||
});
|
||||
waitForOk("@fetchPlanData");
|
||||
tempusPage.waitForCalendarToFinishLoading();
|
||||
|
||||
cy.get("@newRoom").then((newRoom) => {
|
||||
console.log(eventId)
|
||||
console.log(newRoom)
|
||||
cy.get("@updatedEventId").then((updatedEventId) => {
|
||||
tempusPage.expectCalendarEventRoom(updatedEventId, newRoom);
|
||||
|
||||
tempusPage.selectRoleAndWait(LEKTOR);
|
||||
tempusPage.expectCalendarEventRoom(eventId, originalRoom);
|
||||
|
||||
tempusPage.selectRoleAndWait(STUDENT);
|
||||
tempusPage.expectCalendarEventRoom(eventId, originalRoom);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -85,19 +128,54 @@ context("Tempus event mutation tests", () => {
|
||||
expect(originalRoom, "original event room").to.be.a("string").and.not.be
|
||||
.empty;
|
||||
|
||||
tempusPage.changeEventRoom(eventId, originalRoom).then((result) => {
|
||||
const { newRoom, updatedEventId } = result;
|
||||
tempusPage
|
||||
.getCalendarEventById(eventId)
|
||||
.scrollIntoView()
|
||||
.should("be.visible")
|
||||
.rightclick();
|
||||
tempusPage.getEventContextMenuOption("Raumauswahl").click({ force: true });
|
||||
waitForOk("@fetchRoomSuggestions");
|
||||
|
||||
tempusPage.expectCalendarEventRoom(updatedEventId, newRoom);
|
||||
tempusPage
|
||||
.getRaumauswahlRoomOptions()
|
||||
.should("have.length.greaterThan", 0)
|
||||
.then(($roomOptions) => {
|
||||
const roomOption = [...$roomOptions].find((option) => {
|
||||
const room = option.innerText.trim();
|
||||
|
||||
tempusPage.syncAndReloadPlanner();
|
||||
tempusPage.expectCalendarEventRoom(updatedEventId, newRoom);
|
||||
return room && room !== originalRoom;
|
||||
});
|
||||
|
||||
tempusPage.selectRoleAndWait(LEKTOR);
|
||||
tempusPage.expectCalendarEventRoom(updatedEventId, newRoom);
|
||||
expect(roomOption, "different room suggestion").to.exist;
|
||||
|
||||
tempusPage.selectRoleAndWait(STUDENT);
|
||||
tempusPage.expectCalendarEventRoom(updatedEventId, newRoom);
|
||||
cy.wrap(roomOption.innerText.trim()).as("newRoom");
|
||||
cy.wrap(roomOption).click();
|
||||
});
|
||||
|
||||
cy.wait("@updateCalendarEvent").then((interception) => {
|
||||
expect(interception.response.statusCode).to.eq(200);
|
||||
|
||||
const updatedEventId = tempusPage.getUpdatedKalenderId(interception);
|
||||
expect(updatedEventId, "updated planner event id").to.exist;
|
||||
|
||||
cy.wrap(updatedEventId).as("updatedEventId");
|
||||
});
|
||||
waitForOk("@fetchPlanData");
|
||||
tempusPage.waitForCalendarToFinishLoading();
|
||||
|
||||
cy.get("@newRoom").then((newRoom) => {
|
||||
cy.get("@updatedEventId").then((updatedEventId) => {
|
||||
tempusPage.expectCalendarEventRoom(updatedEventId, newRoom);
|
||||
|
||||
tempusPage.syncAndReloadPlanner();
|
||||
tempusPage.expectCalendarEventRoom(updatedEventId, newRoom);
|
||||
|
||||
tempusPage.selectRoleAndWait(LEKTOR);
|
||||
tempusPage.expectCalendarEventRoom(updatedEventId, newRoom);
|
||||
|
||||
tempusPage.selectRoleAndWait(STUDENT);
|
||||
tempusPage.expectCalendarEventRoom(updatedEventId, newRoom);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -45,7 +45,7 @@ context("Tempus filter tests", () => {
|
||||
selectedRoom,
|
||||
);
|
||||
cy.wrap($event)
|
||||
.find("[data-cy='calendar-event-room']")
|
||||
.find(".event-place")
|
||||
.invoke("text")
|
||||
.then((eventPlace) => {
|
||||
expect(eventPlace.trim(), "event body room").to.eq(selectedRoom);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { waitForOk } from "../../../../support/helpers/network";
|
||||
import { getDateForDay } from "../../../../support/helpers/date";
|
||||
import { tempusApi } from "../../../../support/api/tempusApi";
|
||||
import {
|
||||
LEKTOR,
|
||||
@@ -11,7 +12,13 @@ context("Tempus role preview tests", () => {
|
||||
beforeEach(() => {
|
||||
tempusPage.visitAndWaitForPlanner();
|
||||
|
||||
tempusApi.deletePlannerEventsForDay("monday");
|
||||
tempusApi
|
||||
.getPlannerEvents(getDateForDay("monday"), getDateForDay("monday"))
|
||||
.then((events) => {
|
||||
events.forEach((event) => {
|
||||
tempusApi.deleteKalenderEvent(event.kalender_id);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("shows the same number of calendar events for all role previews", () => {
|
||||
|
||||
@@ -44,7 +44,7 @@ context("Tempus smoke tests", () => {
|
||||
tempusPage.getEventContextMenu().should("be.visible");
|
||||
});
|
||||
|
||||
it("shows room selection modal when selecting 'room selection' from event context menu", () => {
|
||||
it("shows Raumauswahl modal when selecting Raumauswahl from event context menu", () => {
|
||||
tempusPage.waitForCalendarToFinishLoading();
|
||||
tempusPage
|
||||
.getCalendarEventsWithLehreinheit()
|
||||
@@ -54,7 +54,7 @@ context("Tempus smoke tests", () => {
|
||||
tempusPage.getEventContextMenuOption("Raumauswahl").click({ force: true });
|
||||
waitForOk("@fetchRoomSuggestions");
|
||||
|
||||
tempusPage.getRoomSelectionModal().should("be.visible");
|
||||
tempusPage.getRaumauswahlModal().should("be.visible");
|
||||
});
|
||||
|
||||
it("shows resources modal when selecting Ressourcen zuordnen from event context menu", () => {
|
||||
|
||||
@@ -1,25 +1,5 @@
|
||||
import { getDateForDay } from "../helpers/date";
|
||||
|
||||
const KALENDER_API = "/index.ci.php/api/frontend/v1/tempus";
|
||||
|
||||
const updatePlannerEventsForDay = (day, predicate, startTime, endTime) => {
|
||||
const date = getDateForDay(day);
|
||||
|
||||
return tempusApi.getPlannerEvents(date, date).then((events) =>
|
||||
cy.wrap(events).each((event) => {
|
||||
if (!predicate(event)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return tempusApi.updateKalenderEvent(
|
||||
event.kalender_id,
|
||||
`${event.datum} ${startTime}`,
|
||||
`${event.datum} ${endTime}`,
|
||||
);
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
export const tempusApi = {
|
||||
getStudyPlansTree: () =>
|
||||
cy
|
||||
@@ -35,23 +15,6 @@ export const tempusApi = {
|
||||
return response.body.data;
|
||||
}),
|
||||
|
||||
getStudySemesters: () =>
|
||||
cy
|
||||
.request({
|
||||
method: "GET",
|
||||
url: `/index.ci.php/api/frontend/v1/organisation/Studiensemester/getAll`,
|
||||
qs: {
|
||||
order: "DESC",
|
||||
},
|
||||
})
|
||||
.then((response) => {
|
||||
expect(response.status).to.eq(200);
|
||||
expect(response.body).to.have.nested.property("meta.status", "success");
|
||||
expect(response.body.data).to.be.an("array");
|
||||
|
||||
return response.body.data;
|
||||
}),
|
||||
|
||||
getCoursesByStudyPlan: (studyPlanId, semesterShortCode) =>
|
||||
cy
|
||||
.request({
|
||||
@@ -88,43 +51,6 @@ export const tempusApi = {
|
||||
return response.body.data;
|
||||
}),
|
||||
|
||||
deletePlannerEventsForDay: (day) => {
|
||||
const date = getDateForDay(day);
|
||||
|
||||
return tempusApi.getPlannerEvents(date, date).then((events) =>
|
||||
cy.wrap(events).each((event) =>
|
||||
tempusApi.deleteKalenderEvent(event.kalender_id),
|
||||
),
|
||||
);
|
||||
},
|
||||
|
||||
resetTempusScenario: () =>
|
||||
tempusApi
|
||||
.deletePlannerEventsForDay("monday")
|
||||
.then(() =>
|
||||
updatePlannerEventsForDay(
|
||||
"tuesday",
|
||||
(event) =>
|
||||
event.type === "lehreinheit" &&
|
||||
event.beginn === "20:15:00" &&
|
||||
event.ende === "21:00:00",
|
||||
"19:30",
|
||||
"20:15",
|
||||
),
|
||||
)
|
||||
.then(() =>
|
||||
updatePlannerEventsForDay(
|
||||
"sunday",
|
||||
(event) =>
|
||||
event.type === "lehreinheit" &&
|
||||
event.beginn === "18:35:00" &&
|
||||
event.ende === "19:20:00" &&
|
||||
event.lektor?.some((lector) => lector.kurzbz === "DemoLKT1"),
|
||||
"17:50",
|
||||
"18:35",
|
||||
),
|
||||
),
|
||||
|
||||
createKalenderEvent: (lehreinheitId, startDateTime, endDateTime) =>
|
||||
cy.request({
|
||||
method: "POST",
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
import { tempusApi } from "../api/tempusApi";
|
||||
|
||||
export const TEMPUS_TEST_STUDY_PLAN_SHORT_CODE = "STG5";
|
||||
|
||||
const getLocalDateString = () => {
|
||||
const today = new Date();
|
||||
const year = today.getFullYear();
|
||||
const month = String(today.getMonth() + 1).padStart(2, "0");
|
||||
const day = String(today.getDate()).padStart(2, "0");
|
||||
|
||||
return `${year}-${month}-${day}`;
|
||||
};
|
||||
|
||||
const getSemesterStartDate = (semester) => semester.start?.slice(0, 10);
|
||||
|
||||
export const getTempusTestSemester = () =>
|
||||
tempusApi.getStudySemesters().then((semesters) => {
|
||||
const today = getLocalDateString();
|
||||
const activeSemester = semesters
|
||||
.filter((semester) => {
|
||||
const startDate = getSemesterStartDate(semester);
|
||||
|
||||
return startDate && startDate <= today;
|
||||
})
|
||||
.sort((a, b) =>
|
||||
getSemesterStartDate(b).localeCompare(getSemesterStartDate(a)),
|
||||
)[0];
|
||||
|
||||
expect(
|
||||
activeSemester,
|
||||
`Tempus test semester starting on or before ${today}`,
|
||||
).to.exist;
|
||||
|
||||
return activeSemester.studiensemester_kurzbz;
|
||||
});
|
||||
@@ -22,7 +22,7 @@ const roleFetchAliases = {
|
||||
|
||||
class TempusPage {
|
||||
selectors = {
|
||||
calendarBaseGrid: "div[data-cy='tempus'] [data-cy='calendar-base-grid']",
|
||||
calendarBaseGrid: "div[data-cy='tempus'] .fhc-calendar-base-grid",
|
||||
parkingSlot: "div[data-cy='tempus'] #parkingslot",
|
||||
};
|
||||
|
||||
@@ -108,26 +108,22 @@ class TempusPage {
|
||||
getCalendarSection = () =>
|
||||
this.getTempusOverview().find(".fhc-calendar-base");
|
||||
getCalendarBaseGrid = () =>
|
||||
this.getCalendarSection().find("[data-cy='calendar-base-grid']");
|
||||
this.getCalendarSection().find(".fhc-calendar-base-grid");
|
||||
getCoursePicker = () => this.getTempusOverview().find(".course-picker");
|
||||
getPreviewRoleOptionsHolder = () =>
|
||||
this.getTempusOverview().find("[data-cy='previewRoleOptionsHolder']");
|
||||
getAllCoursesSliderBtn = () =>
|
||||
this.getSidebarMenu().find("button[title='Verband']").first();
|
||||
getCourseTreeRows = () =>
|
||||
this.getSlideInCoursesMenu()
|
||||
.find("[data-cy='course-tree-row']")
|
||||
.closest("[role='row']");
|
||||
getCourseTreeRowByName = (courseShortName) =>
|
||||
this.getSlideInCoursesMenu()
|
||||
.contains("[data-cy='course-tree-row']", courseShortName)
|
||||
.closest("[role='row']");
|
||||
this.getSlideInCoursesMenu().find(".p-treetable-tbody tr");
|
||||
getCoursePickerRows = () => this.getCoursePicker().find(".course-picker-row");
|
||||
getCoursePickerSearchInput = () => this.getCoursePicker().find("input");
|
||||
getCalendarEventsPerWeekHolders = () =>
|
||||
this.getCalendarBaseGrid().find(".fhc-calendar-base-grid-line");
|
||||
getCalendarEvents = () =>
|
||||
this.getCalendarSection().find("[data-cy='calendar-event']");
|
||||
this.getCalendarSection().then(($calendar) => {
|
||||
return $calendar.find(".fhc-calendar-base-grid-line-event");
|
||||
});
|
||||
getLecturerWishOverlays = () =>
|
||||
this.getCalendarSection().find(".bg-lecturer-wish");
|
||||
getCalendarEventsWithRoom = () =>
|
||||
@@ -199,7 +195,7 @@ class TempusPage {
|
||||
getCalendarEventById = (id) =>
|
||||
this.getCalendarEvents().filter(`div[data-id="event-${id}"]`);
|
||||
getCalendarPartDropTarget = (partIndex) =>
|
||||
`${this.selectors.calendarBaseGrid} [data-cy='calendar-grid-part'][data-drop-index='${partIndex}']`;
|
||||
`${this.selectors.calendarBaseGrid} .part-body:nth-of-type(${partIndex})`;
|
||||
getEventGridRowFromStyle = (style) =>
|
||||
/grid-row:\s*([^;]+)/.exec(style)?.[1]?.trim();
|
||||
getEventGridRow = (id) =>
|
||||
@@ -209,7 +205,7 @@ class TempusPage {
|
||||
getCalendarEventsByWeekday = (weekday) =>
|
||||
this.getCalendarEventsPerWeekHolders()
|
||||
.eq(weekdayToGridRowMap[weekday] - 1)
|
||||
.find("[data-cy='calendar-event']");
|
||||
.find(".fhc-calendar-base-grid-line-event");
|
||||
getCalendarEventsByStartTime = (startTime) =>
|
||||
this.getCalendarEvents().filter((index, event) => {
|
||||
const eventData = JSON.parse(
|
||||
@@ -266,54 +262,12 @@ class TempusPage {
|
||||
|
||||
return retval?.kalender_id ?? retval;
|
||||
};
|
||||
chooseDifferentRoomForEvent = (eventId, originalRoom) => {
|
||||
this.getCalendarEventById(eventId)
|
||||
.scrollIntoView()
|
||||
.should("be.visible")
|
||||
.rightclick();
|
||||
this.getEventContextMenuOption("Raumauswahl").click({ force: true });
|
||||
waitForOk("@fetchRoomSuggestions");
|
||||
|
||||
return this.getRaumauswahlRoomOptions()
|
||||
.should("have.length.greaterThan", 0)
|
||||
.then(($roomOptions) => {
|
||||
const roomOption = [...$roomOptions].find((option) => {
|
||||
const room = option.innerText.trim();
|
||||
|
||||
return room && room !== originalRoom;
|
||||
});
|
||||
|
||||
expect(roomOption, "different room suggestion").to.exist;
|
||||
|
||||
const newRoom = roomOption.innerText.trim();
|
||||
|
||||
return cy.wrap(roomOption).click().then(() => newRoom);
|
||||
});
|
||||
};
|
||||
waitForUpdatedEventId = () =>
|
||||
cy.wait("@updateCalendarEvent").then((interception) => {
|
||||
expect(interception.response.statusCode).to.eq(200);
|
||||
|
||||
const updatedEventId = this.getUpdatedKalenderId(interception);
|
||||
expect(updatedEventId, "updated planner event id").to.exist;
|
||||
|
||||
return updatedEventId;
|
||||
});
|
||||
changeEventRoom = (eventId, originalRoom) =>
|
||||
this.chooseDifferentRoomForEvent(eventId, originalRoom).then((newRoom) =>
|
||||
this.waitForUpdatedEventId().then((updatedEventId) => {
|
||||
waitForOk("@fetchPlanData");
|
||||
this.waitForCalendarToFinishLoading();
|
||||
|
||||
return cy.wrap({ newRoom, updatedEventId });
|
||||
}),
|
||||
);
|
||||
getMondayFirstColumnEventData = ($body) =>
|
||||
[
|
||||
...$body
|
||||
.find(`${this.selectors.calendarBaseGrid} .fhc-calendar-base-grid-line`)
|
||||
.first()
|
||||
.find("[data-cy='calendar-event']"),
|
||||
.find(".fhc-calendar-base-grid-line-event"),
|
||||
]
|
||||
.map((event) => {
|
||||
const eventJSON = event.getAttribute("data-fhc-draggable-value");
|
||||
@@ -332,18 +286,18 @@ class TempusPage {
|
||||
getEventContextMenu = () => cy.get("[data-cy='eventContextMenu']");
|
||||
getEventContextMenuOption = (option) =>
|
||||
this.getEventContextMenu().contains("button", option);
|
||||
getRoomSelectionModal = () =>
|
||||
getRaumauswahlModal = () =>
|
||||
cy
|
||||
.contains(".bootstrap-modal.show .modal-title", "Raumauswahl")
|
||||
.closest(".bootstrap-modal.show");
|
||||
getRaumauswahlRoomOptions = () =>
|
||||
this.getRoomSelectionModal().find(".list-group-item span");
|
||||
this.getRaumauswahlModal().find(".list-group-item span");
|
||||
getResourcesModal = () =>
|
||||
cy
|
||||
.get("[data-cy='resourcesAssignmentModal']")
|
||||
.closest(".bootstrap-modal.show");
|
||||
getCalendarEventRoom = (id) =>
|
||||
this.getCalendarEventById(id).find("[data-cy='calendar-event-room']");
|
||||
this.getCalendarEventById(id).find(".event-place");
|
||||
getStundenrasterToggle = () =>
|
||||
cy.contains(".form-check-label", "Stundenraster").parent();
|
||||
getHistoryModal = () => cy.get("[data-cy='historyModal']");
|
||||
@@ -351,7 +305,7 @@ class TempusPage {
|
||||
getReservationModal = () => cy.get("[data-cy='reservationModal']");
|
||||
getEventParkingSlot = () => this.getSidebarMenu().find("#parkingslot");
|
||||
getParkedEvents = () =>
|
||||
this.getEventParkingSlot().find("[data-cy='calendar-event']");
|
||||
this.getEventParkingSlot().find(".fhc-calendar-base-grid-line-event");
|
||||
getPreviewRoleButton = (role) =>
|
||||
this.getPreviewRoleOptionsHolder().contains("button", role);
|
||||
|
||||
@@ -370,7 +324,7 @@ class TempusPage {
|
||||
|
||||
selectCourseByName = (courseShortName) => {
|
||||
this.openCoursesMenu();
|
||||
this.getCourseTreeRowByName(courseShortName).click();
|
||||
this.getCourseTreeRows().contains(courseShortName).click();
|
||||
};
|
||||
|
||||
selectPreviewRole = (role) => {
|
||||
|
||||
+54
-32
@@ -8,6 +8,8 @@ require_once(dirname(__FILE__).'/../include/datum.class.php');
|
||||
*/
|
||||
class MySabre_CalDAV_Backend extends \Sabre\CalDAV\Backend\AbstractBackend
|
||||
{
|
||||
protected $auth;
|
||||
|
||||
/**
|
||||
* Creates the backend
|
||||
*
|
||||
@@ -54,12 +56,13 @@ class MySabre_CalDAV_Backend extends \Sabre\CalDAV\Backend\AbstractBackend
|
||||
'uri' => 'LVPlan-'.$user,
|
||||
'principaluri' => 'principals/'.$user,
|
||||
'{' . \Sabre\CalDAV\Plugin::NS_CALENDARSERVER . '}getctag' => 'LVPlan-'.$user.'-'.time(),
|
||||
'{' . \Sabre\CalDAV\Plugin::NS_CALDAV . '}supported-calendar-component-set' => new \Sabre\CalDAV\Property\SupportedCalendarComponentSet(array('VEVENT','VTODO')),
|
||||
'{' . \Sabre\CalDAV\Plugin::NS_CALDAV . '}supported-calendar-component-set' => new \Sabre\CalDAV\Xml\Property\SupportedCalendarComponentSet(array('VEVENT','VTODO')),
|
||||
'{DAV:}displayname' => 'LVPlan',
|
||||
'{urn:ietf:params:xml:ns:caldav}calendar-description' => 'description comes here',
|
||||
'{urn:ietf:params:xml:ns:caldav}calendar-timezone' => 'Europe/Vienna',
|
||||
'{http://apple.com/ns/ical/}calendar-order' => '1',
|
||||
'{http://apple.com/ns/ical/}calendar-color' => '#FF0000'
|
||||
'{http://apple.com/ns/ical/}calendar-color' => '#FF0000',
|
||||
'{http://sabredav.org/ns}read-only' => 1
|
||||
);
|
||||
$calendars[] = $calendar;
|
||||
|
||||
@@ -117,9 +120,9 @@ class MySabre_CalDAV_Backend extends \Sabre\CalDAV\Backend\AbstractBackend
|
||||
* @param array $mutations
|
||||
* @return bool|array
|
||||
*/
|
||||
public function updateCalendar($calendarId, array $mutations)
|
||||
public function updateCalendar($calendarId, \Sabre\DAV\PropPatch $propPatch)
|
||||
{
|
||||
return false;
|
||||
$propPatch->setRemainingResultCode(403);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -213,7 +216,7 @@ class MySabre_CalDAV_Backend extends \Sabre\CalDAV\Backend\AbstractBackend
|
||||
foreach($val as $row)
|
||||
{
|
||||
//einzelnen Eintrag holen
|
||||
if($row['dtstart']==$dtstart && ($row['unr'][0]==$unr) || $unr=='R'.$row['reservierung_id'])
|
||||
if($row['dtstart']==$dtstart && (($row['unr'][0]==$unr) || $unr=='R'.$row['reservierung_id']))
|
||||
{
|
||||
return $row;
|
||||
}
|
||||
@@ -251,6 +254,48 @@ TZOFFSETTO:+0100
|
||||
END:STANDARD
|
||||
END:VTIMEZONE\n".$event."\nEND:VCALENDAR";
|
||||
}
|
||||
|
||||
protected function getObjectUri($row)
|
||||
{
|
||||
// Reservierungen werden mit einem R markiert und mit der ReservierungID da sonst
|
||||
// Termine verloren gehen koennen wenn zur selben Zeit eine Reservierung und ein LVPlan Eintrag vorhanden ist
|
||||
if($row['reservierung'])
|
||||
$uri = $row['dtstart'].'-R'.$row['reservierung_id'];
|
||||
else
|
||||
$uri = $row['dtstart'].'-'.$row['unr'][0];
|
||||
|
||||
return $uri.'@'.md5($row['UID']);
|
||||
}
|
||||
|
||||
protected function buildCalendarObject($row, $calendarId)
|
||||
{
|
||||
$calendarData = $this->makeCal($row['data']);
|
||||
|
||||
return array("id"=>$row['UID'],
|
||||
"calendardata"=>$calendarData,
|
||||
"uri"=>$this->getObjectUri($row),
|
||||
"lastmodified"=>$this->getLastModifiedTimestamp($row['updateamum']),
|
||||
"etag"=>'"'.$row['UID'].'"',
|
||||
"calendarid"=>$calendarId,
|
||||
"size"=>strlen($calendarData),
|
||||
"component"=>'vevent');
|
||||
}
|
||||
|
||||
protected function getLastModifiedTimestamp($lastModified)
|
||||
{
|
||||
if($lastModified === null || $lastModified === '')
|
||||
return null;
|
||||
|
||||
if(is_numeric($lastModified))
|
||||
return (int)$lastModified;
|
||||
|
||||
$timestamp = strtotime($lastModified);
|
||||
if($timestamp === false)
|
||||
return null;
|
||||
|
||||
return $timestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all calendar objects within a calendar.
|
||||
*
|
||||
@@ -283,20 +328,7 @@ END:VTIMEZONE\n".$event."\nEND:VCALENDAR";
|
||||
$return = array();
|
||||
foreach($data as $row)
|
||||
{
|
||||
// Reservierungen werden mit einem R markiert und mit der ReservierungID da sonst
|
||||
// Termine verloren gehen koennen wenn zur selben Zeit eine Reservierung und ein LVPlan Eintrag vorhanden ist
|
||||
if($row['reservierung'])
|
||||
$uri = $row['dtstart'].'-R'.$row['reservierung_id'];
|
||||
else
|
||||
$uri = $row['dtstart'].'-'.$row['unr'][0];
|
||||
|
||||
$return[] = array("id"=>$row['UID'],
|
||||
"calendardata"=>$this->makeCal($row['data']),
|
||||
"uri"=>$uri.'@'.md5($row['UID']),
|
||||
"lastmodified"=>$row['updateamum'],
|
||||
"etag"=>'"'.$row['UID'].'"',
|
||||
"calendarid"=>$calendarId);
|
||||
|
||||
$return[] = $this->buildCalendarObject($row, $calendarId);
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
@@ -319,23 +351,13 @@ END:VTIMEZONE\n".$event."\nEND:VCALENDAR";
|
||||
//$user = $this->getUser();
|
||||
$user = $calendarId;
|
||||
$data = $this->getCalendarData($user,$objectUri);
|
||||
if(count($data)==0)
|
||||
if(empty($data))
|
||||
{
|
||||
$ret=array("id"=>'',
|
||||
"calendardata"=>'',
|
||||
"uri"=>'',
|
||||
"lastmodified"=>'',
|
||||
"etag"=>'',
|
||||
"calendarid"=>$calendarId);
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
$ret = array("id"=>$data['UID'],
|
||||
"calendardata"=>$this->makeCal($data['data']),
|
||||
"uri"=>'principals/'.$user.'/LVPlan/'.$data['dtstart'].'-'.$data['unr'][0].'@'.md5($data['UID']),
|
||||
"lastmodified"=>$data['updateamum'],
|
||||
"etag"=>'"'.$data['UID'].'"',
|
||||
"calendarid"=>$calendarId);
|
||||
$ret = $this->buildCalendarObject($data, $calendarId);
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Browser plugin variant that keeps SabreDAV's HTML overview but hides the
|
||||
* verbose WebDAV properties table.
|
||||
*/
|
||||
class MySabre_DAV_Browser_NoProperties extends \Sabre\DAV\Browser\Plugin
|
||||
{
|
||||
public function generateDirectoryIndex($path)
|
||||
{
|
||||
$html = parent::generateDirectoryIndex($path);
|
||||
|
||||
$cleanHtml = preg_replace(
|
||||
'#<section><h1>Properties</h1>.*?</section>#s',
|
||||
'',
|
||||
$html,
|
||||
1
|
||||
);
|
||||
|
||||
$cleanHtml = preg_replace(
|
||||
'#<section><h1>Actions</h1>.*?</section>#s',
|
||||
'',
|
||||
$cleanHtml,
|
||||
1
|
||||
);
|
||||
|
||||
return $cleanHtml === null ? $html : $cleanHtml;
|
||||
}
|
||||
}
|
||||
+10
-14
@@ -32,6 +32,7 @@ class MySabre_DAVACL_PrincipalBackend implements \Sabre\DAVACL\PrincipalBackend\
|
||||
protected $groupMembersTableName;
|
||||
|
||||
protected $result_ma;
|
||||
protected $auth;
|
||||
/**
|
||||
* Sets up the backend.
|
||||
*
|
||||
@@ -121,16 +122,6 @@ class MySabre_DAVACL_PrincipalBackend implements \Sabre\DAVACL\PrincipalBackend\
|
||||
|
||||
}*/
|
||||
}
|
||||
else //if($prefixPath=='principals/oesi')
|
||||
{
|
||||
$user = mb_substr($path,11);
|
||||
$principals[] = array(
|
||||
'id' => $user.'proxyread',
|
||||
'uri' => 'principals/'.$user.'/calendar-proxy-read',
|
||||
'{DAV:}displayname' => '',
|
||||
'{http://sabredav.org/ns}email-address' => '',
|
||||
);
|
||||
}
|
||||
|
||||
return $principals;
|
||||
|
||||
@@ -226,13 +217,18 @@ class MySabre_DAVACL_PrincipalBackend implements \Sabre\DAVACL\PrincipalBackend\
|
||||
throw new \Sabre\DAV\Exception('Not implemented');
|
||||
}
|
||||
|
||||
public function updatePrincipal($path, $mutations)
|
||||
public function updatePrincipal($path, \Sabre\DAV\PropPatch $propPatch)
|
||||
{
|
||||
throw new \Sabre\DAV\Exception('Not implemented');
|
||||
$propPatch->setRemainingResultCode(403);
|
||||
}
|
||||
|
||||
public function searchPrincipals($prefixPath,array $searchProperties)
|
||||
public function searchPrincipals($prefixPath, array $searchProperties, $test = 'allof')
|
||||
{
|
||||
throw new \Sabre\DAV\Exception('Not implemented');
|
||||
return array();
|
||||
}
|
||||
|
||||
public function findByUri($uri, $principalPrefix)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,12 +25,25 @@ require_once(dirname(__FILE__).'/../include/functions.inc.php');
|
||||
|
||||
class myauth extends \Sabre\DAV\Auth\Backend\AbstractBasic
|
||||
{
|
||||
protected $currentUser = null;
|
||||
|
||||
function validateUserPass($username, $password)
|
||||
{
|
||||
if(checkldapuser($username,$password))
|
||||
{
|
||||
$this->currentUser = $username;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->currentUser = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function getCurrentUser()
|
||||
{
|
||||
return $this->currentUser;
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
+6
-5
@@ -1,10 +1,11 @@
|
||||
<?php
|
||||
|
||||
// Files we need
|
||||
require_once '../include/sabredav/lib/Sabre/autoload.php';
|
||||
require_once dirname(__DIR__).'/vendor/autoload.php';
|
||||
require_once 'auth.class.php';
|
||||
require_once 'Caldav_Backend.php';
|
||||
require_once('Principal.php');
|
||||
require_once 'MySabre_DAV_Browser_NoProperties.php';
|
||||
/*
|
||||
//PHP Error To Exception
|
||||
function exception_error_handler($errno, $errstr, $errfile, $errline ) {
|
||||
@@ -19,7 +20,7 @@ $calendarBackend = new MySabre_CalDAV_Backend($authBackend);
|
||||
|
||||
$tree = array(
|
||||
new \Sabre\CalDAV\Principal\Collection($principalBackend),
|
||||
new \Sabre\CalDAV\CalendarRootNode($principalBackend, $calendarBackend)
|
||||
new \Sabre\CalDAV\CalendarRoot($principalBackend, $calendarBackend)
|
||||
);
|
||||
|
||||
// The object tree needs in turn to be passed to the server class
|
||||
@@ -32,7 +33,8 @@ $path = str_replace($_SERVER['DOCUMENT_ROOT'],'',__FILE__).'/';
|
||||
$server->setBaseUri($path);
|
||||
|
||||
// Authentication plugin
|
||||
$authPlugin = new \Sabre\DAV\Auth\Plugin($authBackend,'SabreDAV');
|
||||
$authBackend->setRealm('SabreDAV');
|
||||
$authPlugin = new \Sabre\DAV\Auth\Plugin($authBackend);
|
||||
$server->addPlugin($authPlugin);
|
||||
|
||||
// CalDAV plugin
|
||||
@@ -44,9 +46,8 @@ $aclPlugin = new \Sabre\DAVACL\Plugin();
|
||||
$server->addPlugin($aclPlugin);
|
||||
|
||||
// Support for html frontend
|
||||
$browser = new \Sabre\DAV\Browser\Plugin();
|
||||
$browser = new MySabre_DAV_Browser_NoProperties();
|
||||
$server->addPlugin($browser);
|
||||
|
||||
// And off we go!
|
||||
$server->exec();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user