add Sabre DAV plugin to handle default alarms
authorLars Kneschke <l.kneschke@metaways.de>
Wed, 5 Feb 2014 05:17:05 +0000 (06:17 +0100)
committerPhilipp Schüle <p.schuele@metaways.de>
Thu, 4 Sep 2014 09:25:27 +0000 (11:25 +0200)
See http://tools.ietf.org/html/draft-daboo-valarm-extensions-04

Change-Id: I58c41c6edecef8d587111aabb02471daf818b3fc
Reviewed-on: http://gerrit.tine20.com/customers/319
Tested-by: Jenkins CI (http://ci.tine20.com/)
Reviewed-by: Philipp Schüle <p.schuele@metaways.de>
tests/tine20/Calendar/Frontend/AllTests.php
tests/tine20/Calendar/Frontend/CalDAV/AllTests.php [new file with mode: 0644]
tests/tine20/Calendar/Frontend/CalDAV/PluginDefaultAlarmsTest.php [new file with mode: 0644]
tine20/Calendar/Frontend/CalDAV/PluginDefaultAlarms.php [new file with mode: 0644]
tine20/Tinebase/Server/WebDAV.php

index e70edf5..7120cbd 100644 (file)
@@ -30,6 +30,7 @@ class Calendar_Frontend_AllTests
         $suite->addTest(Calendar_Frontend_WebDAV_AllTests::suite());
         $suite->addTestSuite('Calendar_Frontend_CalDAVTest');
         $suite->addTestSuite('Calendar_Frontend_iMIPTest');
+        $suite->addTestSuite('Calendar_Frontend_CalDAV_AllTests');
         return $suite;
     }
 }
