You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

580 lines
12 KiB

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