server = $server; $server->on('method:GET', [$this, 'httpGet'], 90); $server->on('propFind', [$this, 'propFind']); $server->xml->namespaceMap[self::NS_CALENDARSERVER] = 'cs'; $server->resourceTypeMapping['\\Sabre\\CalDAV\\Notifications\\ICollection'] = '{' . self::NS_CALENDARSERVER . '}notification'; array_push($server->protectedProperties, '{' . self::NS_CALENDARSERVER . '}notification-URL', '{' . self::NS_CALENDARSERVER . '}notificationtype' ); } /** * PropFind * * @param PropFind $propFind * @param BaseINode $node * @return void */ function propFind(PropFind $propFind, BaseINode $node) { $caldavPlugin = $this->server->getPlugin('caldav'); if ($node instanceof DAVACL\IPrincipal) { $principalUrl = $node->getPrincipalUrl(); // notification-URL property $propFind->handle('{' . self::NS_CALENDARSERVER . '}notification-URL', function() use ($principalUrl, $caldavPlugin) { $notificationPath = $caldavPlugin->getCalendarHomeForPrincipal($principalUrl) . '/notifications/'; return new DAV\Xml\Property\Href($notificationPath); }); } if ($node instanceof INode) { $propFind->handle( '{' . self::NS_CALENDARSERVER . '}notificationtype', [$node, 'getNotificationType'] ); } } /** * This event is triggered before the usual GET request handler. * * We use this to intercept GET calls to notification nodes, and return the * proper response. * * @param RequestInterface $request * @param ResponseInterface $response * @return void */ function httpGet(RequestInterface $request, ResponseInterface $response) { $path = $request->getPath(); try { $node = $this->server->tree->getNodeForPath($path); } catch (DAV\Exception\NotFound $e) { return; } if (!$node instanceof INode) return; $writer = $this->server->xml->getWriter(); $writer->contextUri = $this->server->getBaseUri(); $writer->openMemory(); $writer->startDocument('1.0', 'UTF-8'); $writer->startElement('{http://calendarserver.org/ns/}notification'); $node->getNotificationType()->xmlSerializeFull($writer); $writer->endElement(); $response->setHeader('Content-Type', 'application/xml'); $response->setHeader('ETag', $node->getETag()); $response->setStatus(200); $response->setBody($writer->outputMemory()); // Return false to break the event chain. return false; } /** * Returns a bunch of meta-data about the plugin. * * Providing this information is optional, and is mainly displayed by the * Browser plugin. * * The description key in the returned array may contain html and will not * be sanitized. * * @return array */ function getPluginInfo() { return [ 'name' => $this->getPluginName(), 'description' => 'Adds support for caldav-notifications, which is required to enable caldav-sharing.', 'link' => 'http://sabre.io/dav/caldav-sharing/', ]; } }