PageRenderTime 27ms CodeModel.GetById 34ms RepoModel.GetById 1ms app.codeStats 0ms

/tine20/Tasks/Frontend/WebDAV/Backend.php

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