Caldav Schnittstelle für LVPlan

This commit is contained in:
Andreas Österreicher
2012-03-22 13:14:19 +00:00
parent 5a657195ad
commit 9e9d14f3dd
8 changed files with 649 additions and 23 deletions
+2 -2
View File
@@ -37,7 +37,7 @@ if (!$uid=get_uid())
$sql_query="SET search_path TO campus; SELECT titelpre, titelpost, uid, nachname, vorname FROM vw_benutzer WHERE uid LIKE '$uid'";
$sql_query="SELECT titelpre, titelpost, uid, nachname, vorname FROM campus.vw_benutzer WHERE uid LIKE '$uid'";
//echo $sql_query;
$result=$db->db_query($sql_query);
@@ -71,7 +71,7 @@ if(!$result_ort)
die("ort not found!");
$num_rows_ort=$db->db_num_rows($result_ort);
$sql_query="SELECT uid, kurzbz FROM vw_mitarbeiter ORDER BY kurzbz";
$sql_query="SELECT uid, kurzbz FROM campus.vw_mitarbeiter ORDER BY kurzbz";
$result_lektor=$db->db_query($sql_query);
if(!$result_lektor)
die("lektor not found!");
+34 -8
View File
@@ -1907,6 +1907,7 @@ class wochenplan extends basis_db
*/
public function draw_week_csv($target, $lvplan_kategorie)
{
$return = array();
if (!date("w",$this->datum))
$this->datum=jump_day($this->datum,1);
$num_rows_stunde=$this->db_num_rows($this->stunde);
@@ -2161,17 +2162,39 @@ class wochenplan extends basis_db
$start_date_time_ical = $sda[2].$sda[1].$sda[0].'T'.sprintf('%02s',($sta[0])).$sta[1].$sta[2]; //neu gruppieren der Startzeit und des Startdatums
$end_date_time_ical = $eda[2].$eda[1].$eda[0].'T'.sprintf('%02s',($eta[0])).$eta[1].$eta[2]; //neu gruppieren der Startzeit und des Startdatums
echo $this->crlf,'FREEBUSY: ',$start_date_time_ical,'/',$end_date_time_ical;
/*
echo $this->crlf.'BEGIN:VEVENT'.$this->crlf
.'UID:'.'FH'.$lvb.$this->std_plan[$i][$j][$idx]->ort.$this->std_plan[$i][$j][$idx]->lektor.$lehrfach[$idx].$start_date_time_ical.$this->crlf
.'SUMMARY:'.$lehrfach[$idx].' '.$this->std_plan[$i][$j][$idx]->ort.' - '.$lvb.$this->crlf
.'DESCRIPTION:'.$lehrfach[$idx].'\n'.$this->std_plan[$i][$j][$idx]->lektor.'\n'.$lvb.'\n'.$this->std_plan[$i][$j][$idx]->ort.$this->crlf
}
elseif ($target=='return')
{
$sda = explode(".",$start_date); //sda start date array
$sta = explode(":",$start_time); //sta start time array
$eda = explode(".",$end_date); //eda end date array
$eta = explode(":",$end_time); //eta end time array
//Die Zeitzone muss angegeben werden, da sonst der Google Kalender die Endzeiten nicht richtig erkennt
// diese wird in stpl_kalender global definiert und bei den Start und Ende Zeiten mitangegeben
$start_date_time_ical = $sda[2].$sda[1].$sda[0].'T'.sprintf('%02s',($sta[0])).$sta[1].$sta[2]; //neu gruppieren der Startzeit und des Startdatums
$end_date_time_ical = $eda[2].$eda[1].$eda[0].'T'.sprintf('%02s',($eta[0])).$eta[1].$eta[2]; //neu gruppieren der Startzeit und des Startdatums
$UID = 'FH'.$lvb.$this->std_plan[$i][$j][$idx]->ort.$this->std_plan[$i][$j][$idx]->lektor.$lehrfach[$idx].$start_date_time_ical;
$Summary = $lehrfach[$idx].' '.$this->std_plan[$i][$j][$idx]->ort.' - '.$lvb;
$description = $lehrfach[$idx].'\n'.$this->std_plan[$i][$j][$idx]->lektor.'\n'.$lvb.'\n'.$this->std_plan[$i][$j][$idx]->ort;
$return[]=array('UID'=>$UID,
'unr'=>$unr,
'Summary'=>$Summary,
'Description'=>$description,
'dtstart'=>$start_date_time_ical,
'dtend'=>$end_date_time_ical,
'updateamum'=>$this->std_plan[$i][$j][$idx]->updateamum,
'data'=>'BEGIN:VEVENT'.$this->crlf
.'UID:'.$UID.$this->crlf
.'SUMMARY:'.$Summary.$this->crlf
.'DESCRIPTION:'.$description.$this->crlf
.'LOCATION:'.$this->std_plan[$i][$j][$idx]->ort.$this->crlf
.'CATEGORIES:'.$lvplan_kategorie.$this->crlf
.'DTSTART;TZID=Europe/Vienna:'.$start_date_time_ical.$this->crlf
.'DTEND;TZID=Europe/Vienna:'.$end_date_time_ical.$this->crlf
.'END:VEVENT';
*/
.'END:VEVENT');
}
else
{
@@ -2184,7 +2207,10 @@ class wochenplan extends basis_db
}
$this->datum=jump_day($this->datum, 1);
}
return true;
if($target=='return')
return $return;
else
return true;
}
/**
+358
View File
@@ -0,0 +1,358 @@
<?php
require_once(dirname(__FILE__).'/../include/wochenplan.class.php');
/**
* CalDAV backend
*/
class MySabre_CalDAV_Backend extends Sabre_CalDAV_Backend_Abstract
{
/**
* Creates the backend
*
* @param AuthBackend $auth
*/
public function __construct($auth)
{
$this->auth = $auth;
}
/**
* 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)
{
//error_log("Caldav_Backend.php/getCalendarsForUser($principalUri)");
$user = $this->getUser();
$calendars = array();
$calendar = array(
'id' => $user,
'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')),
'{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'
);
$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)
{
throw new Sabre_DAV_Exception('Not Implemented');
}
/**
* 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, array $mutations)
{
return false;
}
/**
* Delete a calendar and all it's objects
*
* @param string $calendarId
* @return void
*/
public function deleteCalendar($calendarId)
{
throw new Sabre_DAV_Exception('Not Implemented');
}
public function getCalendarData($user, $objectUri=null)
{
$bn = new benutzer();
if(!$bn->load($user))
die('User invalid');
if(check_lektor($user))
$type='lektor';
else
$type='student';
// Stundenplanobjekt erzeugen
$stdplan = new wochenplan($type);
$stdplan->crlf="\n";
// Zusaetzliche Daten laden
if(!$stdplan->load_data($type,$user))
{
die($stdplan->errormsg);
}
if(!is_null($objectUri))
{
$unr = mb_substr($objectUri, mb_strpos($objectUri,'-')+1);
$dtstart = mb_substr($objectUri,0,mb_strpos($objectUri,'-'));
//dtstart: 19700325T020000Z
$jahr = mb_substr($dtstart,0,4);
$monat = mb_substr($dtstart,4,2);
$tag = mb_substr($dtstart,6,2);
$stunde = mb_substr($dtstart,9,2);
$minute = mb_substr($dtstart,11,2);
$sekunde = mb_substr($dtstart,13,2);
$begin = mktime($stunde, $minute, $sekunde, $monat, $tag-1, $jahr);
$ende = mktime($stunde, $minute, $sekunde, $monat, $tag+1, $jahr);
error_log("getCalendarData unr: $unr dtstart: $dtstart");
error_log($begin.'/'.$ende);
}
else
{
//TODO Datum eventuell anpassen derzeit nur aktuell +/- 6 Monate
$begin = mktime(0,0,0,date('m')-6,date('d'),date('Y'));
$ende = mktime(0,0,0,date('m')+6,date('d'),date('Y'));
}
$db_stpl_table = 'stundenplan';
$i=0;
$data = array();
// Kalender erstellen
while($begin<$ende)
{
error_log("while");
$i++;
if(!date("w",$begin))
$begin=jump_day($begin,1);
$stdplan->init_stdplan();
$datum=$begin;
$begin+=604800; // eine Woche
// Stundenplan einer Woche laden
if(!$stdplan->load_week($datum,$db_stpl_table))
{
die($stdplan->errormsg);
}
$val = $stdplan->draw_week_csv('return', LVPLAN_KATEGORIE);
if(!is_null($objectUri))
{
foreach($val as $row)
{
error_log("search dtstart:".$dtstart." unr:".$unr);
error_log("row dtstart:".$row['dtstart']." unr:".$row['unr'][0]);
if($row['dtstart']==$dtstart && $row['unr'][0]==$unr)
{
error_log("found!");
return $row;
}
}
}
else
$data=array_merge($data, $val);
}
//$data.="\nEND:VCALENDAR";
return $data;
}
public function makeCal($event)
{
return "BEGIN:VCALENDAR
VERSION:2.0
PRODID:FH Technikum Wien
BEGIN:VTIMEZONE
TZID:Europe/Vienna
BEGIN:DAYLIGHT
TZOFFSETFROM:+0100
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU
DTSTART:19810329T020000
TZNAME:GMT+02:00
TZOFFSETTO:+0200
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETFROM:+0200
RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU
DTSTART:19961027T030000
TZNAME:GMT+01:00
TZOFFSETTO:+0100
END:STANDARD
END:VTIMEZONE\n".$event."\nEND:VCALENDAR";
}
/**
* 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) data:".print_r($data,true));
$return = array();
foreach($data as $row)
{
$return[] = array("id"=>$row['UID'],
"calendardata"=>$this->makeCal($row['data']),
"uri"=>$row['dtstart'].'-'.$row['unr'][0],
"lastmodified"=>$row['updateamum'],
"etag"=>'"'.$row['UID'].'"',
"calendarid"=>$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)
{
error_log("Caldav_Backend.php/getCalendarObject($calendarId, $objectUri)");
$user = $this->getUser();
$data = $this->getCalendarData($user,$objectUri);
if(count($data)==0)
{
$ret=array("id"=>'',
"calendardata"=>'',
"uri"=>'',
"lastmodified"=>'',
"etag"=>'',
"calendarid"=>$calendarId);
}
else
{
$ret = array("id"=>$data['UID'],
"calendardata"=>$this->makeCal($data['data']),
"uri"=>'principals/'.$user.'/LVPlan/'.$data['dtstart'].'-'.$data['unr'][0],
"lastmodified"=>$data['updateamum'],
"etag"=>'"'.$data['UID'].'"',
"calendarid"=>$calendarId);
}
return $ret;
}
/**
* Creates a new calendar object.
*
* @param string $calendarId
* @param string $objectUri
* @param string $calendarData
* @return void
*/
public function createCalendarObject($calendarId,$objectUri,$calendarData)
{
throw new Sabre_DAV_Exception('Not Implemented');
}
/**
* 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)
{
throw new Sabre_DAV_Exception('Not Implemented');
}
/**
* Deletes an existing calendar object.
*
* @param string $calendarId
* @param string $objectUri
* @return void
*/
public function deleteCalendarObject($calendarId,$objectUri)
{
throw new Sabre_DAV_Exception('Not Implemented');
}
}
+1 -1
View File
@@ -204,7 +204,7 @@ class DMSDirectory extends Sabre_DAV_Collection
$ext = '.'.mb_substr($name, $pos);
else
$ext ='';
$filename=uniqid();
$filename=uniqid().$ext;
$dms->version='0';
$dms->kategorie_kurzbz=$this->kategorie_kurzbz;
$dms->insertamum=date('Y-m-d H:i:s');
+32 -9
View File
@@ -191,15 +191,38 @@ class DMSFile extends Sabre_DAV_File
$dms = new dms();
if($dms->load($this->dms_id))
{
$dms->updateamum = date('Y-m-d H:i:s');
$dms->updatevon = $this->getUser();
file_put_contents(DMS_PATH.$dms->filename, $data);
$dms->save(false);
}
else
{
throw new Sabre_DAV_Exception_FileNotFound('Failed '.$dms->errormsg);
$dms->version = $dms->version++;
$pos = mb_strrpos($dms->name,'.')+1;
if($pos>1)
$ext = '.'.mb_substr($dms->name, $pos);
else
$ext ='';
$filename=uniqid().$ext;
$dms->version++;
$dms->insertamum=date('Y-m-d H:i:s');
$dms->insertvon = $this->getUser();
$dms->filename = $filename;
if($dms->save(true))
{
if(file_put_contents(DMS_PATH.$filename, $data))
{
if(!chgrp(DMS_PATH.$filename,'dms'))
echo 'CHGRP failed';
if(!chmod(DMS_PATH.$filename, 0774))
echo 'CHMOD failed';
exec('sudo chown wwwrun '.$filename);
$dms->save(false);
}
else
throw new Sabre_DAV_Exception_FileNotFound('Failed to Write File');
}
else
{
throw new Sabre_DAV_Exception_FileNotFound('Failed '.$dms->errormsg);
}
}
}
}
+172
View File
@@ -0,0 +1,172 @@
<?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 MySabre_DAVACL_PrincipalBackend implements Sabre_DAVACL_IPrincipalBackend
{
/**
* PDO table name for 'principals'
*
* @var string
*/
protected $tableName;
/**
* PDO table name for 'group members'
*
* @var string
*/
protected $groupMembersTableName;
/**
* Sets up the backend.
*
* @param PDO $pdo
* @param string $tableName
*/
public function __construct($auth)
{
$this->auth = $auth;
}
/**
* 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' => 1,
'uri' => 'principals/'.$user,
'{DAV:}displayname' => $user,
'{http://sabredav.org/ns}email-address' => $user.'@example.com',
);
}
elseif($prefixPath=='principals/oesi')
{
$principals[] = array(
'id' => 2,
'uri' => 'principals/'.$user.'/calendar-proxy-read',
'{DAV:}displayname' => '',
'{http://sabredav.org/ns}email-address' => '',
);
$principals[] = array(
'id' => 3,
'uri' => 'principals/'.$user.'/calendar-proxy-write',
'{DAV:}displayname' => '',
'{http://sabredav.org/ns}email-address' => '',
);
}
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)
{
//$path = principals/oesi
error_log('Principal.php/getPrincipalByPath('.$path.')');
$user = $this->getUser();
$result = array(
'id' => $user,
'uri' => 'principals/'.$user,
'{DAV:}displayname' => $user,
'{http://sabredav.org/ns}email-address' => $user.'@example.com',
);
//error_log("data:".print_r($result,true));
return $result;
}
/**
* Returns the list of members for a group-principal
*
* @param string $principal
* @return array
*/
public function getGroupMemberSet($principal)
{
//error_log('Principal.php/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)
{
//$principal = username
$result = array();
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');
}
}
+3 -3
View File
@@ -50,9 +50,9 @@ $server->setBaseUri($path);
// The lock manager is reponsible for making sure users don't overwrite each others changes. Change 'data' to a different
// directory, if you're storing your data somewhere else.
//$lockBackend = new Sabre_DAV_Locks_Backend_File('data/locks');
//$lockPlugin = new Sabre_DAV_Locks_Plugin($lockBackend);
//$server->addPlugin($lockPlugin);
$lockBackend = new Sabre_DAV_Locks_Backend_File('data/locks');
$lockPlugin = new Sabre_DAV_Locks_Plugin($lockBackend);
$server->addPlugin($lockPlugin);
//GUI fuer Browser
$browser = new Sabre_DAV_Browser_Plugin();
+47
View File
@@ -0,0 +1,47 @@
<?php
// Files we need
require_once '../include/sabredav/lib/Sabre/autoload.php';
require_once 'auth.class.php';
require_once 'Caldav_Backend.php';
require_once('Principal.php');
// Backends
$authBackend = new myAuth();
$principalBackend = new MySabre_DAVACL_PrincipalBackend($authBackend);
$calendarBackend = new MySabre_CalDAV_Backend($authBackend);
$tree = array(
new Sabre_DAVACL_PrincipalCollection($principalBackend),
new Sabre_CalDAV_CalendarRootNode($principalBackend, $calendarBackend)
);
// The object tree needs in turn to be passed to the server class
$server = new Sabre_DAV_Server($tree);
// You are highly encouraged to set your WebDAV server base url. Without it,
// SabreDAV will guess, but the guess is not always correct. Putting the
// server on the root of the domain will improve compatibility.
$path = str_replace($_SERVER['DOCUMENT_ROOT'],'',__FILE__).'/';
$server->setBaseUri($path);
// Authentication plugin
$authPlugin = new Sabre_DAV_Auth_Plugin($authBackend,'SabreDAV');
$server->addPlugin($authPlugin);
// CalDAV plugin
$caldavPlugin = new Sabre_CalDAV_Plugin();
$server->addPlugin($caldavPlugin);
// ACL plugin
$aclPlugin = new Sabre_DAVACL_Plugin();
$server->addPlugin($aclPlugin);
// Support for html frontend
$browser = new Sabre_DAV_Browser_Plugin();
$server->addPlugin($browser);
// And off we go!
$server->exec();