You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

SearchPlugin.php 4.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. <?php
  2. /**
  3. * @copyright Copyright (c) 2017 Georg Ehrke <oc.list@georgehrke.com>
  4. *
  5. * @author Georg Ehrke <oc.list@georgehrke.com>
  6. * @author Joas Schilling <coding@schilljs.com>
  7. * @author Morris Jobke <hey@morrisjobke.de>
  8. * @author Roeland Jago Douma <roeland@famdouma.nl>
  9. *
  10. * @license GNU AGPL version 3 or any later version
  11. *
  12. * This program is free software: you can redistribute it and/or modify
  13. * it under the terms of the GNU Affero General Public License as
  14. * published by the Free Software Foundation, either version 3 of the
  15. * License, or (at your option) any later version.
  16. *
  17. * This program is distributed in the hope that it will be useful,
  18. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20. * GNU Affero General Public License for more details.
  21. *
  22. * You should have received a copy of the GNU Affero General Public License
  23. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  24. *
  25. */
  26. namespace OCA\DAV\CalDAV\Search;
  27. use OCA\DAV\CalDAV\CalendarHome;
  28. use OCA\DAV\CalDAV\Search\Xml\Request\CalendarSearchReport;
  29. use Sabre\DAV\Server;
  30. use Sabre\DAV\ServerPlugin;
  31. class SearchPlugin extends ServerPlugin {
  32. const NS_Nextcloud = 'http://nextcloud.com/ns';
  33. /**
  34. * Reference to SabreDAV server object.
  35. *
  36. * @var \Sabre\DAV\Server
  37. */
  38. protected $server;
  39. /**
  40. * This method should return a list of server-features.
  41. *
  42. * This is for example 'versioning' and is added to the DAV: header
  43. * in an OPTIONS response.
  44. *
  45. * @return string[]
  46. */
  47. public function getFeatures() {
  48. // May have to be changed to be detected
  49. return ['nc-calendar-search'];
  50. }
  51. /**
  52. * Returns a plugin name.
  53. *
  54. * Using this name other plugins will be able to access other plugins
  55. * using Sabre\DAV\Server::getPlugin
  56. *
  57. * @return string
  58. */
  59. public function getPluginName() {
  60. return 'nc-calendar-search';
  61. }
  62. /**
  63. * This initializes the plugin.
  64. *
  65. * This function is called by Sabre\DAV\Server, after
  66. * addPlugin is called.
  67. *
  68. * This method should set up the required event subscriptions.
  69. *
  70. * @param Server $server
  71. */
  72. public function initialize(Server $server) {
  73. $this->server = $server;
  74. $server->on('report', [$this, 'report']);
  75. $server->xml->elementMap['{' . self::NS_Nextcloud . '}calendar-search'] =
  76. CalendarSearchReport::class;
  77. }
  78. /**
  79. * This functions handles REPORT requests specific to CalDAV
  80. *
  81. * @param string $reportName
  82. * @param mixed $report
  83. * @param mixed $path
  84. * @return bool
  85. */
  86. public function report($reportName, $report, $path) {
  87. switch ($reportName) {
  88. case '{' . self::NS_Nextcloud . '}calendar-search':
  89. $this->server->transactionType = 'report-nc-calendar-search';
  90. $this->calendarSearch($report);
  91. return false;
  92. }
  93. }
  94. /**
  95. * Returns a list of reports this plugin supports.
  96. *
  97. * This will be used in the {DAV:}supported-report-set property.
  98. * Note that you still need to subscribe to the 'report' event to actually
  99. * implement them
  100. *
  101. * @param string $uri
  102. * @return array
  103. */
  104. public function getSupportedReportSet($uri) {
  105. $node = $this->server->tree->getNodeForPath($uri);
  106. $reports = [];
  107. if ($node instanceof CalendarHome) {
  108. $reports[] = '{' . self::NS_Nextcloud . '}calendar-search';
  109. }
  110. return $reports;
  111. }
  112. /**
  113. * This function handles the calendar-query REPORT
  114. *
  115. * This report is used by clients to request calendar objects based on
  116. * complex conditions.
  117. *
  118. * @param Xml\Request\CalendarSearchReport $report
  119. * @return void
  120. */
  121. private function calendarSearch($report) {
  122. $node = $this->server->tree->getNodeForPath($this->server->getRequestUri());
  123. $depth = $this->server->getHTTPDepth(2);
  124. // The default result is an empty array
  125. $result = [];
  126. // If we're dealing with the calendar home, the calendar home itself is
  127. // responsible for the calendar-query
  128. if ($node instanceof CalendarHome && $depth === 2) {
  129. $nodePaths = $node->calendarSearch($report->filters, $report->limit, $report->offset);
  130. foreach ($nodePaths as $path) {
  131. list($properties) = $this->server->getPropertiesForPath(
  132. $this->server->getRequestUri() . '/' . $path,
  133. $report->properties);
  134. $result[] = $properties;
  135. }
  136. }
  137. $prefer = $this->server->getHTTPPrefer();
  138. $this->server->httpResponse->setStatus(207);
  139. $this->server->httpResponse->setHeader('Content-Type',
  140. 'application/xml; charset=utf-8');
  141. $this->server->httpResponse->setHeader('Vary', 'Brief,Prefer');
  142. $this->server->httpResponse->setBody(
  143. $this->server->generateMultiStatus($result,
  144. $prefer['return'] === 'minimal'));
  145. }
  146. }