[Pkg-owncloud-commits] [php-sabredav] 172/275: addressbook-multiget and addressbook-report support content-negotiation.

David Prévot taffit at moszumanska.debian.org
Thu Sep 25 14:56:05 UTC 2014


This is an automated email from the git hooks/post-receive script.

taffit pushed a commit to branch master
in repository php-sabredav.

commit 6a5e407c563960db48c3fc2377a360076b904aa8
Author: Evert Pot <me at evertpot.com>
Date:   Thu Aug 21 17:56:16 2014 -0400

    addressbook-multiget and addressbook-report support content-negotiation.
---
 lib/CardDAV/Plugin.php               | 162 ++++++++++++++++++++++++++---------
 tests/Sabre/CardDAV/MultiGetTest.php |   2 +-
 2 files changed, 121 insertions(+), 43 deletions(-)

diff --git a/lib/CardDAV/Plugin.php b/lib/CardDAV/Plugin.php
index 3ab28db..6602f2f 100644
--- a/lib/CardDAV/Plugin.php
+++ b/lib/CardDAV/Plugin.php
@@ -6,9 +6,11 @@ use Sabre\DAV;
 use Sabre\DAVACL;
 use Sabre\VObject;
 
+use Sabre\HTTP;
 use Sabre\HTTP\RequestInterface;
 use Sabre\HTTP\ResponseInterface;
 
