Plugin.php 4.7 KB

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