Пример #1
1
 /**
  * PropFind
  *
  * 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 DAV\PropFind $propFind
  * @param DAV\INode $node
  * @return void
  */
 function propFind(DAV\PropFind $propFind, DAV\INode $node)
 {
     $ns = '{' . self::NS_CALDAV . '}';
     if ($node instanceof ICalendarObjectContainer) {
         $propFind->handle($ns . 'max-resource-size', $this->maxResourceSize);
         $propFind->handle($ns . 'supported-calendar-data', function () {
             return new Xml\Property\SupportedCalendarData();
         });
         $propFind->handle($ns . 'supported-collation-set', function () {
             return new Xml\Property\SupportedCollationSet();
         });
     }
     if ($node instanceof DAVACL\IPrincipal) {
         $principalUrl = $node->getPrincipalUrl();
         $propFind->handle('{' . self::NS_CALDAV . '}calendar-home-set', function () use($principalUrl) {
             $calendarHomePath = $this->getCalendarHomeForPrincipal($principalUrl) . '/';
             return new Href($calendarHomePath);
         });
         // The calendar-user-address-set property is basically mapped to
         // the {DAV:}alternate-URI-set property.
         $propFind->handle('{' . self::NS_CALDAV . '}calendar-user-address-set', function () use($node) {
             $addresses = $node->getAlternateUriSet();
             $addresses[] = $this->server->getBaseUri() . $node->getPrincipalUrl() . '/';
             return new Href($addresses, false);
         });
         // For some reason somebody thought it was a good idea to add
         // another one of these properties. We're supporting it too.
         $propFind->handle('{' . self::NS_CALENDARSERVER . '}email-address-set', function () use($node) {
             $addresses = $node->getAlternateUriSet();
             $emails = [];
             foreach ($addresses as $address) {
                 if (substr($address, 0, 7) === 'mailto:') {
                     $emails[] = substr($address, 7);
                 }
             }
             return new Xml\Property\EmailAddressSet($emails);
         });
         // These two properties are shortcuts for ical to easily find
         // other principals this principal has access to.
         $propRead = '{' . self::NS_CALENDARSERVER . '}calendar-proxy-read-for';
         $propWrite = '{' . self::NS_CALENDARSERVER . '}calendar-proxy-write-for';
         if ($propFind->getStatus($propRead) === 404 || $propFind->getStatus($propWrite) === 404) {
             $aclPlugin = $this->server->getPlugin('acl');
             $membership = $aclPlugin->getPrincipalMembership($propFind->getPath());
             $readList = [];
             $writeList = [];
             foreach ($membership as $group) {
                 $groupNode = $this->server->tree->getNodeForPath($group);
                 $listItem = Uri\split($group)[0] . '/';
                 // If the node is either ap proxy-read or proxy-write
                 // group, we grab the parent principal and add it to the
                 // list.
                 if ($groupNode instanceof Principal\IProxyRead) {
                     $readList[] = $listItem;
                 }
                 if ($groupNode instanceof Principal\IProxyWrite) {
                     $writeList[] = $listItem;
                 }
             }
             $propFind->set($propRead, new Href($readList));
             $propFind->set($propWrite, new Href($writeList));
         }
     }
     // instanceof IPrincipal
     if ($node instanceof ICalendarObject) {
         // The calendar-data property is not supposed to be a 'real'
         // property, but in large chunks of the spec it does act as such.
         // Therefore we simply expose it as a property.
         $propFind->handle('{' . self::NS_CALDAV . '}calendar-data', function () use($node) {
             $val = $node->get();
             if (is_resource($val)) {
                 $val = stream_get_contents($val);
             }
             // Taking out \r to not screw up the xml output
             return str_replace("\r", "", $val);
         });
     }
 }
