PageRenderTime 24ms CodeModel.GetById 35ms RepoModel.GetById 0ms app.codeStats 0ms

/tine20/Calendar/Frontend/WebDAV/Backend.php

https://github.com/corneliusweiss/Tine-2.0-Open-Source-Groupware-and-CRM
PHP | 313 lines | 128 code | 39 blank | 146 comment | 17 complexity | 8c9028a9c5a9cc08bc927e592a6f8010 MD5 | raw file
  1. <?php
  2. /**
  3. * Tine 2.0
  4. * @package Calendar
  5. * @license http://www.gnu.org/licenses/agpl.html AGPL Version 3
  6. * @author Cornelius Weiss <c.weiss@metaways.de>
  7. * @copyright Copyright (c) 2010 Metaways Infosystems GmbH (http://www.metaways.de)
  8. */
  9. /**
  10. * @package Calendar
  11. */
  12. class Calendar_Frontend_CalDAV_Backend extends Sabre\CalDAV\Backend\AbstractBackend
  13. {
  14. /**
  15. * Returns a list of calendars for a principal.
  16. *
  17. * Every project is an array with the following keys:
  18. * * id, a unique id that will be used by other functions to modify the
  19. * calendar. This can be the same as the uri or a database key.
  20. * * uri, which the basename of the uri with which the calendar is
  21. * accessed.
  22. * * principalUri. The owner of the calendar. Almost always the same as
  23. * principalUri passed to this method.
  24. *
  25. * Furthermore it can contain webdav properties in clark notation. A very
  26. * common one is '{DAV:}displayname'.
  27. *
  28. * @param string $principalUri
  29. * @return array
  30. */
  31. function getCalendarsForUser($principalUri)
  32. {
  33. if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' $principalUri: ' . $principalUri);
  34. $principalParts = explode('/', $principalUri);
  35. if (count($principalParts) == 2) {
  36. $owner = Tinebase_User::getInstance()->getUserByPropertyFromSqlBackend('accountLoginName', $principalParts[1]);
  37. $containers = Tinebase_Container::getInstance()->getPersonalContainer(Tinebase_Core::getUser(), 'Calendar', $owner, Tinebase_Model_Grants::GRANT_READ);
  38. $containers->sort('name');
  39. } else {
  40. throw new Sabre\DAV\Exception\PreconditionFailed('unsupported pricipalUri');
  41. }
  42. $calendars = array();
  43. // $sessionUriMap = (array) Tinebase_Session::getSessionNamespace()->CalDAVUriMap;
  44. foreach($containers as $container) {
  45. $containerId = $container->getId();
  46. // $uri = array_search($containerId, $sessionUriMap);
  47. $calendars[] = array(
  48. 'id' => $containerId,
  49. 'uri' => /*$uri ? $uri : */$containerId,
  50. 'principaluri' => $principalUri,
  51. '{DAV:}displayname' => $container->name,
  52. '{http://apple.com/ns/ical/}calendar-color' => $container->color,
  53. '{' . Sabre\CalDAV\Plugin::NS_CALDAV . '}supported-calendar-component-set' => new Sabre\CalDAV\Property\SupportedCalendarComponentSet(array('VEVENT')),
  54. );
  55. }
  56. return $calendars;
  57. }
  58. /**
  59. * Creates a new calendar for a principal.
  60. *
  61. * If the creation was a success, an id must be returned that can be used to reference
  62. * this calendar in other methods, such as updateCalendar.
  63. *
  64. * This function must return a server-wide unique id that can be used
  65. * later to reference the calendar.
  66. *
  67. * @param string $principalUri
  68. * @param string $calendarUri
  69. * @param array $properties
  70. * @return string|int
  71. */
  72. function createCalendar($principalUri,$calendarUri,array $properties)
  73. {
  74. throw new Sabre\DAV\Exception\MethodNotAllowed('createCalendar');
  75. if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' $principalUri: ' . $principalUri . ' $calendarUri: ' . $calendarUri . ' $properties' . print_r($properties, TRUE));
  76. // NOTE: at the moment we only support a predefined set of colors
  77. // if ((isset($properties['{http://apple.com/ns/ical/}calendar-color']) || array_key_exists('{http://apple.com/ns/ical/}calendar-color', $properties))) {
  78. // $color = substr($properties['{http://apple.com/ns/ical/}calendar-color'], 0, 7);
  79. // $container->color = $color;
  80. // }
  81. $principalParts = explode('/', $principalUri);
  82. if (count($principalParts) == 2) {
  83. $container = new Tinebase_Model_Container(array(
  84. 'name' => $properties['{DAV:}displayname'],
  85. 'type' => Tinebase_Model_Container::TYPE_PERSONAL,
  86. 'owner_id' => Tinebase_User::getInstance()->getUserByPropertyFromSqlBackend('accountLoginName', $principalParts[1]),
  87. 'application_id' => Tinebase_Application::getInstance()->getApplicationByName('Calendar')->getId(),
  88. 'backend' => 'Sql',
  89. 'model' => 'Calendar_Model_Event'
  90. ));
  91. $container = Tinebase_Container::getInstance()->addContainer($container);
  92. } else {
  93. throw new Sabre\DAV\Exception\PreconditionFailed('unsupported pricipalUri');
  94. }
  95. return $container->getId();
  96. }
  97. /**
  98. * Updates properties on this node,
  99. *
  100. * The properties array uses the propertyName in clark-notation as key,
  101. * and the array value for the property value. In the case a property
  102. * should be deleted, the property value will be null.
  103. *
  104. * This method must be atomic. If one property cannot be changed, the
  105. * entire operation must fail.
  106. *
  107. * If the operation was successful, true can be returned.
  108. * If the operation failed, false can be returned.
  109. *
  110. * Deletion of a non-existant property is always succesful.
  111. *
  112. * Lastly, it is optional to return detailed information about any
  113. * failures. In this case an array should be returned with the following
  114. * structure:
  115. *
  116. * array(
  117. * 403 => array(
  118. * '{DAV:}displayname' => null,
  119. * ),
  120. * 424 => array(
  121. * '{DAV:}owner' => null,
  122. * )
  123. * )
  124. *
  125. * In this example it was forbidden to update {DAV:}displayname.
  126. * (403 Forbidden), which in turn also caused {DAV:}owner to fail
  127. * (424 Failed Dependency) because the request needs to be atomic.
  128. *
  129. * @param string $calendarId
  130. * @param array $properties
  131. * @return bool|array
  132. */
  133. public function updateCalendar($calendarId, array $properties)
  134. {
  135. throw new Sabre\DAV\Exception\MethodNotAllowed('updateCalendar');
  136. if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' $calendarId: ' . $calendarId . ' $properties' . print_r($properties, TRUE));
  137. try {
  138. $transactionId = Tinebase_TransactionManager::getInstance()->startTransaction(Tinebase_Core::getDb());
  139. if ((isset($properties['{DAV:}displayname']) || array_key_exists('{DAV:}displayname', $properties))) {
  140. Tinebase_Container::getInstance()->setContainerName($calendarId, $properties['{DAV:}displayname']);
  141. }
  142. // NOTE: at the moment we only support a predefined set of colors
  143. // if ((isset($properties['{http://apple.com/ns/ical/}calendar-color']) || array_key_exists('{http://apple.com/ns/ical/}calendar-color', $properties))) {
  144. // $color = substr($properties['{http://apple.com/ns/ical/}calendar-color'], 0, 7);
  145. // Tinebase_Container::getInstance()->setContainerColor($calendarId, $color);
  146. // }
  147. Tinebase_TransactionManager::getInstance()->commitTransaction($transactionId);
  148. } catch (Exception $e) {
  149. return false;
  150. }
  151. return true;
  152. }
  153. /**
  154. * Delete a calendar and all it's objects
  155. *
  156. * @param string $calendarId
  157. * @return void
  158. */
  159. function deleteCalendar($calendarId)
  160. {
  161. throw new Sabre\DAV\Exception\MethodNotAllowed('deleteCalendar');
  162. if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' $calendarId: ' . $calendarId);
  163. Tinebase_Container::getInstance()->deleteContainer($calendarId);
  164. }
  165. /**
  166. * Returns all calendar objects within a calendar object.
  167. *
  168. * Every item contains an array with the following keys:
  169. * * id - unique identifier which will be used for subsequent updates
  170. * * calendardata - The iCalendar-compatible calnedar data
  171. * * uri - a unique key which will be used to construct the uri. This can be any arbitrary string.
  172. * * lastmodified - a timestamp of the last modification time
  173. *
  174. * @param string $calendarId
  175. * @return array
  176. */
  177. function getCalendarObjects($calendarId)
  178. {
  179. $calendarObjects = array();
  180. if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' $calendarId: ' . $calendarId);
  181. $events = Calendar_Controller_MSEventFacade::getInstance()->search(new Calendar_Model_EventFilter(array(
  182. array('field' => 'container_id', 'operator' => 'equals', 'value' => $calendarId),
  183. )));
  184. foreach($events as $event) {
  185. $calendarObjects[] = $this->_convertCalendarObject($event);
  186. }
  187. return $calendarObjects;
  188. }
  189. /**
  190. * Returns information from a single calendar object, based on it's object uri.
  191. *
  192. * @param string $calendarId
  193. * @param string $objectUri
  194. * @return array
  195. */
  196. function getCalendarObject($calendarId,$objectUri)
  197. {
  198. if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' $calendarId: ' . $calendarId . ' $objectUri: ' . $objectUri);
  199. try {
  200. $event = Calendar_Controller_MSEventFacade::getInstance()->get($objectUri);
  201. return $this->_convertCalendarObject($event);
  202. } catch (Tinebase_Exception_NotFound $e) {
  203. return array();
  204. }
  205. }
  206. /**
  207. * converts events to calendar objects
  208. *
  209. * @param Calendar_Model_Event $event (from MSFacade atm.)
  210. */
  211. protected function _convertCalendarObject($event)
  212. {
  213. $eventId = $event->getId();
  214. $lastModified = $event->last_modified_time ? $event->last_modified_time : $event->creation_time;
  215. // we always use a event set to return exdates at once
  216. $eventSet = new Tinebase_Record_RecordSet('Calendar_Model_Event', array($event));
  217. if ($event->rrule) {
  218. foreach($event->exdate as $exEvent) {
  219. if (! $exEvent->is_deleted) {
  220. $eventSet->addRecord($exEvent);
  221. $event->exdate->removeRecord($exEvent);
  222. }
  223. }
  224. // remaining exdates are fallouts
  225. $event->exdate = $event->exdate->getOriginalDtStart();
  226. }
  227. $exporter = new Calendar_Export_Ical();
  228. $ics = $exporter->eventToIcal($eventSet);
  229. // work arround broken exdate handling in apple ical
  230. // -> not neccesary at the moment this is done generally in ics export
  231. return array(
  232. 'id' => $eventId,
  233. 'uri' => $eventId,
  234. 'lastmodified' => $lastModified->getTimeStamp(),
  235. 'calendardata' => $ics,
  236. );
  237. }
  238. /**
  239. * Creates a new calendar object.
  240. *
  241. * @param string $calendarId
  242. * @param string $objectUri
  243. * @param string $calendarData
  244. * @return void
  245. */
  246. function createCalendarObject($calendarId,$objectUri,$calendarData)
  247. {
  248. if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' $calendarId: ' . $calendarId . ' $objectUri: ' . $objectUri. ' $calendarData: '. print_r($calendarData, TRUE));
  249. throw new Sabre\DAV\Exception\MethodNotAllowed('createCalendarObject');
  250. }
  251. /**
  252. * Updates an existing calendarobject, based on it's uri.
  253. *
  254. * @param string $calendarId
  255. * @param string $objectUri
  256. * @param string $calendarData
  257. * @return void
  258. */
  259. function updateCalendarObject($calendarId,$objectUri,$calendarData)
  260. {
  261. throw new Sabre\DAV\Exception\MethodNotAllowed('updateCalendarObject');
  262. }
  263. /**
  264. * Deletes an existing calendar object.
  265. *
  266. * @param string $calendarId
  267. * @param string $objectUri
  268. * @return void
  269. */
  270. function deleteCalendarObject($calendarId,$objectUri)
  271. {
  272. throw new Sabre\DAV\Exception\MethodNotAllowed('deleteCalendarObject');
  273. }
  274. }