diff --git a/tests/tine20/Calendar/Frontend/CalDAV/AllTests.php b/tests/tine20/Calendar/Frontend/CalDAV/AllTests.php
new file mode 100644 (file)
index 0000000..aa521b6
--- /dev/null
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Tine 2.0 - http://www.tine20.org
+ * 
+ * @package     Calendar
+ * @license     http://www.gnu.org/licenses/agpl.html
+ * @copyright   Copyright (c) 2011-2011 Metaways Infosystems GmbH (http://www.metaways.de)
+ * @author      Lars Kneschke <l.kneschke@metaways.de>
+ */
+
+/**
+ * Test helper
+ */
+require_once dirname(dirname(dirname(dirname(__FILE__)))) . DIRECTORY_SEPARATOR . 'TestHelper.php';
+
+class Calendar_Frontend_CalDAV_AllTests
+{
+    public static function main ()
+    {
+        PHPUnit_TextUI_TestRunner::run(self::suite());
+    }
+    
+    public static function suite ()
+    {
+        $suite = new PHPUnit_Framework_TestSuite('Tine 2.0 Calendar All Frontend CalDAV Tests');
+        $suite->addTestSuite('Calendar_Frontend_CalDAV_PluginDefaultAlarmsTest');
+        return $suite;
+    }
+}
diff --git a/tests/tine20/Calendar/Frontend/CalDAV/PluginDefaultAlarmsTest.php b/tests/tine20/Calendar/Frontend/CalDAV/PluginDefaultAlarmsTest.php
new file mode 100644 (file)
index 0000000..4b0c1a2
--- /dev/null
@@ -0,0 +1,107 @@
+<?php
+/**
+ * Tine 2.0 - http://www.tine20.org
+ * 
+ * @package     Tinebase
+ * @subpackage  Frontend
+ * @license     http://www.gnu.org/licenses/agpl.html
+ * @copyright   Copyright (c) 2013-2013 Metaways Infosystems GmbH (http://www.metaways.de)
+ * @author      Lars Kneschke <l.kneschke@metaways.de>
+ */
+
+/**
+ * Test helper
+ */
+require_once 'vendor/sabre/dav/tests/Sabre/HTTP/ResponseMock.php';
+
+/**
+ * Test class for Tinebase_WebDav_Plugin_OwnCloud
+ */
+class Calendar_Frontend_CalDAV_PluginDefaultAlarmsTest extends TestCase
+{
+    /**
+     * 
+     * @var Sabre\DAV\Server
+     */
+    protected $server;
+    
+    /**
+     * Sets up the fixture.
+     * This method is called before a test is executed.
+     *
+     * @access protected
+     */
+    protected function setUp()
+    {
+        parent::setUp();
+        
+        $this->server = new Sabre\DAV\Server(new Tinebase_WebDav_Root());
+        
+        $this->plugin = new Calendar_Frontend_CalDAV_PluginDefaultAlarms();
+        
+        $this->server->addPlugin($this->plugin);
+        
+        $this->response = new Sabre\HTTP\ResponseMock();
+        $this->server->httpResponse = $this->response;
+    }
+
+    /**
+     * test getPluginName method
+     */
+    public function testGetPluginName()
+    {
+        $pluginName = $this->plugin->getPluginName();
+        
+        $this->assertEquals('calendarDefaultAlarms', $pluginName);
+    }
+    
+    /**
+     * test testGetProperties method
+     */
+    public function testGetProperties()
+    {
+        $body = '<?xml version="1.0" encoding="utf-8"?>
+                 <propfind xmlns="DAV:">
+                    <prop>
+                        <default-alarm-vevent-date xmlns="urn:ietf:params:xml:ns:caldav"/>
+                        <default-alarm-vevent-datetime xmlns="urn:ietf:params:xml:ns:caldav"/>
+                        <default-alarm-vtodo-date xmlns="urn:ietf:params:xml:ns:caldav"/>
+                        <default-alarm-vtodo-datetime xmlns="urn:ietf:params:xml:ns:caldav"/>
+                    </prop>
+                 </propfind>';
+
+        $request = new Sabre\HTTP\Request(array(
+            'REQUEST_METHOD' => 'PROPFIND',
+            'REQUEST_URI'    => '/calendars/' . Tinebase_Core::getUser()->contact_id,
+            'HTTP_DEPTH'     => '0',
+        ));
+        $request->setBody($body);
+
+        $this->server->httpRequest = $request;
+        $this->server->exec();
+        //var_dump($this->response->body);
+        $this->assertEquals('HTTP/1.1 207 Multi-Status', $this->response->status);
+        
+        $responseDoc = new DOMDocument();
+        $responseDoc->loadXML($this->response->body);
+        //$responseDoc->formatOutput = true; echo $responseDoc->saveXML();
+        $xpath = new DomXPath($responseDoc);
+        $xpath->registerNamespace('cal', 'urn:ietf:params:xml:ns:caldav');
+        
+        $nodes = $xpath->query('//d:multistatus/d:response/d:propstat/d:prop/cal:default-alarm-vevent-datetime');
+        $this->assertEquals(1, $nodes->length, $responseDoc->saveXML());
+        $this->assertNotEmpty($nodes->item(0)->nodeValue, $responseDoc->saveXML());
+        
+        $nodes = $xpath->query('//d:multistatus/d:response/d:propstat/d:prop/cal:default-alarm-vevent-date');
+        $this->assertEquals(1, $nodes->length, $responseDoc->saveXML());
+        $this->assertNotEmpty($nodes->item(0)->nodeValue, $responseDoc->saveXML());
+        
+        $nodes = $xpath->query('//d:multistatus/d:response/d:propstat/d:prop/cal:default-alarm-vtodo-datetime');
+        $this->assertEquals(1, $nodes->length, $responseDoc->saveXML());
+        $this->assertNotEmpty($nodes->item(0)->nodeValue, $responseDoc->saveXML());
+        
+        $nodes = $xpath->query('//d:multistatus/d:response/d:propstat/d:prop/cal:default-alarm-vtodo-date');
+        $this->assertEquals(1, $nodes->length, $responseDoc->saveXML());
+        $this->assertNotEmpty($nodes->item(0)->nodeValue, $responseDoc->saveXML());
+    }
+}
diff --git a/tine20/Calendar/Frontend/CalDAV/PluginDefaultAlarms.php b/tine20/Calendar/Frontend/CalDAV/PluginDefaultAlarms.php
new file mode 100644 (file)
index 0000000..ade5682
--- /dev/null
@@ -0,0 +1,136 @@
+<?php
+/**
+ * CalDAV plugin for draft-daboo-valarm-extensions-04
+ * 
+ * This plugin provides functionality added by RFC6638
+ * It takes care of additional properties and features
+ * 
+ * see: http://tools.ietf.org/html/draft-daboo-valarm-extensions-04
+ *
+ * @package    Sabre
+ * @subpackage CalDAV
+ * @copyright  Copyright (c) 2014-2014 Metaways Infosystems GmbH (http://www.metaways.de)
+ * @author     Lars Kneschke <l.kneschke@metaways.de>
+ * @license    http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class Calendar_Frontend_CalDAV_PluginDefaultAlarms extends \Sabre\DAV\ServerPlugin 
+{
+    /**
+     * Reference to server object
+     *
+     * @var \Sabre\DAV\Server
+     */
+    protected $server;
+
+    /**
+     * Returns a list of features for the DAV: HTTP header. 
+     * 
+     * @return array 
+     */
+    public function getFeatures() 
+    {
+        return array('calendar-default-alarms');
+    }
+
+    /**
+     * Returns a plugin name.
+     * 
+     * Using this name other plugins will be able to access other plugins
+     * using \Sabre\DAV\Server::getPlugin 
+     * 
+     * @return string 
+     */
+    public function getPluginName() 
+    {
+        return 'calendarDefaultAlarms';
+    }
+
+    /**
+     * Initializes the plugin 
+     * 
+     * @param \Sabre\DAV\Server $server 
+     * @return void
+     */
+    public function initialize(\Sabre\DAV\Server $server) 
+    {
+        $this->server = $server;
+
+        $server->subscribeEvent('beforeGetProperties', array($this, 'beforeGetProperties'));
+
+        $server->xmlNamespaces[\Sabre\CalDAV\Plugin::NS_CALDAV] = 'cal';
+    }
+    
+    /**
+     * beforeGetProperties
+     *
+     * This method handler is invoked before any after properties for a
+     * resource are fetched. This allows us to add in any CalDAV specific
+     * properties.
+     *
+     * @param string $path
+     * @param \Sabre\DAV\INode $node
+     * @param array $requestedProperties
+     * @param array $returnedProperties
+     * @return void
+     */
+    public function beforeGetProperties($path, \Sabre\DAV\INode $node, &$requestedProperties, &$returnedProperties) 
+    {
+        if ($node instanceof \Sabre\CalDAV\ICalendar || $node instanceof Calendar_Frontend_CalDAV) {
+            $vcalendar = new \Sabre\VObject\Component\VCalendar();
+            
+            $property = '{' . \Sabre\CalDAV\Plugin::NS_CALDAV . '}default-alarm-vevent-datetime';
+            if (in_array($property, $requestedProperties)) {
+                unset($requestedProperties[array_search($property, $requestedProperties)]);
+                
+                $valarm = $vcalendar->create('VALARM');
+                $valarm->add('ACTION',  'NONE');
+                $valarm->add('TRIGGER', '19760401T005545Z', array('VALUE' => 'DATE-TIME'));
+                $valarm->add('UID',     'E35C3EB2-4DC1-4223-AA5D-B4B491F2C111');
+                
+                // Taking out \r to not screw up the xml output
+                $returnedProperties[200][$property] = str_replace("\r","", $valarm->serialize()); 
+            }
+            
+            $property = '{' . \Sabre\CalDAV\Plugin::NS_CALDAV . '}default-alarm-vevent-date';
+            if (in_array($property, $requestedProperties)) {
+                unset($requestedProperties[array_search($property, $requestedProperties)]);
+                
+                $valarm = $vcalendar->create('VALARM');
+                $valarm->add('ACTION',  'AUDIO');
+                $valarm->add('ATTACH',  'Basso', array('VALUE' => 'URI'));
+                $valarm->add('TRIGGER', '-PT15H');
+                $valarm->add('UID',     '17DC9682-230E-47D6-A035-EEAB602B1229');
+                
+                // Taking out \r to not screw up the xml output
+                $returnedProperties[200][$property] = str_replace("\r","", $valarm->serialize()); 
+            }
+            
+            $property = '{' . \Sabre\CalDAV\Plugin::NS_CALDAV . '}default-alarm-vtodo-datetime';
+            if (in_array($property, $requestedProperties)) {
+                unset($requestedProperties[array_search($property, $requestedProperties)]);
+                
+                $valarm = $vcalendar->create('VALARM');
+                $valarm->add('ACTION',  'NONE');
+                $valarm->add('TRIGGER', '19760401T005545Z', array('VALUE' => 'DATE-TIME'));
+                $valarm->add('UID',     'D35C3EB2-4DC1-4223-AA5D-B4B491F2C111');
+                
+                // Taking out \r to not screw up the xml output
+                $returnedProperties[200][$property] = str_replace("\r","", $valarm->serialize()); 
+            }
+            
+            $property = '{' . \Sabre\CalDAV\Plugin::NS_CALDAV . '}default-alarm-vtodo-date';
+            if (in_array($property, $requestedProperties)) {
+                unset($requestedProperties[array_search($property, $requestedProperties)]);
+                
+                $valarm = $vcalendar->create('VALARM');
+                $valarm->add('ACTION',  'AUDIO');
+                $valarm->add('ATTACH',  'Basso', array('VALUE' => 'URI'));
+                $valarm->add('TRIGGER', '-PT15H');
+                $valarm->add('UID',     '27DC9682-230E-47D6-A035-EEAB602B1229');
+                
+                // Taking out \r to not screw up the xml output
+                $returnedProperties[200][$property] = str_replace("\r","", $valarm->serialize()); 
+            }
+        }
+    }
+}
index 17f719e..97bea2b 100644 (file)
@@ -107,6 +107,7 @@ class Tinebase_Server_WebDAV extends Tinebase_Server_Abstract implements Tinebas
         self::$_server->addPlugin(new \Sabre\CardDAV\Plugin());
         self::$_server->addPlugin(new \Sabre\CalDAV\Plugin());
         self::$_server->addPlugin(new Calendar_Frontend_CalDAV_PluginAutoSchedule());
+        self::$_server->addPlugin(new Calendar_Frontend_CalDAV_PluginDefaultAlarms());
         self::$_server->addPlugin(new Tinebase_WebDav_Plugin_Inverse());
         self::$_server->addPlugin(new Tinebase_WebDav_Plugin_OwnCloud());
         #self::$_server->addPlugin(new DAV\Sync\Plugin());