CalendarObject.php 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. <?php
  2. namespace Sabre\CalDAV;
  3. /**
  4. * The CalendarObject represents a single VEVENT or VTODO within a Calendar.
  5. *
  6. * @copyright Copyright (C) fruux GmbH (https://fruux.com/)
  7. * @author Evert Pot (http://evertpot.com/)
  8. * @license http://sabre.io/license/ Modified BSD License
  9. */
  10. class CalendarObject extends \Sabre\DAV\File implements ICalendarObject, \Sabre\DAVACL\IACL {
  11. /**
  12. * Sabre\CalDAV\Backend\BackendInterface
  13. *
  14. * @var Sabre\CalDAV\Backend\AbstractBackend
  15. */
  16. protected $caldavBackend;
  17. /**
  18. * Array with information about this CalendarObject
  19. *
  20. * @var array
  21. */
  22. protected $objectData;
  23. /**
  24. * Array with information about the containing calendar
  25. *
  26. * @var array
  27. */
  28. protected $calendarInfo;
  29. /**
  30. * Constructor
  31. *
  32. * The following properties may be passed within $objectData:
  33. *
  34. * * calendarid - This must refer to a calendarid from a caldavBackend
  35. * * uri - A unique uri. Only the 'basename' must be passed.
  36. * * calendardata (optional) - The iCalendar data
  37. * * etag - (optional) The etag for this object, MUST be encloded with
  38. * double-quotes.
  39. * * size - (optional) The size of the data in bytes.
  40. * * lastmodified - (optional) format as a unix timestamp.
  41. * * acl - (optional) Use this to override the default ACL for the node.
  42. *
  43. * @param Backend\BackendInterface $caldavBackend
  44. * @param array $calendarInfo
  45. * @param array $objectData
  46. */
  47. function __construct(Backend\BackendInterface $caldavBackend, array $calendarInfo, array $objectData) {
  48. $this->caldavBackend = $caldavBackend;
  49. if (!isset($objectData['uri'])) {
  50. throw new \InvalidArgumentException('The objectData argument must contain an \'uri\' property');
  51. }
  52. $this->calendarInfo = $calendarInfo;
  53. $this->objectData = $objectData;
  54. }
  55. /**
  56. * Returns the uri for this object
  57. *
  58. * @return string
  59. */
  60. function getName() {
  61. return $this->objectData['uri'];
  62. }
  63. /**
  64. * Returns the ICalendar-formatted object
  65. *
  66. * @return string
  67. */
  68. function get() {
  69. // Pre-populating the 'calendardata' is optional, if we don't have it
  70. // already we fetch it from the backend.
  71. if (!isset($this->objectData['calendardata'])) {
  72. $this->objectData = $this->caldavBackend->getCalendarObject($this->calendarInfo['id'], $this->objectData['uri']);
  73. }
  74. return $this->objectData['calendardata'];
  75. }
  76. /**
  77. * Updates the ICalendar-formatted object
  78. *
  79. * @param string|resource $calendarData
  80. * @return string
  81. */
  82. function put($calendarData) {
  83. if (is_resource($calendarData)) {
  84. $calendarData = stream_get_contents($calendarData);
  85. }
  86. $etag = $this->caldavBackend->updateCalendarObject($this->calendarInfo['id'], $this->objectData['uri'], $calendarData);
  87. $this->objectData['calendardata'] = $calendarData;
  88. $this->objectData['etag'] = $etag;
  89. return $etag;
  90. }
  91. /**
  92. * Deletes the calendar object
  93. *
  94. * @return void
  95. */
  96. function delete() {
  97. $this->caldavBackend->deleteCalendarObject($this->calendarInfo['id'], $this->objectData['uri']);
  98. }
  99. /**
  100. * Returns the mime content-type
  101. *
  102. * @return string
  103. */
  104. function getContentType() {
  105. $mime = 'text/calendar; charset=utf-8';
  106. if (isset($this->objectData['component']) && $this->objectData['component']) {
  107. $mime .= '; component=' . $this->objectData['component'];
  108. }
  109. return $mime;
  110. }
  111. /**
  112. * Returns an ETag for this object.
  113. *
  114. * The ETag is an arbitrary string, but MUST be surrounded by double-quotes.
  115. *
  116. * @return string
  117. */
  118. function getETag() {
  119. if (isset($this->objectData['etag'])) {
  120. return $this->objectData['etag'];
  121. } else {
  122. return '"' . md5($this->get()) . '"';
  123. }
  124. }
  125. /**
  126. * Returns the last modification date as a unix timestamp
  127. *
  128. * @return int
  129. */
  130. function getLastModified() {
  131. return $this->objectData['lastmodified'];
  132. }
  133. /**
  134. * Returns the size of this object in bytes
  135. *
  136. * @return int
  137. */
  138. function getSize() {
  139. if (array_key_exists('size', $this->objectData)) {
  140. return $this->objectData['size'];
  141. } else {
  142. return strlen($this->get());
  143. }
  144. }
  145. /**
  146. * Returns the owner principal
  147. *
  148. * This must be a url to a principal, or null if there's no owner
  149. *
  150. * @return string|null
  151. */
  152. function getOwner() {
  153. return $this->calendarInfo['principaluri'];
  154. }
  155. /**
  156. * Returns a group principal
  157. *
  158. * This must be a url to a principal, or null if there's no owner
  159. *
  160. * @return string|null
  161. */
  162. function getGroup() {
  163. return null;
  164. }
  165. /**
  166. * Returns a list of ACE's for this node.
  167. *
  168. * Each ACE has the following properties:
  169. * * 'privilege', a string such as {DAV:}read or {DAV:}write. These are
  170. * currently the only supported privileges
  171. * * 'principal', a url to the principal who owns the node
  172. * * 'protected' (optional), indicating that this ACE is not allowed to
  173. * be updated.
  174. *
  175. * @return array
  176. */
  177. function getACL() {
  178. // An alternative acl may be specified in the object data.
  179. if (isset($this->objectData['acl'])) {
  180. return $this->objectData['acl'];
  181. }
  182. // The default ACL
  183. return [
  184. [
  185. 'privilege' => '{DAV:}read',
  186. 'principal' => $this->calendarInfo['principaluri'],
  187. 'protected' => true,
  188. ],
  189. [
  190. 'privilege' => '{DAV:}write',
  191. 'principal' => $this->calendarInfo['principaluri'],
  192. 'protected' => true,
  193. ],
  194. [
  195. 'privilege' => '{DAV:}read',
  196. 'principal' => $this->calendarInfo['principaluri'] . '/calendar-proxy-write',
  197. 'protected' => true,
  198. ],
  199. [
  200. 'privilege' => '{DAV:}write',
  201. 'principal' => $this->calendarInfo['principaluri'] . '/calendar-proxy-write',
  202. 'protected' => true,
  203. ],
  204. [
  205. 'privilege' => '{DAV:}read',
  206. 'principal' => $this->calendarInfo['principaluri'] . '/calendar-proxy-read',
  207. 'protected' => true,
  208. ],
  209. ];
  210. }
  211. /**
  212. * Updates the ACL
  213. *
  214. * This method will receive a list of new ACE's.
  215. *
  216. * @param array $acl
  217. * @return void
  218. */
  219. function setACL(array $acl) {
  220. throw new \Sabre\DAV\Exception\MethodNotAllowed('Changing ACL is not yet supported');
  221. }
  222. /**
  223. * Returns the list of supported privileges for this node.
  224. *
  225. * The returned data structure is a list of nested privileges.
  226. * See \Sabre\DAVACL\Plugin::getDefaultSupportedPrivilegeSet for a simple
  227. * standard structure.
  228. *
  229. * If null is returned from this method, the default privilege set is used,
  230. * which is fine for most common usecases.
  231. *
  232. * @return array|null
  233. */
  234. function getSupportedPrivilegeSet() {
  235. return null;
  236. }
  237. }