+
 /**
  * CardDAV plugin
  *
@@ -299,10 +301,31 @@ class Plugin extends DAV\ServerPlugin {
 
         }
 
-        $propertyList = array_values(
-            $this->server->getPropertiesForMultiplePaths($uris, $properties)
+        $xpath = new \DOMXPath($dom);
+        $xpath->registerNameSpace('card',Plugin::NS_CARDDAV);
+        $xpath->registerNameSpace('dav','urn:DAV');
+
+        $requestedContentType = $xpath->evaluate("string(/card:addressbook-multiget/dav:prop/card:address-data[@content-type])");
+
+        $vcardType = $this->negotiateVCard(
+            $requestedContentType
         );
 
+        $propertyList = [];
+        foreach($this->server->getPropertiesForMultiplePaths($uris, $properties) as $props) {
+
+            if (isset($props['200']['{' . self::NS_CARDDAV . '}address-data'])) {
+
+                $props['200']['{' . self::NS_CARDDAV . '}address-data'] = $this->convertVCard(
+                    $props[200]['{' . self::NS_CARDDAV . '}address-data'],
+                    $vcardType
+                );
+
+            }
+            $propertyList[] = $props;
+
+        }
+
         $prefer = $this->server->getHTTPPRefer();
 
         $this->server->httpResponse->setStatus(207);
@@ -442,6 +465,17 @@ class Plugin extends DAV\ServerPlugin {
             $candidateNodes = $this->server->tree->getChildren($this->server->getRequestUri());
         }
 
+        $xpath = new \DOMXPath($dom);
+        $xpath->registerNameSpace('card',Plugin::NS_CARDDAV);
+        $xpath->registerNameSpace('dav','urn:DAV');
+
+        $requestedContentType = $xpath->evaluate("string(/card:addressbook-multiget/dav:prop/card:address-data[@content-type])");
+
+        $vcardType = $this->negotiateVCard(
+            $requestedContentType
+        );
+
+
         $validNodes = [];
         foreach($candidateNodes as $node) {
 
@@ -475,7 +509,17 @@ class Plugin extends DAV\ServerPlugin {
                 $href = $this->server->getRequestUri() . '/' . $validNode->getName();
             }
 
-            list($result[]) = $this->server->getPropertiesForPath($href, $query->requestedProperties, 0);
+            list($props) = $this->server->getPropertiesForPath($href, $query->requestedProperties, 0);
+
+            if (isset($props['200']['{' . self::NS_CARDDAV . '}address-data'])) {
+
+                $props['200']['{' . self::NS_CARDDAV . '}address-data'] = $this->convertVCard(
+                    $props[200]['{' . self::NS_CARDDAV . '}address-data'],
+                    $vcardType
+                );
+
+            }
+            $result[] = $props;
 
         }
 
@@ -738,8 +782,59 @@ class Plugin extends DAV\ServerPlugin {
             return;
         }
 
+        $target = $this->negotiateVCard($request->getHeader('Accept'));
+
+        $newBody = $this->convertVCard(
+            $response->getBody(),
+            $target
+        );
+
+        $response->setBody($newBody);
+        $response->setHeader('Content-Type', $result . '; charset=utf-8');
+        $response->setHeader('Content-Length', strlen($body));
+
+    }
+
+    /**
+     * This method allows us to intercept the 'mkaddressbook' sabreAction. This
+     * action enables the user to create new addressbooks from the browser plugin.
+     *
+     * @param string $uri
+     * @param string $action
+     * @param array $postVars
+     * @return bool
+     */
+    function browserPostAction($uri, $action, array $postVars) {
+
+        if ($action!=='mkaddressbook')
+            return;
+
+        $resourceType = ['{DAV:}collection','{urn:ietf:params:xml:ns:carddav}addressbook'];
+        $properties = [];
+        if (isset($postVars['{DAV:}displayname'])) {
+            $properties['{DAV:}displayname'] = $postVars['{DAV:}displayname'];
+        }
+        $this->server->createCollection($uri . '/' . $postVars['name'],$resourceType,$properties);
+        return false;
+
+    }
+
+    /**
+     * This helper function performs the content-type negotiation for vcards.
+     *
+     * It will return one of the following strings:
+     * 1. vcard3
+     * 2. vcard4
+     * 3. jcard
+     *
+     * It defaults to vcard3.
+     *
+     * @return string
+     */
+    protected function negotiateVCard($input) {
+
         $result = HTTP\Util::negotiate(
-            $request->getHeader('Accept'),
+            $input,
             [
                 // Most often used mime-type. Version 3
                 'text/x-vcard',
@@ -755,62 +850,45 @@ class Plugin extends DAV\ServerPlugin {
             ]
         );
 
-        // Transforming.
-        $vobj = VObject\Reader::read($response->getBody());
-
         switch($result) {
 
             default :
             case 'text/x-vcard' :
             case 'text/vcard' :
             case 'text/vcard; version=3.0' :
-                if ($vobj->getDocumentType() === VObject\Document::VCARD30) {
-                    return;
-                }
-                $vobj = $vobj->convert(VObject\Document::VCARD30);
-                $newBody = $vobj->serialize();
-                break;
+                return 'vcard3';
             case 'text/vcard; version=4.0' :
-                if ($vobj->getDocumentType() === VObject\Document::VCARD40) {
-                    return;
-                }
-                $vobj = $vobj->convert(VObject\Document::VCARD40);
-                $newBody = $vobj->serialize();
-                break;
+                return 'vcard4';
             case 'application/vcard+json' :
-                $vobj = $vobj->convert(VObject\Document::VCARD40);
-                $newBody = json_encode($vobj->jsonSerialize());
-                break;
+                return 'jcard';
 
         }
 
-        $response->setBody($newBody);
-        $response->setHeader('Content-Type', $result . '; charset=utf-8');
-        $response->setHeader('Content-Length', strlen($body));
-
     }
 
     /**
-     * This method allows us to intercept the 'mkaddressbook' sabreAction. This
-     * action enables the user to create new addressbooks from the browser plugin.
+     * Converts a vcard blob to a different version, or jcard.
      *
-     * @param string $uri
-     * @param string $action
-     * @param array $postVars
-     * @return bool
+     * @param string $data
+     * @param string $target
+     * @return string
      */
-    function browserPostAction($uri, $action, array $postVars) {
+    protected function convertVCard($data, $target) {
 
-        if ($action!=='mkaddressbook')
-            return;
-
-        $resourceType = ['{DAV:}collection','{urn:ietf:params:xml:ns:carddav}addressbook'];
-        $properties = [];
-        if (isset($postVars['{DAV:}displayname'])) {
-            $properties['{DAV:}displayname'] = $postVars['{DAV:}displayname'];
+        $data = VObject\Reader::read($data);
+        switch($data) {
+            default :
+            case 'vcard3' :
+                $data = $data->convert(VObject\Document::VCARD30);
+                return $data->serialize();
+            case 'vcard4' :
+                $data = $data->convert(VObject\Document::VCARD40);
+                return $data->serialize();
+            case 'jcard' :
+                $data = $data->convert(VObject\Document::VCARD40);
+                return json_encode($vcard->jsonSerialize());
         }
-        $this->server->createCollection($uri . '/' . $postVars['name'],$resourceType,$properties);
-        return false;
 
     }
+
 }
diff --git a/tests/Sabre/CardDAV/MultiGetTest.php b/tests/Sabre/CardDAV/MultiGetTest.php
index 549ce98..621754e 100644
--- a/tests/Sabre/CardDAV/MultiGetTest.php
+++ b/tests/Sabre/CardDAV/MultiGetTest.php
@@ -45,7 +45,7 @@ class MultiGetTest extends AbstractPluginTest {
             '/addressbooks/user1/book1/card1' => array(
                 200 => array(
                     '{DAV:}getetag' => '"' . md5("BEGIN:VCARD\nVERSION:3.0\nUID:12345\nEND:VCARD") . '"',
-                    '{urn:ietf:params:xml:ns:carddav}address-data' => "BEGIN:VCARD\nVERSION:3.0\nUID:12345\nEND:VCARD",
+                    '{urn:ietf:params:xml:ns:carddav}address-data' => "BEGIN:VCARD\r\nVERSION:3.0\r\nUID:12345\r\nEND:VCARD\r\n",
                 )
             )
         ), $result);

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-owncloud/php-sabredav.git



More information about the Pkg-owncloud-commits mailing list