Set notifications of events; the actual notification routine is not yet implemented

pull/73/head
Tobias Hößl 2012-07-23 21:15:47 +00:00
parent 62ec9bfa69
commit 8196f9b900
26 changed files with 324 additions and 212 deletions

View File

@ -12,6 +12,8 @@
* BC Break: Sabre_CalDAV_Schedule_IMip::sendMessage now has an extra * BC Break: Sabre_CalDAV_Schedule_IMip::sendMessage now has an extra
argument. If you extended this class, you should fix this method. It's argument. If you extended this class, you should fix this method. It's
only used for informational purposes. only used for informational purposes.
* BC Break: The DAV: namespace is no longer converted to urn:DAV. This was
a workaround for a bug in older PHP versions (pre-5.3).
* New feature: Support for caldav notifications! * New feature: Support for caldav notifications!
* Changed: Responsibility for dealing with the calendar-query is now * Changed: Responsibility for dealing with the calendar-query is now
moved from the CalDAV plugin to the CalDAV backends. This allows for moved from the CalDAV plugin to the CalDAV backends. This allows for
@ -33,6 +35,9 @@
supported-calendar-component list. (thanks Armin!) supported-calendar-component list. (thanks Armin!)
* Fixed: Workaround for 10.8 Mountain Lion vCards, as it needs \r line * Fixed: Workaround for 10.8 Mountain Lion vCards, as it needs \r line
endings to parse them correctly. endings to parse them correctly.
* Fixed: Issue 219: serialize() now reorders correctly.
* Fixed: Sabre_DAV_XMLUtil no longer returns empty $dom->childNodes
if there is whitespace in $dom.
1.6.4-stable (2012-??-??) 1.6.4-stable (2012-??-??)
* Fixed: Issue 220: Calendar-query filters may fail when filtering on * Fixed: Issue 220: Calendar-query filters may fail when filtering on

View File

@ -68,7 +68,7 @@ class Sabre_CalDAV_CalendarQueryParser {
$this->xpath = new DOMXPath($dom); $this->xpath = new DOMXPath($dom);
$this->xpath->registerNameSpace('cal',Sabre_CalDAV_Plugin::NS_CALDAV); $this->xpath->registerNameSpace('cal',Sabre_CalDAV_Plugin::NS_CALDAV);
$this->xpath->registerNameSpace('dav','urn:DAV'); $this->xpath->registerNameSpace('dav','DAV:');
} }

View File

