CalendarObject.php 6.0 KB

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