Plugin.php 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. <?php
  2. namespace Sabre\CalDAV\Notifications;
  3. use Sabre\DAV;
  4. use Sabre\DAV\PropFind;
  5. use Sabre\DAV\INode as BaseINode;
  6. use Sabre\DAV\ServerPlugin;
  7. use Sabre\DAV\Server;
  8. use Sabre\DAVACL;
  9. use Sabre\HTTP\RequestInterface;
  10. use Sabre\HTTP\ResponseInterface;
  11. /**
  12. * Notifications plugin
  13. *
  14. * This plugin implements several features required by the caldav-notification
  15. * draft specification.
  16. *
  17. * Before version 2.1.0 this functionality was part of Sabre\CalDAV\Plugin but
  18. * this has since been split up.
  19. *
  20. * @copyright Copyright (C) fruux GmbH (https://fruux.com/)
  21. * @author Evert Pot (http://evertpot.com/)
  22. * @license http://sabre.io/license/ Modified BSD License
  23. */
  24. class Plugin extends ServerPlugin {
  25. /**
  26. * This is the namespace for the proprietary calendarserver extensions
  27. */
  28. const NS_CALENDARSERVER = 'http://calendarserver.org/ns/';
  29. /**
  30. * Reference to the main server object.
  31. *
  32. * @var Server
  33. */
  34. protected $server;
  35. /**
  36. * Returns a plugin name.
  37. *
  38. * Using this name other plugins will be able to access other plugins
  39. * using \Sabre\DAV\Server::getPlugin
  40. *
  41. * @return string
  42. */
  43. function getPluginName() {
  44. return 'notifications';
  45. }
  46. /**
  47. * This initializes the plugin.
  48. *
  49. * This function is called by Sabre\DAV\Server, after
  50. * addPlugin is called.
  51. *
  52. * This method should set up the required event subscriptions.
  53. *
  54. * @param Server $server
  55. * @return void
  56. */
  57. function initialize(Server $server) {
  58. $this->server = $server;
  59. $server->on('method:GET', [$this, 'httpGet'], 90);
  60. $server->on('propFind', [$this, 'propFind']);
  61. $server->xml->namespaceMap[self::NS_CALENDARSERVER] = 'cs';
  62. $server->resourceTypeMapping['\\Sabre\\CalDAV\\Notifications\\ICollection'] = '{' . self::NS_CALENDARSERVER . '}notification';
  63. array_push($server->protectedProperties,
  64. '{' . self::NS_CALENDARSERVER . '}notification-URL',
  65. '{' . self::NS_CALENDARSERVER . '}notificationtype'
  66. );
  67. }
  68. /**
  69. * PropFind
  70. *
  71. * @param PropFind $propFind
  72. * @param BaseINode $node
  73. * @return void
  74. */
  75. function propFind(PropFind $propFind, BaseINode $node) {
  76. $caldavPlugin = $this->server->getPlugin('caldav');
  77. if ($node instanceof DAVACL\IPrincipal) {
  78. $principalUrl = $node->getPrincipalUrl();
  79. // notification-URL property
  80. $propFind->handle('{' . self::NS_CALENDARSERVER . '}notification-URL', function() use ($principalUrl, $caldavPlugin) {
  81. $notificationPath = $caldavPlugin->getCalendarHomeForPrincipal($principalUrl) . '/notifications/';
  82. return new DAV\Xml\Property\Href($notificationPath);
  83. });
  84. }
  85. if ($node instanceof INode) {
  86. $propFind->handle(
  87. '{' . self::NS_CALENDARSERVER . '}notificationtype',
  88. [$node, 'getNotificationType']
  89. );
  90. }
  91. }
  92. /**
  93. * This event is triggered before the usual GET request handler.
  94. *
  95. * We use this to intercept GET calls to notification nodes, and return the
  96. * proper response.
  97. *
  98. * @param RequestInterface $request
  99. * @param ResponseInterface $response
  100. * @return void
  101. */
  102. function httpGet(RequestInterface $request, ResponseInterface $response) {
  103. $path = $request->getPath();
  104. try {
  105. $node = $this->server->tree->getNodeForPath($path);
  106. } catch (DAV\Exception\NotFound $e) {
  107. return;
  108. }
  109. if (!$node instanceof INode)
  110. return;
  111. $writer = $this->server->xml->getWriter();
  112. $writer->contextUri = $this->server->getBaseUri();
  113. $writer->openMemory();
  114. $writer->startDocument('1.0', 'UTF-8');
  115. $writer->startElement('{http://calendarserver.org/ns/}notification');
  116. $node->getNotificationType()->xmlSerializeFull($writer);
  117. $writer->endElement();
  118. $response->setHeader('Content-Type', 'application/xml');
  119. $response->setHeader('ETag', $node->getETag());
  120. $response->setStatus(200);
  121. $response->setBody($writer->outputMemory());
  122. // Return false to break the event chain.
  123. return false;
  124. }
  125. /**
  126. * Returns a bunch of meta-data about the plugin.
  127. *
  128. * Providing this information is optional, and is mainly displayed by the
  129. * Browser plugin.
  130. *
  131. * The description key in the returned array may contain html and will not
  132. * be sanitized.
  133. *
  134. * @return array
  135. */
  136. function getPluginInfo() {
  137. return [
  138. 'name' => $this->getPluginName(),
  139. 'description' => 'Adds support for caldav-notifications, which is required to enable caldav-sharing.',
  140. 'link' => 'http://sabre.io/dav/caldav-sharing/',
  141. ];
  142. }
  143. }