@ -442,11 +442,11 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
public function calendarMultiGetReport($dom) { public function calendarMultiGetReport($dom) {
$properties = array_keys(Sabre_DAV_XMLUtil::parseProperties($dom->firstChild)); $properties = array_keys(Sabre_DAV_XMLUtil::parseProperties($dom->firstChild));
$hrefElems = $dom->getElementsByTagNameNS('urn:DAV','href'); $hrefElems = $dom->getElementsByTagNameNS('DAV:','href');
$xpath = new DOMXPath($dom); $xpath = new DOMXPath($dom);
$xpath->registerNameSpace('cal',Sabre_CalDAV_Plugin::NS_CALDAV); $xpath->registerNameSpace('cal',Sabre_CalDAV_Plugin::NS_CALDAV);
$xpath->registerNameSpace('dav','urn:DAV'); $xpath->registerNameSpace('dav','DAV:');
$expand = $xpath->query('/cal:calendar-multiget/dav:prop/cal:calendar-data/cal:expand'); $expand = $xpath->query('/cal:calendar-multiget/dav:prop/cal:calendar-data/cal:expand');
if ($expand->length>0) { if ($expand->length>0) {

View File

@ -269,7 +269,7 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin {
$properties = array_keys(Sabre_DAV_XMLUtil::parseProperties($dom->firstChild)); $properties = array_keys(Sabre_DAV_XMLUtil::parseProperties($dom->firstChild));
$hrefElems = $dom->getElementsByTagNameNS('urn:DAV','href'); $hrefElems = $dom->getElementsByTagNameNS('DAV:','href');
$propertyList = array(); $propertyList = array();
foreach($hrefElems as $elem) { foreach($hrefElems as $elem) {

View File

@ -485,19 +485,17 @@ class Sabre_DAV_Client {
*/ */
public function parseMultiStatus($body) { public function parseMultiStatus($body) {
$body = Sabre_DAV_XMLUtil::convertDAVNamespace($body);
$responseXML = simplexml_load_string($body, null, LIBXML_NOBLANKS | LIBXML_NOCDATA); $responseXML = simplexml_load_string($body, null, LIBXML_NOBLANKS | LIBXML_NOCDATA);
if ($responseXML===false) { if ($responseXML===false) {
throw new InvalidArgumentException('The passed data is not valid XML'); throw new InvalidArgumentException('The passed data is not valid XML');
} }
$responseXML->registerXPathNamespace('d', 'urn:DAV'); $responseXML->registerXPathNamespace('d', 'DAV:');
$propResult = array(); $propResult = array();
foreach($responseXML->xpath('d:response') as $response) { foreach($responseXML->xpath('d:response') as $response) {
$response->registerXPathNamespace('d', 'urn:DAV'); $response->registerXPathNamespace('d', 'DAV:');
$href = $response->xpath('d:href'); $href = $response->xpath('d:href');
$href = (string)$href[0]; $href = (string)$href[0];
@ -505,7 +503,7 @@ class Sabre_DAV_Client {
foreach($response->xpath('d:propstat') as $propStat) { foreach($response->xpath('d:propstat') as $propStat) {
$propStat->registerXPathNamespace('d', 'urn:DAV'); $propStat->registerXPathNamespace('d', 'DAV:');
$status = $propStat->xpath('d:status'); $status = $propStat->xpath('d:status');
list($httpVersion, $statusCode, $message) = explode(' ', (string)$status[0],3); list($httpVersion, $statusCode, $message) = explode(' ', (string)$status[0],3);

View File

@ -1999,7 +1999,7 @@ class Sabre_DAV_Server {
if (!$body) return array(); if (!$body) return array();
$dom = Sabre_DAV_XMLUtil::loadDOMDocument($body); $dom = Sabre_DAV_XMLUtil::loadDOMDocument($body);
$elem = $dom->getElementsByTagNameNS('urn:DAV','propfind')->item(0); $elem = $dom->getElementsByTagNameNS('DAV:','propfind')->item(0);
return array_keys(Sabre_DAV_XMLUtil::parseProperties($elem)); return array_keys(Sabre_DAV_XMLUtil::parseProperties($elem));
} }

View File

@ -20,9 +20,6 @@ class Sabre_DAV_XMLUtil {
* {http://www.example.org}myelem * {http://www.example.org}myelem
* *
* This format is used throughout the SabreDAV sourcecode. * This format is used throughout the SabreDAV sourcecode.
* Elements encoded with the urn:DAV namespace will
* be returned as if they were in the DAV: namespace. This is to avoid
* compatibility problems.
* *
* This function will return null if a nodetype other than an Element is passed. * This function will return null if a nodetype other than an Element is passed.
* *
@ -33,8 +30,7 @@ class Sabre_DAV_XMLUtil {
if ($dom->nodeType !== XML_ELEMENT_NODE) return null; if ($dom->nodeType !== XML_ELEMENT_NODE) return null;
// Mapping back to the real namespace, in case it was dav $ns = $dom->namespaceURI;
if ($dom->namespaceURI=='urn:DAV') $ns = 'DAV:'; else $ns = $dom->namespaceURI;
// Mapping to clark notation // Mapping to clark notation
return '{' . $ns . '}' . $dom->localName; return '{' . $ns . '}' . $dom->localName;
@ -64,29 +60,11 @@ class Sabre_DAV_XMLUtil {
} }
/**
* This method takes an XML document (as string) and converts all instances of the
* DAV: namespace to urn:DAV
*
* This is unfortunately needed, because the DAV: namespace violates the xml namespaces
* spec, and causes the DOM to throw errors
*
* @param string $xmlDocument
* @return array|string|null
*/
static function convertDAVNamespace($xmlDocument) {
// This is used to map the DAV: namespace to urn:DAV. This is needed, because the DAV:
// namespace is actually a violation of the XML namespaces specification, and will cause errors
return preg_replace("/xmlns(:[A-Za-z0-9_]*)?=(\"|\')DAV:(\\2)/","xmlns\\1=\\2urn:DAV\\2",$xmlDocument);
}
/** /**
* This method provides a generic way to load a DOMDocument for WebDAV use. * This method provides a generic way to load a DOMDocument for WebDAV use.
* *
* This method throws a Sabre_DAV_Exception_BadRequest exception for any xml errors. * This method throws a Sabre_DAV_Exception_BadRequest exception for any xml errors.
* It does not preserve whitespace, and it converts the DAV: namespace to urn:DAV. * It does not preserve whitespace.
* *
* @param string $xml * @param string $xml
* @throws Sabre_DAV_Exception_BadRequest * @throws Sabre_DAV_Exception_BadRequest
@ -118,11 +96,12 @@ class Sabre_DAV_XMLUtil {
libxml_clear_errors(); libxml_clear_errors();
$dom = new DOMDocument(); $dom = new DOMDocument();
$dom->loadXML(self::convertDAVNamespace($xml),LIBXML_NOWARNING | LIBXML_NOERROR);
// We don't generally care about any whitespace // We don't generally care about any whitespace
$dom->preserveWhiteSpace = false; $dom->preserveWhiteSpace = false;
$dom->loadXML($xml,LIBXML_NOWARNING | LIBXML_NOERROR);
if ($error = libxml_get_last_error()) { if ($error = libxml_get_last_error()) {
libxml_clear_errors(); libxml_clear_errors();
throw new Sabre_DAV_Exception_BadRequest('The request body had an invalid XML body. (message: ' . $error->message . ', errorcode: ' . $error->code . ', line: ' . $error->line . ')'); throw new Sabre_DAV_Exception_BadRequest('The request body had an invalid XML body. (message: ' . $error->message . ', errorcode: ' . $error->code . ', line: ' . $error->line . ')');

View File

@ -88,11 +88,11 @@ class Sabre_DAVACL_Property_Acl extends Sabre_DAV_Property {
static public function unserialize(DOMElement $dom) { static public function unserialize(DOMElement $dom) {
$privileges = array(); $privileges = array();
$xaces = $dom->getElementsByTagNameNS('urn:DAV','ace'); $xaces = $dom->getElementsByTagNameNS('DAV:','ace');
for($ii=0; $ii < $xaces->length; $ii++) { for($ii=0; $ii < $xaces->length; $ii++) {
$xace = $xaces->item($ii); $xace = $xaces->item($ii);
$principal = $xace->getElementsByTagNameNS('urn:DAV','principal'); $principal = $xace->getElementsByTagNameNS('DAV:','principal');
if ($principal->length !== 1) { if ($principal->length !== 1) {
throw new Sabre_DAV_Exception_BadRequest('Each {DAV:}ace element must have one {DAV:}principal element'); throw new Sabre_DAV_Exception_BadRequest('Each {DAV:}ace element must have one {DAV:}principal element');
} }
@ -116,17 +116,17 @@ class Sabre_DAVACL_Property_Acl extends Sabre_DAV_Property {
$protected = false; $protected = false;
if ($xace->getElementsByTagNameNS('urn:DAV','protected')->length > 0) { if ($xace->getElementsByTagNameNS('DAV:','protected')->length > 0) {
$protected = true; $protected = true;
} }
$grants = $xace->getElementsByTagNameNS('urn:DAV','grant'); $grants = $xace->getElementsByTagNameNS('DAV:','grant');
if ($grants->length < 1) { if ($grants->length < 1) {
throw new Sabre_DAV_Exception_NotImplemented('Every {DAV:}ace element must have a {DAV:}grant element. {DAV:}deny is not yet supported'); throw new Sabre_DAV_Exception_NotImplemented('Every {DAV:}ace element must have a {DAV:}grant element. {DAV:}deny is not yet supported');
} }
$grant = $grants->item(0); $grant = $grants->item(0);
$xprivs = $grant->getElementsByTagNameNS('urn:DAV','privilege'); $xprivs = $grant->getElementsByTagNameNS('DAV:','privilege');
for($jj=0; $jj<$xprivs->length; $jj++) { for($jj=0; $jj<$xprivs->length; $jj++) {
$xpriv = $xprivs->item($jj); $xpriv = $xprivs->item($jj);

View File

@ -30,7 +30,7 @@ class Sabre_VObject_Component extends Sabre_VObject_Element {
public $children = array(); public $children = array();
/** /**
* If coponents are added to this map, they will be automatically mapped * If components are added to this map, they will be automatically mapped
* to their respective classes, if parsed by the reader or constructed with * to their respective classes, if parsed by the reader or constructed with
* the 'create' method. * the 'create' method.
* *
@ -94,40 +94,54 @@ class Sabre_VObject_Component extends Sabre_VObject_Element {
* *
* This is solely used by the childrenSort method. * This is solely used by the childrenSort method.
* *
* A higher score means the item will be higher in the list * A higher score means the item will be lower in the list.
* To avoid score collisions, each "score category" has a reasonable
* space to accomodate elements. The $key is added to the $score to
* preserve the original relative order of elements.
* *
* @param Sabre_VObject_Node $n * @param int $key
* @param Sabre_VObject $array
* @return int * @return int
*/ */
$sortScore = function($n) { $sortScore = function($key, $array) {
if ($n instanceof Sabre_VObject_Component) { if ($array[$key] instanceof Sabre_VObject_Component) {
// We want to encode VTIMEZONE first, this is a personal // We want to encode VTIMEZONE first, this is a personal
// preference. // preference.
if ($n->name === 'VTIMEZONE') { if ($array[$key]->name === 'VTIMEZONE') {
return 1; $score=300000000;
return $score+$key;
} else { } else {
return 0; $score=400000000;
return $score+$key;
} }
} else { } else {
// Properties get encoded first
// VCARD version 4.0 wants the VERSION property to appear first // VCARD version 4.0 wants the VERSION property to appear first
if ($n->name === 'VERSION') { if ($array[$key] instanceof Sabre_VObject_Property) {
return 3; if ($array[$key]->name === 'VERSION') {
} else { $score=100000000;
return 2; return $score+$key;
} else {
// All other properties
$score=200000000;
return $score+$key;
}
} }
} }
next($children);
}; };
usort($this->children, function($a, $b) use ($sortScore) { $tmp = $this->children;
uksort($this->children, function($a, $b) use ($sortScore, $tmp) {
$sA = $sortScore($a); $sA = $sortScore($a, $tmp);
$sB = $sortScore($b); $sB = $sortScore($b, $tmp);
if ($sA === $sB) return 0; if ($sA === $sB) return 0;
return ($sA > $sB) ? -1 : 1; return ($sA < $sB) ? -1 : 1;
}); });

View File

@ -536,9 +536,9 @@ END:VCALENDAR';
$this->assertEquals('HTTP/1.1 207 Multi-Status',$this->response->status,'Invalid HTTP status received. Full response body: ' . $this->response->body); $this->assertEquals('HTTP/1.1 207 Multi-Status',$this->response->status,'Invalid HTTP status received. Full response body: ' . $this->response->body);
$xml = simplexml_load_string(Sabre_DAV_XMLUtil::convertDAVNamespace($this->response->body)); $xml = simplexml_load_string($this->response->body);
$xml->registerXPathNamespace('d','urn:DAV'); $xml->registerXPathNamespace('d','DAV:');
$xml->registerXPathNamespace('c','urn:ietf:params:xml:ns:caldav'); $xml->registerXPathNamespace('c','urn:ietf:params:xml:ns:caldav');
$check = array( $check = array(
@ -598,9 +598,9 @@ END:VCALENDAR';
$this->assertEquals('HTTP/1.1 207 Multi-Status',$this->response->status,'Invalid HTTP status received. Full response body: ' . $this->response->body); $this->assertEquals('HTTP/1.1 207 Multi-Status',$this->response->status,'Invalid HTTP status received. Full response body: ' . $this->response->body);
$xml = simplexml_load_string(Sabre_DAV_XMLUtil::convertDAVNamespace($this->response->body)); $xml = simplexml_load_string($this->response->body);
$xml->registerXPathNamespace('d','urn:DAV'); $xml->registerXPathNamespace('d','DAV:');
$xml->registerXPathNamespace('c','urn:ietf:params:xml:ns:caldav'); $xml->registerXPathNamespace('c','urn:ietf:params:xml:ns:caldav');
$check = array( $check = array(
@ -663,9 +663,9 @@ END:VCALENDAR';
$this->assertEquals('HTTP/1.1 207 Multi-Status',$this->response->status,'Received an unexpected status. Full response body: ' . $this->response->body); $this->assertEquals('HTTP/1.1 207 Multi-Status',$this->response->status,'Received an unexpected status. Full response body: ' . $this->response->body);
$xml = simplexml_load_string(Sabre_DAV_XMLUtil::convertDAVNamespace($this->response->body)); $xml = simplexml_load_string($this->response->body);
$xml->registerXPathNamespace('d','urn:DAV'); $xml->registerXPathNamespace('d','DAV:');
$xml->registerXPathNamespace('c','urn:ietf:params:xml:ns:caldav'); $xml->registerXPathNamespace('c','urn:ietf:params:xml:ns:caldav');
$check = array( $check = array(
@ -722,9 +722,9 @@ END:VCALENDAR';
$this->assertEquals('HTTP/1.1 207 Multi-Status',$this->response->status,'Received an unexpected status. Full response body: ' . $this->response->body); $this->assertEquals('HTTP/1.1 207 Multi-Status',$this->response->status,'Received an unexpected status. Full response body: ' . $this->response->body);
$xml = simplexml_load_string(Sabre_DAV_XMLUtil::convertDAVNamespace($this->response->body)); $xml = simplexml_load_string($this->response->body);
$xml->registerXPathNamespace('d','urn:DAV'); $xml->registerXPathNamespace('d','DAV:');
$xml->registerXPathNamespace('c','urn:ietf:params:xml:ns:caldav'); $xml->registerXPathNamespace('c','urn:ietf:params:xml:ns:caldav');
$check = array( $check = array(
@ -811,9 +811,9 @@ END:VCALENDAR';
$this->assertEquals('HTTP/1.1 207 Multi-Status',$this->response->status,'Received an unexpected status. Full response body: ' . $this->response->body); $this->assertEquals('HTTP/1.1 207 Multi-Status',$this->response->status,'Received an unexpected status. Full response body: ' . $this->response->body);
$xml = simplexml_load_string(Sabre_DAV_XMLUtil::convertDAVNamespace($this->response->body)); $xml = simplexml_load_string($this->response->body);
$xml->registerXPathNamespace('d','urn:DAV'); $xml->registerXPathNamespace('d','DAV:');
$xml->registerXPathNamespace('c','urn:ietf:params:xml:ns:caldav'); $xml->registerXPathNamespace('c','urn:ietf:params:xml:ns:caldav');
$check = array( $check = array(
@ -871,9 +871,9 @@ END:VCALENDAR';
$this->assertEquals('HTTP/1.1 207 Multi-Status',$this->response->status,'Received an unexpected status. Full response body: ' . $this->response->body); $this->assertEquals('HTTP/1.1 207 Multi-Status',$this->response->status,'Received an unexpected status. Full response body: ' . $this->response->body);
$xml = simplexml_load_string(Sabre_DAV_XMLUtil::convertDAVNamespace($this->response->body)); $xml = simplexml_load_string($this->response->body);
$xml->registerXPathNamespace('d','urn:DAV'); $xml->registerXPathNamespace('d','DAV:');
$xml->registerXPathNamespace('c','urn:ietf:params:xml:ns:caldav'); $xml->registerXPathNamespace('c','urn:ietf:params:xml:ns:caldav');
$check = array( $check = array(

View File

@ -92,9 +92,9 @@ class Sabre_DAV_Locks_PluginTest extends Sabre_DAV_AbstractServer {
$this->assertEquals('HTTP/1.1 200 OK',$this->response->status,'Got an incorrect status back. Response body: ' . $this->response->body); $this->assertEquals('HTTP/1.1 200 OK',$this->response->status,'Got an incorrect status back. Response body: ' . $this->response->body);
$body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/","xmlns\\1=\"urn:DAV\"",$this->response->body); $body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/","xmlns\\1=\"DAV:\"",$this->response->body);
$xml = simplexml_load_string($body); $xml = simplexml_load_string($body);
$xml->registerXPathNamespace('d','urn:DAV'); $xml->registerXPathNamespace('d','DAV:');
$elements = array( $elements = array(
'/d:prop', '/d:prop',

View File

@ -60,7 +60,7 @@ class Sabre_DAV_Property_HrefListTest extends PHPUnit_Framework_TestCase {
function testUnserialize() { function testUnserialize() {
$xml = '<?xml version="1.0"?> $xml = '<?xml version="1.0"?>
<d:anything xmlns:d="urn:DAV"><d:href>/bla/foo</d:href><d:href>/bla/bar</d:href></d:anything> <d:anything xmlns:d="DAV:"><d:href>/bla/foo</d:href><d:href>/bla/bar</d:href></d:anything>
'; ';
$dom = new DOMDocument(); $dom = new DOMDocument();
@ -74,7 +74,7 @@ class Sabre_DAV_Property_HrefListTest extends PHPUnit_Framework_TestCase {
function testUnserializeIncompatible() { function testUnserializeIncompatible() {
$xml = '<?xml version="1.0"?> $xml = '<?xml version="1.0"?>
<d:anything xmlns:d="urn:DAV"><d:href2>/bla/foo</d:href2></d:anything> <d:anything xmlns:d="DAV:"><d:href2>/bla/foo</d:href2></d:anything>
'; ';
$dom = new DOMDocument(); $dom = new DOMDocument();

View File

@ -60,7 +60,7 @@ class Sabre_DAV_Property_HrefTest extends PHPUnit_Framework_TestCase {
function testUnserialize() { function testUnserialize() {
$xml = '<?xml version="1.0"?> $xml = '<?xml version="1.0"?>
<d:anything xmlns:d="urn:DAV"><d:href>/bla/path</d:href></d:anything> <d:anything xmlns:d="DAV:"><d:href>/bla/path</d:href></d:anything>
'; ';
$dom = new DOMDocument(); $dom = new DOMDocument();
@ -74,7 +74,7 @@ class Sabre_DAV_Property_HrefTest extends PHPUnit_Framework_TestCase {
function testUnserializeIncompatible() { function testUnserializeIncompatible() {
$xml = '<?xml version="1.0"?> $xml = '<?xml version="1.0"?>
<d:anything xmlns:d="urn:DAV"><d:href2>/bla/path</d:href2></d:anything> <d:anything xmlns:d="DAV:"><d:href2>/bla/path</d:href2></d:anything>
'; ';
$dom = new DOMDocument(); $dom = new DOMDocument();

View File

@ -37,9 +37,9 @@ class Sabre_DAV_Property_SupportedReportSetTest extends Sabre_DAV_AbstractServer
$this->assertEquals('HTTP/1.1 207 Multi-Status',$this->response->status,'We expected a multi-status response. Full response body: ' . $this->response->body); $this->assertEquals('HTTP/1.1 207 Multi-Status',$this->response->status,'We expected a multi-status response. Full response body: ' . $this->response->body);
$body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/","xmlns\\1=\"urn:DAV\"",$this->response->body); $body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/","xmlns\\1=\"DAV:\"",$this->response->body);
$xml = simplexml_load_string($body); $xml = simplexml_load_string($body);
$xml->registerXPathNamespace('d','urn:DAV'); $xml->registerXPathNamespace('d','DAV:');
$data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop'); $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop');
$this->assertEquals(1,count($data),'We expected 1 \'d:prop\' element'); $this->assertEquals(1,count($data),'We expected 1 \'d:prop\' element');
@ -74,9 +74,9 @@ class Sabre_DAV_Property_SupportedReportSetTest extends Sabre_DAV_AbstractServer
$this->assertEquals('HTTP/1.1 207 Multi-Status',$this->response->status,'We expected a multi-status response. Full response body: ' . $this->response->body); $this->assertEquals('HTTP/1.1 207 Multi-Status',$this->response->status,'We expected a multi-status response. Full response body: ' . $this->response->body);
$body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/","xmlns\\1=\"urn:DAV\"",$this->response->body); $body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/","xmlns\\1=\"DAV:\"",$this->response->body);
$xml = simplexml_load_string($body); $xml = simplexml_load_string($body);
$xml->registerXPathNamespace('d','urn:DAV'); $xml->registerXPathNamespace('d','DAV:');
$xml->registerXPathNamespace('x','http://www.rooftopsolutions.nl/testnamespace'); $xml->registerXPathNamespace('x','http://www.rooftopsolutions.nl/testnamespace');
$data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop'); $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop');

View File

@ -192,7 +192,6 @@ class Sabre_DAV_ServerMKCOLTest extends Sabre_DAV_AbstractServer {
} }
/** /**
* @depends testMKCOLIncorrectResourceType2 * @depends testMKCOLIncorrectResourceType2
*/ */
@ -224,6 +223,38 @@ class Sabre_DAV_ServerMKCOLTest extends Sabre_DAV_AbstractServer {
} }
/**
* @depends testMKCOLIncorrectResourceType2
*/
function testMKCOLWhiteSpaceResourceType() {
$serverVars = array(
'REQUEST_URI' => '/testcol',
'REQUEST_METHOD' => 'MKCOL',
'HTTP_CONTENT_TYPE' => 'application/xml',
);
$request = new Sabre_HTTP_Request($serverVars);
$request->setBody('<?xml version="1.0"?>
<mkcol xmlns="DAV:">
<set>
<prop>
<resourcetype>
<collection />
</resourcetype>
</prop>
</set>
</mkcol>');
$this->server->httpRequest = ($request);
$this->server->exec();
$this->assertEquals(array(
'Content-Length' => '0',
),$this->response->headers);
$this->assertEquals('HTTP/1.1 201 Created',$this->response->status,'Wrong statuscode received. Full response body: ' .$this->response->body);
}
/** /**
* @depends testMKCOLIncorrectResourceType2 * @depends testMKCOLIncorrectResourceType2

View File

@ -58,9 +58,9 @@ class Sabre_DAV_ServerPropsTest extends Sabre_DAV_AbstractServer {
$this->response->headers $this->response->headers
); );
$body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/","xmlns\\1=\"urn:DAV\"",$this->response->body); $body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/","xmlns\\1=\"DAV:\"",$this->response->body);
$xml = simplexml_load_string($body); $xml = simplexml_load_string($body);
$xml->registerXPathNamespace('d','urn:DAV'); $xml->registerXPathNamespace('d','DAV:');
list($data) = $xml->xpath('/d:multistatus/d:response/d:href'); list($data) = $xml->xpath('/d:multistatus/d:response/d:href');
$this->assertEquals('/',(string)$data,'href element should have been /'); $this->assertEquals('/',(string)$data,'href element should have been /');
@ -81,9 +81,9 @@ class Sabre_DAV_ServerPropsTest extends Sabre_DAV_AbstractServer {
$this->sendRequest($xml); $this->sendRequest($xml);
$body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/","xmlns\\1=\"urn:DAV\"",$this->response->body); $body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/","xmlns\\1=\"DAV:\"",$this->response->body);
$xml = simplexml_load_string($body); $xml = simplexml_load_string($body);
$xml->registerXPathNamespace('d','urn:DAV'); $xml->registerXPathNamespace('d','DAV:');
$data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop/d:supportedlock/d:lockentry'); $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop/d:supportedlock/d:lockentry');
$this->assertEquals(2,count($data),'We expected two \'d:lockentry\' tags'); $this->assertEquals(2,count($data),'We expected two \'d:lockentry\' tags');
@ -115,9 +115,9 @@ class Sabre_DAV_ServerPropsTest extends Sabre_DAV_AbstractServer {
$this->sendRequest($xml); $this->sendRequest($xml);
$body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/","xmlns\\1=\"urn:DAV\"",$this->response->body); $body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/","xmlns\\1=\"DAV:\"",$this->response->body);
$xml = simplexml_load_string($body); $xml = simplexml_load_string($body);
$xml->registerXPathNamespace('d','urn:DAV'); $xml->registerXPathNamespace('d','DAV:');
$data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop/d:lockdiscovery'); $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop/d:lockdiscovery');
$this->assertEquals(1,count($data),'We expected a \'d:lockdiscovery\' tag'); $this->assertEquals(1,count($data),'We expected a \'d:lockdiscovery\' tag');
@ -134,9 +134,9 @@ class Sabre_DAV_ServerPropsTest extends Sabre_DAV_AbstractServer {
</d:propfind>'; </d:propfind>';
$this->sendRequest($xml); $this->sendRequest($xml);
$body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/","xmlns\\1=\"urn:DAV\"",$this->response->body); $body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/","xmlns\\1=\"DAV:\"",$this->response->body);
$xml = simplexml_load_string($body); $xml = simplexml_load_string($body);
$xml->registerXPathNamespace('d','urn:DAV'); $xml->registerXPathNamespace('d','DAV:');
$pathTests = array( $pathTests = array(
'/d:multistatus', '/d:multistatus',
'/d:multistatus/d:response', '/d:multistatus/d:response',
@ -312,9 +312,9 @@ class Sabre_DAV_ServerPropsTest extends Sabre_DAV_AbstractServer {
$this->assertEquals('HTTP/1.1 207 Multi-Status',$this->response->status,'We got the wrong status. Full XML response: ' . $this->response->body); $this->assertEquals('HTTP/1.1 207 Multi-Status',$this->response->status,'We got the wrong status. Full XML response: ' . $this->response->body);
$body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/","xmlns\\1=\"urn:DAV\"",$this->response->body); $body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/","xmlns\\1=\"DAV:\"",$this->response->body);
$xml = simplexml_load_string($body); $xml = simplexml_load_string($body);
$xml->registerXPathNamespace('d','urn:DAV'); $xml->registerXPathNamespace('d','DAV:');
$xml->registerXPathNamespace('bla','http://www.rooftopsolutions.nl/testnamespace'); $xml->registerXPathNamespace('bla','http://www.rooftopsolutions.nl/testnamespace');
$data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop'); $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop');
@ -345,9 +345,9 @@ class Sabre_DAV_ServerPropsTest extends Sabre_DAV_AbstractServer {
$this->sendRequest($xml); $this->sendRequest($xml);
$body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/","xmlns\\1=\"urn:DAV\"",$this->response->body); $body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/","xmlns\\1=\"DAV:\"",$this->response->body);
$xml = simplexml_load_string($body); $xml = simplexml_load_string($body);
$xml->registerXPathNamespace('d','urn:DAV'); $xml->registerXPathNamespace('d','DAV:');
$xml->registerXPathNamespace('bla','http://www.rooftopsolutions.nl/testnamespace'); $xml->registerXPathNamespace('bla','http://www.rooftopsolutions.nl/testnamespace');
$xpath='//bla:someprop'; $xpath='//bla:someprop';

View File

@ -233,9 +233,9 @@ class Sabre_DAV_TemporaryFileFilterTest extends Sabre_DAV_AbstractServer {
'Content-Type' => 'application/xml; charset=utf-8', 'Content-Type' => 'application/xml; charset=utf-8',
),$this->response->headers); ),$this->response->headers);
$body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/","xmlns\\1=\"urn:DAV\"",$this->response->body); $body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/","xmlns\\1=\"DAV:\"",$this->response->body);
$xml = simplexml_load_string($body); $xml = simplexml_load_string($body);
$xml->registerXPathNamespace('d','urn:DAV'); $xml->registerXPathNamespace('d','DAV:');
list($data) = $xml->xpath('/d:multistatus/d:response/d:href'); list($data) = $xml->xpath('/d:multistatus/d:response/d:href');
$this->assertEquals('/._testput.txt',(string)$data,'href element should have been /._testput.txt'); $this->assertEquals('/._testput.txt',(string)$data,'href element should have been /._testput.txt');

View File

@ -29,7 +29,7 @@ class Sabre_DAV_XMLUtilTest extends PHPUnit_Framework_TestCase {
function testToClarkNotationDAVNamespace() { function testToClarkNotationDAVNamespace() {
$dom = new DOMDocument(); $dom = new DOMDocument();
$dom->loadXML('<?xml version="1.0"?><s:test1 xmlns:s="urn:DAV">Testdoc</s:test1>'); $dom->loadXML('<?xml version="1.0"?><s:test1 xmlns:s="DAV:">Testdoc</s:test1>');
$this->assertEquals( $this->assertEquals(
'{DAV:}test1', '{DAV:}test1',
@ -41,7 +41,7 @@ class Sabre_DAV_XMLUtilTest extends PHPUnit_Framework_TestCase {
function testToClarkNotationNoElem() { function testToClarkNotationNoElem() {
$dom = new DOMDocument(); $dom = new DOMDocument();
$dom->loadXML('<?xml version="1.0"?><s:test1 xmlns:s="urn:DAV">Testdoc</s:test1>'); $dom->loadXML('<?xml version="1.0"?><s:test1 xmlns:s="DAV:">Testdoc</s:test1>');
$this->assertNull( $this->assertNull(
Sabre_DAV_XMLUtil::toClarkNotation($dom->firstChild->firstChild) Sabre_DAV_XMLUtil::toClarkNotation($dom->firstChild->firstChild)
@ -49,59 +49,6 @@ class Sabre_DAV_XMLUtilTest extends PHPUnit_Framework_TestCase {
} }
function testConvertDAVNamespace() {
$xml='<?xml version="1.0"?><document xmlns="DAV:">blablabla</document>';
$this->assertEquals(
'<?xml version="1.0"?><document xmlns="urn:DAV">blablabla</document>',
Sabre_DAV_XMLUtil::convertDAVNamespace($xml)
);
}
function testConvertDAVNamespace2() {
$xml='<?xml version="1.0"?><s:document xmlns:s="DAV:">blablabla</s:document>';
$this->assertEquals(
'<?xml version="1.0"?><s:document xmlns:s="urn:DAV">blablabla</s:document>',
Sabre_DAV_XMLUtil::convertDAVNamespace($xml)
);
}
function testConvertDAVNamespace3() {
$xml='<?xml version="1.0"?><s:document xmlns="http://bla" xmlns:s="DAV:" xmlns:z="http://othernamespace">blablabla</s:document>';
$this->assertEquals(
'<?xml version="1.0"?><s:document xmlns="http://bla" xmlns:s="urn:DAV" xmlns:z="http://othernamespace">blablabla</s:document>',
Sabre_DAV_XMLUtil::convertDAVNamespace($xml)
);
}
function testConvertDAVNamespace4() {
$xml='<?xml version="1.0"?><document xmlns=\'DAV:\'>blablabla</document>';
$this->assertEquals(
'<?xml version="1.0"?><document xmlns=\'urn:DAV\'>blablabla</document>',
Sabre_DAV_XMLUtil::convertDAVNamespace($xml)
);
}
function testConvertDAVNamespaceMixedQuotes() {
$xml='<?xml version="1.0"?><document xmlns=\'DAV:" xmlns="Another attribute\'>blablabla</document>';
$this->assertEquals(
$xml,
Sabre_DAV_XMLUtil::convertDAVNamespace($xml)
);
}
/**
* @depends testConvertDAVNamespace
*/
function testLoadDOMDocument() { function testLoadDOMDocument() {
$xml='<?xml version="1.0"?><document></document>'; $xml='<?xml version="1.0"?><document></document>';
@ -121,7 +68,6 @@ class Sabre_DAV_XMLUtilTest extends PHPUnit_Framework_TestCase {
} }
/** /**
* @depends testConvertDAVNamespace
* @expectedException Sabre_DAV_Exception_BadRequest * @expectedException Sabre_DAV_Exception_BadRequest
*/ */
function testLoadDOMDocumentInvalid() { function testLoadDOMDocumentInvalid() {

View File

@ -340,11 +340,14 @@ class Sabre_VObject_ComponentTest extends PHPUnit_Framework_TestCase {
new Sabre_VObject_Component('VEVENT'), new Sabre_VObject_Component('VEVENT'),
new Sabre_VObject_Component('VTODO') new Sabre_VObject_Component('VTODO')
); );
$this->assertEquals("BEGIN:VCALENDAR\r\nBEGIN:VTODO\r\nEND:VTODO\r\nBEGIN:VEVENT\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n", $comp->serialize());
$str = $comp->serialize();
$this->assertEquals("BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nEND:VEVENT\r\nBEGIN:VTODO\r\nEND:VTODO\r\nEND:VCALENDAR\r\n", $str);
} }
function testSerializeOrder() { function testSerializeOrderCompAndProp() {
$comp = new Sabre_VObject_Component('VCALENDAR'); $comp = new Sabre_VObject_Component('VCALENDAR');
$comp->add(new Sabre_VObject_Component('VEVENT')); $comp->add(new Sabre_VObject_Component('VEVENT'));
@ -358,4 +361,30 @@ class Sabre_VObject_ComponentTest extends PHPUnit_Framework_TestCase {
} }
function testAnotherSerializeOrderProp() {
$prop4s=array('1', '2', '3', '4', '5', '6', '7', '8', '9', '10');
$comp = new Sabre_VObject_Component('VCARD');
$comp->__set('SOMEPROP','FOO');
$comp->__set('ANOTHERPROP','FOO');
$comp->__set('THIRDPROP','FOO');
foreach ($prop4s as $prop4) {
$comp->add('PROP4', 'FOO '.$prop4);
}
$comp->__set('PROPNUMBERFIVE', 'FOO');
$comp->__set('PROPNUMBERSIX', 'FOO');
$comp->__set('PROPNUMBERSEVEN', 'FOO');
$comp->__set('PROPNUMBEREIGHT', 'FOO');
$comp->__set('PROPNUMBERNINE', 'FOO');
$comp->__set('PROPNUMBERTEN', 'FOO');
$comp->__set('VERSION','2.0');
$comp->__set('UID', 'FOO');
$str = $comp->serialize();
$this->assertEquals("BEGIN:VCARD\r\nVERSION:2.0\r\nSOMEPROP:FOO\r\nANOTHERPROP:FOO\r\nTHIRDPROP:FOO\r\nPROP4:FOO 1\r\nPROP4:FOO 2\r\nPROP4:FOO 3\r\nPROP4:FOO 4\r\nPROP4:FOO 5\r\nPROP4:FOO 6\r\nPROP4:FOO 7\r\nPROP4:FOO 8\r\nPROP4:FOO 9\r\nPROP4:FOO 10\r\nPROPNUMBERFIVE:FOO\r\nPROPNUMBERSIX:FOO\r\nPROPNUMBERSEVEN:FOO\r\nPROPNUMBEREIGHT:FOO\r\nPROPNUMBERNINE:FOO\r\nPROPNUMBERTEN:FOO\r\nUID:FOO\r\nEND:VCARD\r\n", $str);
}
} }

View File

@ -6,9 +6,9 @@ class Sabre_VObject_Issue154Test extends PHPUnit_Framework_TestCase {
$vcard = new Sabre_VObject_Component('VCARD'); $vcard = new Sabre_VObject_Component('VCARD');
$vcard->VERSION = '3.0'; $vcard->VERSION = '3.0';
$vcard->UID = 'foo-bar';
$vcard->PHOTO = base64_encode('random_stuff'); $vcard->PHOTO = base64_encode('random_stuff');
$vcard->PHOTO->add('BASE64',null); $vcard->PHOTO->add('BASE64',null);
$vcard->UID = 'foo-bar';
$result = $vcard->serialize(); $result = $vcard->serialize();
$expected = array( $expected = array(

View File

@ -301,7 +301,7 @@ function dav_get_current_user_calendars(&$server, $with_privilege = "")
* @param Sabre_CalDAV_Calendar $calendar * @param Sabre_CalDAV_Calendar $calendar
* @param string $calendarobject_uri * @param string $calendarobject_uri
* @param string $with_privilege * @param string $with_privilege
* @return null|Sabre_VObject_Component_VEvent * @return null|Sabre_VObject_Component_VCalendar
*/ */
function dav_get_current_user_calendarobject(&$server, &$calendar, $calendarobject_uri, $with_privilege = "") function dav_get_current_user_calendarobject(&$server, &$calendar, $calendarobject_uri, $with_privilege = "")
{ {

View File

@ -12,7 +12,7 @@ function renderCalDavEntry_calcalarm(&$alarm, &$parent)
{ {
$trigger = $alarm->__get("TRIGGER"); $trigger = $alarm->__get("TRIGGER");
if (!isset($trigger['VALUE']) || strtoupper($trigger['VALUE']) === 'DURATION') { if (!isset($trigger['VALUE']) || strtoupper($trigger['VALUE']) === 'DURATION') {
$triggerDuration = Sabre_VObject_DateTimeParser::parseDuration($trigger); $triggerDuration = Sabre_VObject_DateTimeParser::parseDuration($trigger->value);
$related = (isset($trigger['RELATED']) && strtoupper($trigger['RELATED']) == 'END') ? 'END' : 'START'; $related = (isset($trigger['RELATED']) && strtoupper($trigger['RELATED']) == 'END') ? 'END' : 'START';

View File

@ -120,6 +120,13 @@ function wdcal_edit_init(dateFormat, base_path) {
$(this).data("orig", $(this).text()); $(this).data("orig", $(this).text());
}); });
$("#new_alarm_adder a").click(function(ev) {
$("#new_alarm").val("1");
$("#noti_new_row").show();
$("#new_alarm_adder").hide();
ev.preventDefault();
});
wdcal_edit_recur_recalc(); wdcal_edit_recur_recalc();
$(document).on("click", ".exception_remover", function(ev) { $(document).on("click", ".exception_remover", function(ev) {

View File

@ -3,13 +3,11 @@
/** /**
* @param wdcal_local $localization * @param wdcal_local $localization
* @param string $baseurl * @param string $baseurl
* @param int $uid
* @param int $calendar_id * @param int $calendar_id
* @param int $uri * @param int $uri
* @param string $recurr_uri
* @return string * @return string
*/ */
function wdcal_getEditPage_str(&$localization, $baseurl, $uid, $calendar_id, $uri, $recurr_uri = "") function wdcal_getEditPage_str(&$localization, $baseurl, $calendar_id, $uri)
{ {
$server = dav_create_server(true, true, false); $server = dav_create_server(true, true, false);
@ -53,12 +51,53 @@ function wdcal_getEditPage_str(&$localization, $baseurl, $uid, $calendar_id, $ur
foreach ($z as $y) $recurrentce_exdates[] = $y->getTimeStamp(); foreach ($z as $y) $recurrentce_exdates[] = $y->getTimeStamp();
} }
$notifications = array();
$alarms = $component->select("VALARM");
foreach ($alarms as $alarm) {
/** @var Sabre_VObject_Component_VAlarm $alarm */
$action = $alarm->__get("ACTION")->value;
$trigger = $alarm->__get("TRIGGER");
if(isset($trigger['VALUE']) && strtoupper($trigger['VALUE']) !== 'DURATION') {
notice("The notification of this event cannot be parsed");
continue;
}
/** @var DateInterval $triggerDuration */
$triggerDuration = Sabre_VObject_DateTimeParser::parseDuration($trigger);
$unit = "hour";
$value = 1;
if ($triggerDuration->s > 0) {
$unit = "second";
$value = $triggerDuration->s + $triggerDuration->i * 60 + $triggerDuration->h * 3600 + $triggerDuration->d * 3600 * 24; // @TODO support more than days?
} elseif ($triggerDuration->m) {
$unit = "minute";
$value = $triggerDuration->i + $triggerDuration->h * 60 + $triggerDuration->d * 60 * 24;
} elseif ($triggerDuration->h) {
$unit = "hour";
$value = $triggerDuration->h + $triggerDuration->d * 24;
} elseif ($triggerDuration->d > 0) {
$unit = "day";
$value = $triggerDuration->d;
}
$rel = (isset($trigger['RELATED']) && strtoupper($trigger['RELATED']) == 'END') ? 'end' : 'start';
$notifications[] = array(
"action" => strtolower($action),
"rel" => $rel,
"trigger_unit" => $unit,
"trigger_value" => $value,
);
}
if ($component->select("RRULE")) $recurrence = new Sabre_VObject_RecurrenceIterator($vObject, (string)$component->__get("UID")); if ($component->select("RRULE")) $recurrence = new Sabre_VObject_RecurrenceIterator($vObject, (string)$component->__get("UID"));
else $recurrence = null; else $recurrence = null;
} elseif (isset($_REQUEST["start"]) && $_REQUEST["start"] > 0) { } elseif (isset($_REQUEST["start"]) && $_REQUEST["start"] > 0) {
$calendars = dav_get_current_user_calendars($server, DAV_ACL_WRITE); $calendars = dav_get_current_user_calendars($server, DAV_ACL_WRITE);
$calendar = dav_get_current_user_calendar_by_id($server, $calendar_id, DAV_ACL_WRITE); //$calendar = dav_get_current_user_calendar_by_id($server, $calendar_id, DAV_ACL_WRITE);
$event = array( $event = array(
"id" => 0, "id" => 0,
@ -71,15 +110,15 @@ function wdcal_getEditPage_str(&$localization, $baseurl, $uid, $calendar_id, $ur
"Color" => null, "Color" => null,
); );
if ($_REQUEST["isallday"]) { if ($_REQUEST["isallday"]) {
$notifications = array(array("rel" => "start", "type" => "duration", "period" => "hour", "period_val" => 24)); $notifications = array();
} else { } else {
$notifications = array(array("rel" => "start", "type" => "duration", "period" => "hour", "period_val" => 1)); $notifications = array(array("action" => "email", "rel" => "start", "trigger_unit" => "hour", "trigger_value" => 1));
} }
$recurrence = null; $recurrence = null;
$recurrentce_exdates = array(); $recurrentce_exdates = array();
} else { } else {
$calendars = dav_get_current_user_calendars($server, DAV_ACL_WRITE); $calendars = dav_get_current_user_calendars($server, DAV_ACL_WRITE);
$calendar = dav_get_current_user_calendar_by_id($server, $calendar_id, DAV_ACL_WRITE); //$calendar = dav_get_current_user_calendar_by_id($server, $calendar_id, DAV_ACL_WRITE);
$event = array( $event = array(
"id" => 0, "id" => 0,
@ -91,7 +130,7 @@ function wdcal_getEditPage_str(&$localization, $baseurl, $uid, $calendar_id, $ur
"Location" => "", "Location" => "",
"Color" => null, "Color" => null,
); );
$notifications = array(array("rel" => "start", "type" => "duration", "period" => "hour", "period_val" => 1)); $notifications = array(array("action" => "email", "rel" => "start", "trigger_unit" => "hour", "trigger_value" => 1));
$recurrence = null; $recurrence = null;
$recurrentce_exdates = array(); $recurrentce_exdates = array();
} }
@ -270,7 +309,7 @@ function wdcal_getEditPage_str(&$localization, $baseurl, $uid, $calendar_id, $ur
$out .= "</div>"; $out .= "</div>";
$monthly_rule = ""; $monthly_rule = "";
if ($recurrence->frequency == "monthly" || $recurrence->frequency == "yearly") { if ($recurrence && ($recurrence->frequency == "monthly" || $recurrence->frequency == "yearly")) {
if (is_null($recurrence->byDay) && !is_null($recurrence->byMonthDay) && count($recurrence->byMonthDay) == 1) { if (is_null($recurrence->byDay) && !is_null($recurrence->byMonthDay) && count($recurrence->byMonthDay) == 1) {
$day = date("j", $event["StartTime"]); $day = date("j", $event["StartTime"]);
if ($recurrence->byMonthDay[0] == $day) $monthly_rule = "bymonthday"; if ($recurrence->byMonthDay[0] == $day) $monthly_rule = "bymonthday";
@ -324,7 +363,7 @@ function wdcal_getEditPage_str(&$localization, $baseurl, $uid, $calendar_id, $ur
$out .= "</select>"; $out .= "</select>";
$out .= "</div>\n"; $out .= "</div>\n";
if ($recurrence->frequency == "yearly") { if ($recurrence && $recurrence->frequency == "yearly") {
if (count($recurrence->byMonth) != 1 || $recurrence->byMonth[0] != date("n", $event["StartTime"])) notice("The recurrence of this event cannot be parsed!"); if (count($recurrence->byMonth) != 1 || $recurrence->byMonth[0] != date("n", $event["StartTime"])) notice("The recurrence of this event cannot be parsed!");
} }
@ -408,31 +447,53 @@ function wdcal_getEditPage_str(&$localization, $baseurl, $uid, $calendar_id, $ur
$out .= "<h2>" . t("Notification") . "</h2>"; $out .= "<h2>" . t("Notification") . "</h2>";
/* if (!$notifications) $notifications = array();
$out .= '<input type="checkbox" name="notification" id="notification" '; $notifications["new"] = array(
if ($notification) $out .= "checked"; "action" => "email",
$out .= '> '; "trigger_value" => 60,
$out .= '<span id="notification_detail" style="display: none;"> "trigger_unit" => "minute",
<input name="notification_value" value="' . $notification_value . '" size="3"> "rel" => "start",
<select name="notification_type" size="1"> );
<option value="minute" ';
if ($notification_type == "minute") $out .= "selected"; foreach ($notifications as $index => $noti) {
$out .= '> ' . t('Minutes') . '</option>
<option value="hour" '; $unparsable = false;
if ($notification_type == "hour") $out .= "selected"; if (!in_array($noti["action"], array("email", "display"))) $unparsable = true;
$out .= '> ' . t('Hours') . '</option>
<option value="day" '; $out .= "<div class='noti_holder' ";
if ($notification_type == "day") echo "selected"; if (!is_numeric($index) && $index == "new") $out .= "style='display: none;' id='noti_new_row'";
$out .= '> ' . t('Days') . '</option> $out .= "><label class='plain'>" . t("Notify by");
</select> ' . t('before') . ' $out .= "<select name='noti_type[$index]' size='1'>";
</span><br><br>'; $out .= "<option value=''>- " . t("Remove") . " -</option>\n";
*/ $out .= "<option value='email' "; if (!$unparsable && $noti["action"] == "email") $out .= "selected"; $out .= ">" . t("E-Mail") . "</option>\n";
$out .= "<option value='display' "; if (!$unparsable && $noti["action"] == "display") $out .= "selected"; $out .= ">" . t("On Friendica / Display") . "</option>\n";
//$out .= "<option value='other' "; if ($unparsable) $out .= "selected"; $out .= ">- " . t("other (leave it untouched)") . " -</option>\n"; // @TODO
$out .= "</select></label>";
$out .= "<input name='noti_value[$index]' size='5' style='width: 5em;' value='" . $noti["trigger_value"] . "'>";
$out .= "<select name='noti_unit[$index]' size='1'>";
$out .= "<option value='H' "; if ($noti["trigger_unit"] == "hour") $out .= "selected"; $out .= ">" . t("Hours") . "</option>\n";
$out .= "<option value='M' "; if ($noti["trigger_unit"] == "minute") $out .= "selected"; $out .= ">" . t("Minutes") . "</option>\n";
$out .= "<option value='S' "; if ($noti["trigger_unit"] == "second") $out .= "selected"; $out .= ">" . t("Seconds") . "</option>\n";
$out .= "<option value='D' "; if ($noti["trigger_unit"] == "day") $out .= "selected"; $out .= ">" . t("Days") . "</option>\n";
$out .= "<option value='W' "; if ($noti["trigger_unit"] == "week") $out .= "selected"; $out .= ">" . t("Weeks") . "</option>\n";
$out .= "</select>";
$out .= " <label class='plain'>" . t("before the") . " <select name='noti_ref[$index]' size='1'>";
$out .= "<option value='start' "; if ($noti["rel"] == "start") $out .= "selected"; $out .= ">" . t("start of the event") . "</option>\n";
$out .= "<option value='end' "; if ($noti["rel"] == "end") $out .= "selected"; $out .= ">" . t("end of the event") . "</option>\n";
$out .= "</select></label>\n";
$out .= "</div>";
}
$out .= "<input type='hidden' name='new_alarm' id='new_alarm' value='0'><div id='new_alarm_adder'><a href='#'>" . t("Add a notification") . "</a></div>";
$out .= "<script>\$(function() { $out .= "<script>\$(function() {
wdcal_edit_init('" . $localization->dateformat_datepicker_js() . "', '${baseurl}/dav/'); wdcal_edit_init('" . $localization->dateformat_datepicker_js() . "', '${baseurl}/dav/');
});</script>"; });</script>";
$out .= "<input type='submit' name='save' value='Save'></form>"; $out .= "<br><input type='submit' name='save' value='Save'></form>";
return $out; return $out;
} }
@ -441,6 +502,7 @@ function wdcal_getEditPage_str(&$localization, $baseurl, $uid, $calendar_id, $ur
/** /**
* @param Sabre_VObject_Component_VEvent $component * @param Sabre_VObject_Component_VEvent $component
* @param wdcal_local $localization * @param wdcal_local $localization
* @return int
*/ */
function wdcal_set_component_date(&$component, &$localization) function wdcal_set_component_date(&$component, &$localization)
{ {
@ -462,6 +524,8 @@ function wdcal_set_component_date(&$component, &$localization)
$component->__unset("DTEND"); $component->__unset("DTEND");
$component->add($datetime_start); $component->add($datetime_start);
$component->add($datetime_end); $component->add($datetime_end);
return $ts_start;
} }
/** /**
@ -569,13 +633,6 @@ function wdcal_set_component_recurrence(&$component, &$localization)
default: default:
$part_freq = ""; $part_freq = "";
} }
/*
echo "<pre>!";
echo $part_freq . "\n";
var_dump($_REQUEST);
echo "</pre>";
die();
*/
if ($part_freq == "") return; if ($part_freq == "") return;
@ -598,15 +655,69 @@ function wdcal_set_component_recurrence(&$component, &$localization)
} }
/** /**
* @param Sabre_VObject_Component_VEvent $component
* @param wdcal_local $localization
* @param string $summary
* @param int $dtstart
*/
function wdcal_set_component_alerts(&$component, &$localization, $summary, $dtstart)
{
$a = get_app();
$prev_alarms = $component->select("VALARM");
$component->__unset("VALARM");
foreach ($prev_alarms as $al) {
/** @var Sabre_VObject_Component_VAlarm $al */
}
foreach (array_keys($_REQUEST["noti_type"]) as $key) if (is_numeric($key) || ($key == "new" && $_REQUEST["new_alarm"] == 1)) {
$alarm = new Sabre_VObject_Component_VAlarm("VALARM");
switch ($_REQUEST["noti_type"][$key]) {
case "email":
$mailtext = str_replace(array(
"#date#", "#name",
), array(
$localization->date_timestamp2local($dtstart), $summary,
), t("The event #name# will start at #date"));
$alarm->add(new Sabre_VObject_Property("ACTION", "EMAIL"));
$alarm->add(new Sabre_VObject_Property("SUMMARY", $summary));
$alarm->add(new Sabre_VObject_Property("DESCRIPTION", $mailtext));
$alarm->add(new Sabre_VObject_Property("ATTENDEE", "MAILTO:" . $a->user["email"]));
break;
case "display":
$alarm->add(new Sabre_VObject_Property("ACTION", "DISPLAY"));
$text = str_replace("#name#", $summary, t("#name# is about to begin."));
$alarm->add(new Sabre_VObject_Property("DESCRIPTION", $text));
break;
default:
continue;
}
$trigger_name = "TRIGGER";
$trigger_val = ""; // @TODO Bugfix : und ; sind evtl. vertauscht vgl. http://www.kanzaki.com/docs/ical/trigger.html
if ($_REQUEST["noti_ref"][$key] == "end") $trigger_name .= ";RELATED=END";
$trigger_val .= "-P";
if (in_array($_REQUEST["noti_unit"][$key], array("H", "M", "S"))) $trigger_val .= "T";
$trigger_val .= IntVal($_REQUEST["noti_value"][$key]) . $_REQUEST["noti_unit"][$key];
$alarm->add(new Sabre_VObject_Property($trigger_name, $trigger_val));
$component->add($alarm);
}
}
/**
* @param string $uri * @param string $uri
* @param string $recurr_uri
* @param int $uid * @param int $uid
* @param string $timezone * @param string $timezone
* @param string $goaway_url * @param string $goaway_url
* @return array * @return array
*/ */
function wdcal_postEditPage($uri, $recurr_uri = "", $uid = 0, $timezone = "", $goaway_url = "") function wdcal_postEditPage($uri, $uid = 0, $timezone = "", $goaway_url = "")
{ {
$uid = IntVal($uid); $uid = IntVal($uid);
$localization = wdcal_local::getInstanceByUser($uid); $localization = wdcal_local::getInstanceByUser($uid);
@ -629,8 +740,9 @@ function wdcal_postEditPage($uri, $recurr_uri = "", $uid = 0, $timezone = "", $g
$obj_uri = $component->__get("UID"); $obj_uri = $component->__get("UID");
} }
wdcal_set_component_date($component, $localization); $ts_start = wdcal_set_component_date($component, $localization);
wdcal_set_component_recurrence($component, $localization); wdcal_set_component_recurrence($component, $localization);
wdcal_set_component_alerts($component, $localization, icalendar_sanitize_string(dav_compat_parse_text_serverside("summary")), $ts_start);
$component->__unset("LOCATION"); $component->__unset("LOCATION");
$component->__unset("SUMMARY"); $component->__unset("SUMMARY");

View File

@ -290,10 +290,9 @@ function wdcal_printCalendar($calendars, $calendars_selected, $data_feed_url, $v
/** /**
* @param int $calendar_id * @param int $calendar_id
* @param int $calendarobject_id * @param int $calendarobject_id
* @param string $recurr_uri
* @return string * @return string
*/ */
function wdcal_getDetailPage($calendar_id, $calendarobject_id, $recurr_uri) function wdcal_getDetailPage($calendar_id, $calendarobject_id)
{ {
$a = get_app(); $a = get_app();
@ -322,15 +321,14 @@ function wdcal_getDetailPage($calendar_id, $calendarobject_id, $recurr_uri)
/** /**
* @param int $calendar_id * @param int $calendar_id
* @param int $uri * @param int $uri
* @param string $recurr_uri
* @return string * @return string
*/ */
function wdcal_getEditPage($calendar_id, $uri, $recurr_uri = "") function wdcal_getEditPage($calendar_id, $uri)
{ {
$a = get_app(); $a = get_app();
$localization = wdcal_local::getInstanceByUser($a->user["uid"]); $localization = wdcal_local::getInstanceByUser($a->user["uid"]);
return wdcal_getEditPage_str($localization, $a->get_baseurl(), $a->user["uid"], $calendar_id, $uri, $recurr_uri); return wdcal_getEditPage_str($localization, $a->get_baseurl(), $calendar_id, $uri);
} }
/** /**
@ -341,7 +339,7 @@ function wdcal_getNewPage()
$a = get_app(); $a = get_app();
$localization = wdcal_local::getInstanceByUser($a->user["uid"]); $localization = wdcal_local::getInstanceByUser($a->user["uid"]);
return wdcal_getEditPage_str($localization, $a->get_baseurl(), $a->user["uid"], 0, 0); return wdcal_getEditPage_str($localization, $a->get_baseurl(), 0, 0);
} }

View File

@ -24,12 +24,6 @@ function dav_module()
function dav_include_files() function dav_include_files()
{ {
/*
require_once (__DIR__ . "/SabreDAV/lib/Sabre.includes.php");
require_once (__DIR__ . "/SabreDAV/lib/Sabre/VObject/includes.php");
require_once (__DIR__ . "/SabreDAV/lib/Sabre/DAVACL/includes.php");
require_once (__DIR__ . "/SabreDAV/lib/Sabre/CalDAV/includes.php");
*/
require_once (__DIR__ . "/SabreDAV/lib/Sabre/autoload.php"); require_once (__DIR__ . "/SabreDAV/lib/Sabre/autoload.php");
require_once (__DIR__ . "/common/calendar.fnk.php"); require_once (__DIR__ . "/common/calendar.fnk.php");
@ -145,20 +139,19 @@ function dav_content()
} elseif (isset($a->argv[3]) && $a->argv[3] == "ics-import") { } elseif (isset($a->argv[3]) && $a->argv[3] == "ics-import") {
return wdcal_import_user_ics($calendar_id); return wdcal_import_user_ics($calendar_id);
} elseif (isset($a->argv[3]) && $a->argv[3] > 0) { } elseif (isset($a->argv[3]) && $a->argv[3] > 0) {
$recurr_uri = ""; // @TODO
if (isset($a->argv[4]) && $a->argv[4] == "edit") { if (isset($a->argv[4]) && $a->argv[4] == "edit") {
$o = ""; $o = "";
if (isset($_REQUEST["save"])) { if (isset($_REQUEST["save"])) {
check_form_security_token_redirectOnErr($a->get_baseurl() . "/dav/wdcal/", "caledit"); check_form_security_token_redirectOnErr($a->get_baseurl() . "/dav/wdcal/", "caledit");
$ret = wdcal_postEditPage($a->argv[3], $recurr_uri, $a->user["uid"], $a->timezone, $a->get_baseurl() . "/dav/wdcal/"); $ret = wdcal_postEditPage($a->argv[3], $a->user["uid"], $a->timezone, $a->get_baseurl() . "/dav/wdcal/");
if ($ret["ok"]) notice($ret["msg"]); if ($ret["ok"]) notice($ret["msg"]);
else info($ret["msg"]); else info($ret["msg"]);
goaway($a->get_baseurl() . "/dav/wdcal/"); goaway($a->get_baseurl() . "/dav/wdcal/");
} }
$o .= wdcal_getEditPage($calendar_id, $a->argv[3], $recurr_uri); $o .= wdcal_getEditPage($calendar_id, $a->argv[3]);
return $o; return $o;
} else { } else {
return wdcal_getDetailPage($calendar_id, $a->argv[3], $recurr_uri); return wdcal_getDetailPage($calendar_id, $a->argv[3]);
} }
} else { } else {
// @TODO Edit Calendar // @TODO Edit Calendar