Пример #2
0
 /**
  * Triggered after properties have been fetched.
  *
  * @param PropFind $propFind
  * @param INode $node
  * @return void
  */
 function propFind(PropFind $propFind, INode $node)
 {
     // There's a bunch of properties that must appear as a self-closing
     // xml-element. This event handler ensures that this will be the case.
     $props = ['{http://calendarserver.org/ns/}subscribed-strip-alarms', '{http://calendarserver.org/ns/}subscribed-strip-attachments', '{http://calendarserver.org/ns/}subscribed-strip-todos'];
     foreach ($props as $prop) {
         if ($propFind->getStatus($prop) === 200) {
             $propFind->set($prop, '', 200);
         }
     }
 }
Пример #3
0
 /**
  * Adds tags and favorites properties to the response,
  * if requested.
  *
  * @param PropFind $propFind
  * @param \Sabre\DAV\INode $node
  * @return void
  */
 public function handleGetProperties(PropFind $propFind, \Sabre\DAV\INode $node)
 {
     if (!$node instanceof \OCA\DAV\Connector\Sabre\Node) {
         return;
     }
     // need prefetch ?
     if ($node instanceof \OCA\DAV\Connector\Sabre\Directory && $propFind->getDepth() !== 0 && (!is_null($propFind->getStatus(self::TAGS_PROPERTYNAME)) || !is_null($propFind->getStatus(self::FAVORITE_PROPERTYNAME)))) {
         // note: pre-fetching only supported for depth <= 1
         $folderContent = $node->getChildren();
         $fileIds[] = (int) $node->getId();
         foreach ($folderContent as $info) {
             $fileIds[] = (int) $info->getId();
         }
         $tags = $this->getTagger()->getTagsForObjects($fileIds);
         if ($tags === false) {
             // the tags API returns false on error...
             $tags = array();
         }
         $this->cachedTags = $this->cachedTags + $tags;
         $emptyFileIds = array_diff($fileIds, array_keys($tags));
         // also cache the ones that were not found
         foreach ($emptyFileIds as $fileId) {
             $this->cachedTags[$fileId] = [];
         }
     }
     $tags = null;
     $isFav = null;
     $propFind->handle(self::TAGS_PROPERTYNAME, function () use($tags, &$isFav, $node) {
         list($tags, $isFav) = $this->getTagsAndFav($node->getId());
         return new TagList($tags);
     });
     $propFind->handle(self::FAVORITE_PROPERTYNAME, function () use($isFav, $node) {
         if (is_null($isFav)) {
             list(, $isFav) = $this->getTagsAndFav($node->getId());
         }
         return $isFav;
     });
 }
Пример #4
0
 /**
  * Adds shares to propfind response
  *
  * @param PropFind $propFind propfind object
  * @param \Sabre\DAV\INode $sabreNode sabre node
  */
 public function handleGetProperties(PropFind $propFind, \Sabre\DAV\INode $sabreNode)
 {
     if (!$sabreNode instanceof \OCA\DAV\Connector\Sabre\Node) {
         return;
     }
     // need prefetch ?
     if ($sabreNode instanceof \OCA\DAV\Connector\Sabre\Directory && $propFind->getDepth() !== 0 && !is_null($propFind->getStatus(self::SHARETYPES_PROPERTYNAME))) {
         $folderNode = $this->userFolder->get($propFind->getPath());
         $children = $folderNode->getDirectoryListing();
         $this->cachedShareTypes[$folderNode->getId()] = $this->getShareTypes($folderNode);
         foreach ($children as $childNode) {
             $this->cachedShareTypes[$childNode->getId()] = $this->getShareTypes($childNode);
         }
     }
     $propFind->handle(self::SHARETYPES_PROPERTYNAME, function () use($sabreNode) {
         if (isset($this->cachedShareTypes[$sabreNode->getId()])) {
             $shareTypes = $this->cachedShareTypes[$sabreNode->getId()];
         } else {
             $node = $this->userFolder->get($sabreNode->getPath());
             $shareTypes = $this->getShareTypes($node);
         }
         return new ShareTypeList($shareTypes);
     });
 }