Event.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * @copyright Copyright (c) 2016, ownCloud, Inc.
  5. * @copyright Copyright (c) 2016 Joas Schilling <coding@schilljs.com>
  6. *
  7. * @author Christoph Wurst <christoph@winzerhof-wurst.at>
  8. * @author Joas Schilling <coding@schilljs.com>
  9. * @author Phil Davis <phil.davis@inf.org>
  10. * @author Robin Appelman <robin@icewind.nl>
  11. *
  12. * @license AGPL-3.0
  13. *
  14. * This code is free software: you can redistribute it and/or modify
  15. * it under the terms of the GNU Affero General Public License, version 3,
  16. * as published by the Free Software Foundation.
  17. *
  18. * This program is distributed in the hope that it will be useful,
  19. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21. * GNU Affero General Public License for more details.
  22. *
  23. * You should have received a copy of the GNU Affero General Public License, version 3,
  24. * along with this program. If not, see <http://www.gnu.org/licenses/>
  25. *
  26. */
  27. namespace OC\Activity;
  28. use OCP\Activity\IEvent;
  29. use OCP\RichObjectStrings\InvalidObjectExeption;
  30. use OCP\RichObjectStrings\IValidator;
  31. class Event implements IEvent {
  32. /** @var string */
  33. protected $app = '';
  34. /** @var string */
  35. protected $type = '';
  36. /** @var string */
  37. protected $affectedUser = '';
  38. /** @var string */
  39. protected $author = '';
  40. /** @var int */
  41. protected $timestamp = 0;
  42. /** @var string */
  43. protected $subject = '';
  44. /** @var array */
  45. protected $subjectParameters = [];
  46. /** @var string */
  47. protected $subjectParsed = '';
  48. /** @var string */
  49. protected $subjectRich = '';
  50. /** @var array */
  51. protected $subjectRichParameters = [];
  52. /** @var string */
  53. protected $message = '';
  54. /** @var array */
  55. protected $messageParameters = [];
  56. /** @var string */
  57. protected $messageParsed = '';
  58. /** @var string */
  59. protected $messageRich = '';
  60. /** @var array */
  61. protected $messageRichParameters = [];
  62. /** @var string */
  63. protected $objectType = '';
  64. /** @var int */
  65. protected $objectId = 0;
  66. /** @var string */
  67. protected $objectName = '';
  68. /** @var string */
  69. protected $link = '';
  70. /** @var string */
  71. protected $icon = '';
  72. /** @var bool */
  73. protected $generateNotification = true;
  74. /** @var IEvent|null */
  75. protected $child;
  76. /** @var IValidator */
  77. protected $richValidator;
  78. /**
  79. * @param IValidator $richValidator
  80. */
  81. public function __construct(IValidator $richValidator) {
  82. $this->richValidator = $richValidator;
  83. }
  84. /**
  85. * Set the app of the activity
  86. *
  87. * @param string $app
  88. * @return IEvent
  89. * @throws \InvalidArgumentException if the app id is invalid
  90. * @since 8.2.0
  91. */
  92. public function setApp(string $app): IEvent {
  93. if ($app === '' || isset($app[32])) {
  94. throw new \InvalidArgumentException('The given app is invalid');
  95. }
  96. $this->app = $app;
  97. return $this;
  98. }
  99. /**
  100. * @return string
  101. */
  102. public function getApp(): string {
  103. return $this->app;
  104. }
  105. /**
  106. * Set the type of the activity
  107. *
  108. * @param string $type
  109. * @return IEvent
  110. * @throws \InvalidArgumentException if the type is invalid
  111. * @since 8.2.0
  112. */
  113. public function setType(string $type): IEvent {
  114. if ($type === '' || isset($type[255])) {
  115. throw new \InvalidArgumentException('The given type is invalid');
  116. }
  117. $this->type = $type;
  118. return $this;
  119. }
  120. /**
  121. * @return string
  122. */
  123. public function getType(): string {
  124. return $this->type;
  125. }
  126. /**
  127. * Set the affected user of the activity
  128. *
  129. * @param string $affectedUser
  130. * @return IEvent
  131. * @throws \InvalidArgumentException if the affected user is invalid
  132. * @since 8.2.0
  133. */
  134. public function setAffectedUser(string $affectedUser): IEvent {
  135. if ($affectedUser === '' || isset($affectedUser[64])) {
  136. throw new \InvalidArgumentException('The given affected user is invalid');
  137. }
  138. $this->affectedUser = $affectedUser;
  139. return $this;
  140. }
  141. /**
  142. * @return string
  143. */
  144. public function getAffectedUser(): string {
  145. return $this->affectedUser;
  146. }
  147. /**
  148. * Set the author of the activity
  149. *
  150. * @param string $author
  151. * @return IEvent
  152. * @throws \InvalidArgumentException if the author is invalid
  153. * @since 8.2.0
  154. */
  155. public function setAuthor(string $author): IEvent {
  156. if (isset($author[64])) {
  157. throw new \InvalidArgumentException('The given author user is invalid');
  158. }
  159. $this->author = $author;
  160. return $this;
  161. }
  162. /**
  163. * @return string
  164. */
  165. public function getAuthor(): string {
  166. return $this->author;
  167. }
  168. /**
  169. * Set the timestamp of the activity
  170. *
  171. * @param int $timestamp
  172. * @return IEvent
  173. * @throws \InvalidArgumentException if the timestamp is invalid
  174. * @since 8.2.0
  175. */
  176. public function setTimestamp(int $timestamp): IEvent {
  177. $this->timestamp = $timestamp;
  178. return $this;
  179. }
  180. /**
  181. * @return int
  182. */
  183. public function getTimestamp(): int {
  184. return $this->timestamp;
  185. }
  186. /**
  187. * Set the subject of the activity
  188. *
  189. * @param string $subject
  190. * @param array $parameters
  191. * @return IEvent
  192. * @throws \InvalidArgumentException if the subject or parameters are invalid
  193. * @since 8.2.0
  194. */
  195. public function setSubject(string $subject, array $parameters = []): IEvent {
  196. if (isset($subject[255])) {
  197. throw new \InvalidArgumentException('The given subject is invalid');
  198. }
  199. $this->subject = $subject;
  200. $this->subjectParameters = $parameters;
  201. return $this;
  202. }
  203. /**
  204. * @return string
  205. */
  206. public function getSubject(): string {
  207. return $this->subject;
  208. }
  209. /**
  210. * @return array
  211. */
  212. public function getSubjectParameters(): array {
  213. return $this->subjectParameters;
  214. }
  215. /**
  216. * @param string $subject
  217. * @return $this
  218. * @throws \InvalidArgumentException if the subject is invalid
  219. * @since 11.0.0
  220. */
  221. public function setParsedSubject(string $subject): IEvent {
  222. if ($subject === '') {
  223. throw new \InvalidArgumentException('The given parsed subject is invalid');
  224. }
  225. $this->subjectParsed = $subject;
  226. return $this;
  227. }
  228. /**
  229. * @return string
  230. * @since 11.0.0
  231. */
  232. public function getParsedSubject(): string {
  233. return $this->subjectParsed;
  234. }
  235. /**
  236. * @param string $subject
  237. * @param array $parameters
  238. * @return $this
  239. * @throws \InvalidArgumentException if the subject or parameters are invalid
  240. * @since 11.0.0
  241. */
  242. public function setRichSubject(string $subject, array $parameters = []): IEvent {
  243. if ($subject === '') {
  244. throw new \InvalidArgumentException('The given parsed subject is invalid');
  245. }
  246. $this->subjectRich = $subject;
  247. $this->subjectRichParameters = $parameters;
  248. if ($this->subjectParsed === '') {
  249. $this->subjectParsed = $this->richToParsed($subject, $parameters);
  250. }
  251. return $this;
  252. }
  253. /**
  254. * @throws \InvalidArgumentException if a parameter has no name or no type
  255. */
  256. private function richToParsed(string $message, array $parameters): string {
  257. $placeholders = [];
  258. $replacements = [];
  259. foreach ($parameters as $placeholder => $parameter) {
  260. $placeholders[] = '{' . $placeholder . '}';
  261. foreach (['name','type'] as $requiredField) {
  262. if (!isset($parameter[$requiredField]) || !is_string($parameter[$requiredField])) {
  263. throw new \InvalidArgumentException("Invalid rich object, {$requiredField} field is missing");
  264. }
  265. }
  266. if ($parameter['type'] === 'user') {
  267. $replacements[] = '@' . $parameter['name'];
  268. } elseif ($parameter['type'] === 'file') {
  269. $replacements[] = $parameter['path'] ?? $parameter['name'];
  270. } else {
  271. $replacements[] = $parameter['name'];
  272. }
  273. }
  274. return str_replace($placeholders, $replacements, $message);
  275. }
  276. /**
  277. * @return string
  278. * @since 11.0.0
  279. */
  280. public function getRichSubject(): string {
  281. return $this->subjectRich;
  282. }
  283. /**
  284. * @return array[]
  285. * @since 11.0.0
  286. */
  287. public function getRichSubjectParameters(): array {
  288. return $this->subjectRichParameters;
  289. }
  290. /**
  291. * Set the message of the activity
  292. *
  293. * @param string $message
  294. * @param array $parameters
  295. * @return IEvent
  296. * @throws \InvalidArgumentException if the message or parameters are invalid
  297. * @since 8.2.0
  298. */
  299. public function setMessage(string $message, array $parameters = []): IEvent {
  300. if (isset($message[255])) {
  301. throw new \InvalidArgumentException('The given message is invalid');
  302. }
  303. $this->message = $message;
  304. $this->messageParameters = $parameters;
  305. return $this;
  306. }
  307. /**
  308. * @return string
  309. */
  310. public function getMessage(): string {
  311. return $this->message;
  312. }
  313. /**
  314. * @return array
  315. */
  316. public function getMessageParameters(): array {
  317. return $this->messageParameters;
  318. }
  319. /**
  320. * @param string $message
  321. * @return $this
  322. * @throws \InvalidArgumentException if the message is invalid
  323. * @since 11.0.0
  324. */
  325. public function setParsedMessage(string $message): IEvent {
  326. $this->messageParsed = $message;
  327. return $this;
  328. }
  329. /**
  330. * @return string
  331. * @since 11.0.0
  332. */
  333. public function getParsedMessage(): string {
  334. return $this->messageParsed;
  335. }
  336. /**
  337. * @param string $message
  338. * @param array $parameters
  339. * @return $this
  340. * @throws \InvalidArgumentException if the subject or parameters are invalid
  341. * @since 11.0.0
  342. */
  343. public function setRichMessage(string $message, array $parameters = []): IEvent {
  344. $this->messageRich = $message;
  345. $this->messageRichParameters = $parameters;
  346. if ($this->messageParsed === '') {
  347. $this->messageParsed = $this->richToParsed($message, $parameters);
  348. }
  349. return $this;
  350. }
  351. /**
  352. * @return string
  353. * @since 11.0.0
  354. */
  355. public function getRichMessage(): string {
  356. return $this->messageRich;
  357. }
  358. /**
  359. * @return array[]
  360. * @since 11.0.0
  361. */
  362. public function getRichMessageParameters(): array {
  363. return $this->messageRichParameters;
  364. }
  365. /**
  366. * Set the object of the activity
  367. *
  368. * @param string $objectType
  369. * @param int $objectId
  370. * @param string $objectName
  371. * @return IEvent
  372. * @throws \InvalidArgumentException if the object is invalid
  373. * @since 8.2.0
  374. */
  375. public function setObject(string $objectType, int $objectId, string $objectName = ''): IEvent {
  376. if (isset($objectType[255])) {
  377. throw new \InvalidArgumentException('The given object type is invalid');
  378. }
  379. if (isset($objectName[4000])) {
  380. throw new \InvalidArgumentException('The given object name is invalid');
  381. }
  382. $this->objectType = $objectType;
  383. $this->objectId = $objectId;
  384. $this->objectName = $objectName;
  385. return $this;
  386. }
  387. /**
  388. * @return string
  389. */
  390. public function getObjectType(): string {
  391. return $this->objectType;
  392. }
  393. /**
  394. * @return int
  395. */
  396. public function getObjectId(): int {
  397. return $this->objectId;
  398. }
  399. /**
  400. * @return string
  401. */
  402. public function getObjectName(): string {
  403. return $this->objectName;
  404. }
  405. /**
  406. * Set the link of the activity
  407. *
  408. * @param string $link
  409. * @return IEvent
  410. * @throws \InvalidArgumentException if the link is invalid
  411. * @since 8.2.0
  412. */
  413. public function setLink(string $link): IEvent {
  414. if (isset($link[4000])) {
  415. throw new \InvalidArgumentException('The given link is invalid');
  416. }
  417. $this->link = $link;
  418. return $this;
  419. }
  420. /**
  421. * @return string
  422. */
  423. public function getLink(): string {
  424. return $this->link;
  425. }
  426. /**
  427. * @param string $icon
  428. * @return $this
  429. * @throws \InvalidArgumentException if the icon is invalid
  430. * @since 11.0.0
  431. */
  432. public function setIcon(string $icon): IEvent {
  433. if (isset($icon[4000])) {
  434. throw new \InvalidArgumentException('The given icon is invalid');
  435. }
  436. $this->icon = $icon;
  437. return $this;
  438. }
  439. /**
  440. * @return string
  441. * @since 11.0.0
  442. */
  443. public function getIcon(): string {
  444. return $this->icon;
  445. }
  446. /**
  447. * @param IEvent $child
  448. * @return $this
  449. * @since 11.0.0 - Since 15.0.0 returns $this
  450. */
  451. public function setChildEvent(IEvent $child): IEvent {
  452. $this->child = $child;
  453. return $this;
  454. }
  455. /**
  456. * @return IEvent|null
  457. * @since 11.0.0
  458. */
  459. public function getChildEvent() {
  460. return $this->child;
  461. }
  462. /**
  463. * @return bool
  464. * @since 8.2.0
  465. */
  466. public function isValid(): bool {
  467. return
  468. $this->isValidCommon()
  469. &&
  470. $this->getSubject() !== ''
  471. ;
  472. }
  473. /**
  474. * @return bool
  475. * @since 8.2.0
  476. */
  477. public function isValidParsed(): bool {
  478. if ($this->getRichSubject() !== '' || !empty($this->getRichSubjectParameters())) {
  479. try {
  480. $this->richValidator->validate($this->getRichSubject(), $this->getRichSubjectParameters());
  481. } catch (InvalidObjectExeption $e) {
  482. return false;
  483. }
  484. }
  485. if ($this->getRichMessage() !== '' || !empty($this->getRichMessageParameters())) {
  486. try {
  487. $this->richValidator->validate($this->getRichMessage(), $this->getRichMessageParameters());
  488. } catch (InvalidObjectExeption $e) {
  489. return false;
  490. }
  491. }
  492. return
  493. $this->isValidCommon()
  494. &&
  495. $this->getParsedSubject() !== ''
  496. ;
  497. }
  498. protected function isValidCommon(): bool {
  499. return
  500. $this->getApp() !== ''
  501. &&
  502. $this->getType() !== ''
  503. &&
  504. $this->getAffectedUser() !== ''
  505. &&
  506. $this->getTimestamp() !== 0
  507. /**
  508. * Disabled for BC with old activities
  509. * &&
  510. * $this->getObjectType() !== ''
  511. * &&
  512. * $this->getObjectId() !== 0
  513. */
  514. ;
  515. }
  516. public function setGenerateNotification(bool $generate): IEvent {
  517. $this->generateNotification = $generate;
  518. return $this;
  519. }
  520. public function getGenerateNotification(): bool {
  521. return $this->generateNotification;
  522. }
  523. }