Calendar.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. <?php
  2. /**
  3. * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
  4. * SPDX-License-Identifier: AGPL-3.0-or-later
  5. */
  6. namespace OCA\DAV\CalDAV\Activity\Provider;
  7. use OCP\Activity\IEvent;
  8. use OCP\Activity\IEventMerger;
  9. use OCP\Activity\IManager;
  10. use OCP\IGroupManager;
  11. use OCP\IL10N;
  12. use OCP\IURLGenerator;
  13. use OCP\IUserManager;
  14. use OCP\L10N\IFactory;
  15. class Calendar extends Base {
  16. public const SUBJECT_ADD = 'calendar_add';
  17. public const SUBJECT_UPDATE = 'calendar_update';
  18. public const SUBJECT_MOVE_TO_TRASH = 'calendar_move_to_trash';
  19. public const SUBJECT_RESTORE = 'calendar_restore';
  20. public const SUBJECT_DELETE = 'calendar_delete';
  21. public const SUBJECT_PUBLISH = 'calendar_publish';
  22. public const SUBJECT_UNPUBLISH = 'calendar_unpublish';
  23. public const SUBJECT_SHARE_USER = 'calendar_user_share';
  24. public const SUBJECT_SHARE_GROUP = 'calendar_group_share';
  25. public const SUBJECT_UNSHARE_USER = 'calendar_user_unshare';
  26. public const SUBJECT_UNSHARE_GROUP = 'calendar_group_unshare';
  27. /** @var IFactory */
  28. protected $languageFactory;
  29. /** @var IL10N */
  30. protected $l;
  31. /** @var IManager */
  32. protected $activityManager;
  33. /** @var IEventMerger */
  34. protected $eventMerger;
  35. /**
  36. * @param IFactory $languageFactory
  37. * @param IURLGenerator $url
  38. * @param IManager $activityManager
  39. * @param IUserManager $userManager
  40. * @param IGroupManager $groupManager
  41. * @param IEventMerger $eventMerger
  42. */
  43. public function __construct(IFactory $languageFactory, IURLGenerator $url, IManager $activityManager, IUserManager $userManager, IGroupManager $groupManager, IEventMerger $eventMerger) {
  44. parent::__construct($userManager, $groupManager, $url);
  45. $this->languageFactory = $languageFactory;
  46. $this->activityManager = $activityManager;
  47. $this->eventMerger = $eventMerger;
  48. }
  49. /**
  50. * @param string $language
  51. * @param IEvent $event
  52. * @param IEvent|null $previousEvent
  53. * @return IEvent
  54. * @throws \InvalidArgumentException
  55. * @since 11.0.0
  56. */
  57. public function parse($language, IEvent $event, ?IEvent $previousEvent = null) {
  58. if ($event->getApp() !== 'dav' || $event->getType() !== 'calendar') {
  59. throw new \InvalidArgumentException();
  60. }
  61. $this->l = $this->languageFactory->get('dav', $language);
  62. if ($this->activityManager->getRequirePNG()) {
  63. $event->setIcon($this->url->getAbsoluteURL($this->url->imagePath('core', 'places/calendar-dark.png')));
  64. } else {
  65. $event->setIcon($this->url->getAbsoluteURL($this->url->imagePath('core', 'places/calendar.svg')));
  66. }
  67. if ($event->getSubject() === self::SUBJECT_ADD) {
  68. $subject = $this->l->t('{actor} created calendar {calendar}');
  69. } elseif ($event->getSubject() === self::SUBJECT_ADD . '_self') {
  70. $subject = $this->l->t('You created calendar {calendar}');
  71. } elseif ($event->getSubject() === self::SUBJECT_DELETE) {
  72. $subject = $this->l->t('{actor} deleted calendar {calendar}');
  73. } elseif ($event->getSubject() === self::SUBJECT_DELETE . '_self') {
  74. $subject = $this->l->t('You deleted calendar {calendar}');
  75. } elseif ($event->getSubject() === self::SUBJECT_UPDATE) {
  76. $subject = $this->l->t('{actor} updated calendar {calendar}');
  77. } elseif ($event->getSubject() === self::SUBJECT_UPDATE . '_self') {
  78. $subject = $this->l->t('You updated calendar {calendar}');
  79. } elseif ($event->getSubject() === self::SUBJECT_MOVE_TO_TRASH) {
  80. $subject = $this->l->t('{actor} deleted calendar {calendar}');
  81. } elseif ($event->getSubject() === self::SUBJECT_MOVE_TO_TRASH . '_self') {
  82. $subject = $this->l->t('You deleted calendar {calendar}');
  83. } elseif ($event->getSubject() === self::SUBJECT_RESTORE) {
  84. $subject = $this->l->t('{actor} restored calendar {calendar}');
  85. } elseif ($event->getSubject() === self::SUBJECT_RESTORE . '_self') {
  86. $subject = $this->l->t('You restored calendar {calendar}');
  87. } elseif ($event->getSubject() === self::SUBJECT_PUBLISH . '_self') {
  88. $subject = $this->l->t('You shared calendar {calendar} as public link');
  89. } elseif ($event->getSubject() === self::SUBJECT_UNPUBLISH . '_self') {
  90. $subject = $this->l->t('You removed public link for calendar {calendar}');
  91. } elseif ($event->getSubject() === self::SUBJECT_SHARE_USER) {
  92. $subject = $this->l->t('{actor} shared calendar {calendar} with you');
  93. } elseif ($event->getSubject() === self::SUBJECT_SHARE_USER . '_you') {
  94. $subject = $this->l->t('You shared calendar {calendar} with {user}');
  95. } elseif ($event->getSubject() === self::SUBJECT_SHARE_USER . '_by') {
  96. $subject = $this->l->t('{actor} shared calendar {calendar} with {user}');
  97. } elseif ($event->getSubject() === self::SUBJECT_UNSHARE_USER) {
  98. $subject = $this->l->t('{actor} unshared calendar {calendar} from you');
  99. } elseif ($event->getSubject() === self::SUBJECT_UNSHARE_USER . '_you') {
  100. $subject = $this->l->t('You unshared calendar {calendar} from {user}');
  101. } elseif ($event->getSubject() === self::SUBJECT_UNSHARE_USER . '_by') {
  102. $subject = $this->l->t('{actor} unshared calendar {calendar} from {user}');
  103. } elseif ($event->getSubject() === self::SUBJECT_UNSHARE_USER . '_self') {
  104. $subject = $this->l->t('{actor} unshared calendar {calendar} from themselves');
  105. } elseif ($event->getSubject() === self::SUBJECT_SHARE_GROUP . '_you') {
  106. $subject = $this->l->t('You shared calendar {calendar} with group {group}');
  107. } elseif ($event->getSubject() === self::SUBJECT_SHARE_GROUP . '_by') {
  108. $subject = $this->l->t('{actor} shared calendar {calendar} with group {group}');
  109. } elseif ($event->getSubject() === self::SUBJECT_UNSHARE_GROUP . '_you') {
  110. $subject = $this->l->t('You unshared calendar {calendar} from group {group}');
  111. } elseif ($event->getSubject() === self::SUBJECT_UNSHARE_GROUP . '_by') {
  112. $subject = $this->l->t('{actor} unshared calendar {calendar} from group {group}');
  113. } else {
  114. throw new \InvalidArgumentException();
  115. }
  116. $parsedParameters = $this->getParameters($event);
  117. $this->setSubjects($event, $subject, $parsedParameters);
  118. $event = $this->eventMerger->mergeEvents('calendar', $event, $previousEvent);
  119. if ($event->getChildEvent() === null) {
  120. if (isset($parsedParameters['user'])) {
  121. // Couldn't group by calendar, maybe we can group by users
  122. $event = $this->eventMerger->mergeEvents('user', $event, $previousEvent);
  123. } elseif (isset($parsedParameters['group'])) {
  124. // Couldn't group by calendar, maybe we can group by groups
  125. $event = $this->eventMerger->mergeEvents('group', $event, $previousEvent);
  126. }
  127. }
  128. return $event;
  129. }
  130. /**
  131. * @param IEvent $event
  132. * @return array
  133. */
  134. protected function getParameters(IEvent $event) {
  135. $subject = $event->getSubject();
  136. $parameters = $event->getSubjectParameters();
  137. // Nextcloud 13+
  138. if (isset($parameters['calendar'])) {
  139. switch ($subject) {
  140. case self::SUBJECT_ADD:
  141. case self::SUBJECT_ADD . '_self':
  142. case self::SUBJECT_DELETE:
  143. case self::SUBJECT_DELETE . '_self':
  144. case self::SUBJECT_UPDATE:
  145. case self::SUBJECT_UPDATE . '_self':
  146. case self::SUBJECT_MOVE_TO_TRASH:
  147. case self::SUBJECT_MOVE_TO_TRASH . '_self':
  148. case self::SUBJECT_RESTORE:
  149. case self::SUBJECT_RESTORE . '_self':
  150. case self::SUBJECT_PUBLISH . '_self':
  151. case self::SUBJECT_UNPUBLISH . '_self':
  152. case self::SUBJECT_SHARE_USER:
  153. case self::SUBJECT_UNSHARE_USER:
  154. case self::SUBJECT_UNSHARE_USER . '_self':
  155. return [
  156. 'actor' => $this->generateUserParameter($parameters['actor']),
  157. 'calendar' => $this->generateCalendarParameter($parameters['calendar'], $this->l),
  158. ];
  159. case self::SUBJECT_SHARE_USER . '_you':
  160. case self::SUBJECT_UNSHARE_USER . '_you':
  161. return [
  162. 'calendar' => $this->generateCalendarParameter($parameters['calendar'], $this->l),
  163. 'user' => $this->generateUserParameter($parameters['user']),
  164. ];
  165. case self::SUBJECT_SHARE_USER . '_by':
  166. case self::SUBJECT_UNSHARE_USER . '_by':
  167. return [
  168. 'actor' => $this->generateUserParameter($parameters['actor']),
  169. 'calendar' => $this->generateCalendarParameter($parameters['calendar'], $this->l),
  170. 'user' => $this->generateUserParameter($parameters['user']),
  171. ];
  172. case self::SUBJECT_SHARE_GROUP . '_you':
  173. case self::SUBJECT_UNSHARE_GROUP . '_you':
  174. return [
  175. 'calendar' => $this->generateCalendarParameter($parameters['calendar'], $this->l),
  176. 'group' => $this->generateGroupParameter($parameters['group']),
  177. ];
  178. case self::SUBJECT_SHARE_GROUP . '_by':
  179. case self::SUBJECT_UNSHARE_GROUP . '_by':
  180. return [
  181. 'actor' => $this->generateUserParameter($parameters['actor']),
  182. 'calendar' => $this->generateCalendarParameter($parameters['calendar'], $this->l),
  183. 'group' => $this->generateGroupParameter($parameters['group']),
  184. ];
  185. }
  186. }
  187. // Legacy - Do NOT Remove unless necessary
  188. // Removing this will break parsing of activities that were created on
  189. // Nextcloud 12, so we should keep this as long as it's acceptable.
  190. // Otherwise if people upgrade over multiple releases in a short period,
  191. // they will get the dead entries in their stream.
  192. switch ($subject) {
  193. case self::SUBJECT_ADD:
  194. case self::SUBJECT_ADD . '_self':
  195. case self::SUBJECT_DELETE:
  196. case self::SUBJECT_DELETE . '_self':
  197. case self::SUBJECT_UPDATE:
  198. case self::SUBJECT_UPDATE . '_self':
  199. case self::SUBJECT_PUBLISH . '_self':
  200. case self::SUBJECT_UNPUBLISH . '_self':
  201. case self::SUBJECT_SHARE_USER:
  202. case self::SUBJECT_UNSHARE_USER:
  203. case self::SUBJECT_UNSHARE_USER . '_self':
  204. return [
  205. 'actor' => $this->generateUserParameter($parameters[0]),
  206. 'calendar' => $this->generateLegacyCalendarParameter($event->getObjectId(), $parameters[1]),
  207. ];
  208. case self::SUBJECT_SHARE_USER . '_you':
  209. case self::SUBJECT_UNSHARE_USER . '_you':
  210. return [
  211. 'user' => $this->generateUserParameter($parameters[0]),
  212. 'calendar' => $this->generateLegacyCalendarParameter($event->getObjectId(), $parameters[1]),
  213. ];
  214. case self::SUBJECT_SHARE_USER . '_by':
  215. case self::SUBJECT_UNSHARE_USER . '_by':
  216. return [
  217. 'user' => $this->generateUserParameter($parameters[0]),
  218. 'calendar' => $this->generateLegacyCalendarParameter($event->getObjectId(), $parameters[1]),
  219. 'actor' => $this->generateUserParameter($parameters[2]),
  220. ];
  221. case self::SUBJECT_SHARE_GROUP . '_you':
  222. case self::SUBJECT_UNSHARE_GROUP . '_you':
  223. return [
  224. 'group' => $this->generateGroupParameter($parameters[0]),
  225. 'calendar' => $this->generateLegacyCalendarParameter($event->getObjectId(), $parameters[1]),
  226. ];
  227. case self::SUBJECT_SHARE_GROUP . '_by':
  228. case self::SUBJECT_UNSHARE_GROUP . '_by':
  229. return [
  230. 'group' => $this->generateGroupParameter($parameters[0]),
  231. 'calendar' => $this->generateLegacyCalendarParameter($event->getObjectId(), $parameters[1]),
  232. 'actor' => $this->generateUserParameter($parameters[2]),
  233. ];
  234. }
  235. throw new \InvalidArgumentException();
  236. }
  237. }