diff --git a/lib/composer/composer/LICENSE b/lib/composer/composer/LICENSE index 62ecfd8d0046b..f27399a042d95 100644 --- a/lib/composer/composer/LICENSE +++ b/lib/composer/composer/LICENSE @@ -1,3 +1,4 @@ + Copyright (c) Nils Adermann, Jordi Boggiano Permission is hereby granted, free of charge, to any person obtaining a copy @@ -17,3 +18,4 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php index 526854bea7726..a726e5a54d524 100644 --- a/lib/composer/composer/autoload_classmap.php +++ b/lib/composer/composer/autoload_classmap.php @@ -567,6 +567,10 @@ 'OCP\\Notification\\IManager' => $baseDir . '/lib/public/Notification/IManager.php', 'OCP\\Notification\\INotification' => $baseDir . '/lib/public/Notification/INotification.php', 'OCP\\Notification\\INotifier' => $baseDir . '/lib/public/Notification/INotifier.php', + 'OCP\\Notification\\IncompleteNotificationException' => $baseDir . '/lib/public/Notification/IncompleteNotificationException.php', + 'OCP\\Notification\\IncompleteParsedNotificationException' => $baseDir . '/lib/public/Notification/IncompleteParsedNotificationException.php', + 'OCP\\Notification\\InvalidValueException' => $baseDir . '/lib/public/Notification/InvalidValueException.php', + 'OCP\\Notification\\UnknownNotificationException' => $baseDir . '/lib/public/Notification/UnknownNotificationException.php', 'OCP\\OCM\\Events\\ResourceTypeRegisterEvent' => $baseDir . '/lib/public/OCM/Events/ResourceTypeRegisterEvent.php', 'OCP\\OCM\\Exceptions\\OCMArgumentException' => $baseDir . '/lib/public/OCM/Exceptions/OCMArgumentException.php', 'OCP\\OCM\\Exceptions\\OCMProviderException' => $baseDir . '/lib/public/OCM/Exceptions/OCMProviderException.php', diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php index b05f8eaa395a2..1f29b6cb3b6db 100644 --- a/lib/composer/composer/autoload_static.php +++ b/lib/composer/composer/autoload_static.php @@ -600,6 +600,10 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2 'OCP\\Notification\\IManager' => __DIR__ . '/../../..' . '/lib/public/Notification/IManager.php', 'OCP\\Notification\\INotification' => __DIR__ . '/../../..' . '/lib/public/Notification/INotification.php', 'OCP\\Notification\\INotifier' => __DIR__ . '/../../..' . '/lib/public/Notification/INotifier.php', + 'OCP\\Notification\\IncompleteNotificationException' => __DIR__ . '/../../..' . '/lib/public/Notification/IncompleteNotificationException.php', + 'OCP\\Notification\\IncompleteParsedNotificationException' => __DIR__ . '/../../..' . '/lib/public/Notification/IncompleteParsedNotificationException.php', + 'OCP\\Notification\\InvalidValueException' => __DIR__ . '/../../..' . '/lib/public/Notification/InvalidValueException.php', + 'OCP\\Notification\\UnknownNotificationException' => __DIR__ . '/../../..' . '/lib/public/Notification/UnknownNotificationException.php', 'OCP\\OCM\\Events\\ResourceTypeRegisterEvent' => __DIR__ . '/../../..' . '/lib/public/OCM/Events/ResourceTypeRegisterEvent.php', 'OCP\\OCM\\Exceptions\\OCMArgumentException' => __DIR__ . '/../../..' . '/lib/public/OCM/Exceptions/OCMArgumentException.php', 'OCP\\OCM\\Exceptions\\OCMProviderException' => __DIR__ . '/../../..' . '/lib/public/OCM/Exceptions/OCMProviderException.php', diff --git a/lib/private/Notification/Action.php b/lib/private/Notification/Action.php index 9590d28af4ab7..8307960cf06b3 100644 --- a/lib/private/Notification/Action.php +++ b/lib/private/Notification/Action.php @@ -25,76 +25,53 @@ namespace OC\Notification; use OCP\Notification\IAction; +use OCP\Notification\InvalidValueException; class Action implements IAction { - protected string $label; - - protected string $labelParsed; - - protected string $link; - - protected string $requestType; - - protected string $icon; - - protected bool $primary; - - public function __construct() { - $this->label = ''; - $this->labelParsed = ''; - $this->link = ''; - $this->requestType = ''; - $this->primary = false; - } + protected string $label = ''; + protected string $labelParsed = ''; + protected string $link = ''; + protected string $requestType = ''; + protected bool $primary = false; /** - * @param string $label - * @return $this - * @throws \InvalidArgumentException if the label is invalid - * @since 8.2.0 + * {@inheritDoc} */ public function setLabel(string $label): IAction { if ($label === '' || isset($label[32])) { - throw new \InvalidArgumentException('The given label is invalid'); + throw new InvalidValueException('label'); } $this->label = $label; return $this; } /** - * @return string - * @since 8.2.0 + * {@inheritDoc} */ public function getLabel(): string { return $this->label; } /** - * @param string $label - * @return $this - * @throws \InvalidArgumentException if the label is invalid - * @since 8.2.0 + * {@inheritDoc} */ public function setParsedLabel(string $label): IAction { if ($label === '') { - throw new \InvalidArgumentException('The given parsed label is invalid'); + throw new InvalidValueException('parsedLabel'); } $this->labelParsed = $label; return $this; } /** - * @return string - * @since 8.2.0 + * {@inheritDoc} */ public function getParsedLabel(): string { return $this->labelParsed; } /** - * @param $primary bool - * @return $this - * @since 9.0.0 + * {@inheritDoc} */ public function setPrimary(bool $primary): IAction { $this->primary = $primary; @@ -102,23 +79,18 @@ public function setPrimary(bool $primary): IAction { } /** - * @return bool - * @since 9.0.0 + * {@inheritDoc} */ public function isPrimary(): bool { return $this->primary; } /** - * @param string $link - * @param string $requestType - * @return $this - * @throws \InvalidArgumentException if the link is invalid - * @since 8.2.0 + * {@inheritDoc} */ public function setLink(string $link, string $requestType): IAction { if ($link === '' || isset($link[256])) { - throw new \InvalidArgumentException('The given link is invalid'); + throw new InvalidValueException('link'); } if (!in_array($requestType, [ self::TYPE_GET, @@ -127,7 +99,7 @@ public function setLink(string $link, string $requestType): IAction { self::TYPE_DELETE, self::TYPE_WEB, ], true)) { - throw new \InvalidArgumentException('The given request type is invalid'); + throw new InvalidValueException('requestType'); } $this->link = $link; $this->requestType = $requestType; @@ -135,30 +107,28 @@ public function setLink(string $link, string $requestType): IAction { } /** - * @return string - * @since 8.2.0 + * {@inheritDoc} */ public function getLink(): string { return $this->link; } /** - * @return string - * @since 8.2.0 + * {@inheritDoc} */ public function getRequestType(): string { return $this->requestType; } /** - * @return bool + * {@inheritDoc} */ public function isValid(): bool { return $this->label !== '' && $this->link !== ''; } /** - * @return bool + * {@inheritDoc} */ public function isValidParsed(): bool { return $this->labelParsed !== '' && $this->link !== ''; diff --git a/lib/private/Notification/Manager.php b/lib/private/Notification/Manager.php index 348ddb03df92c..5e7c888d4d941 100644 --- a/lib/private/Notification/Manager.php +++ b/lib/private/Notification/Manager.php @@ -35,8 +35,11 @@ use OCP\Notification\IDeferrableApp; use OCP\Notification\IDismissableNotifier; use OCP\Notification\IManager; +use OCP\Notification\IncompleteNotificationException; +use OCP\Notification\IncompleteParsedNotificationException; use OCP\Notification\INotification; use OCP\Notification\INotifier; +use OCP\Notification\UnknownNotificationException; use OCP\RichObjectStrings\IValidator; use OCP\Support\Subscription\IRegistry; use Psr\Container\ContainerExceptionInterface; @@ -300,13 +303,11 @@ public function isFairUseOfFreePushService(): bool { } /** - * @param INotification $notification - * @throws \InvalidArgumentException When the notification is not valid - * @since 8.2.0 + * {@inheritDoc} */ public function notify(INotification $notification): void { if (!$notification->isValid()) { - throw new \InvalidArgumentException('The given notification is invalid'); + throw new IncompleteNotificationException('The given notification is invalid'); } $apps = $this->getApps(); @@ -314,7 +315,11 @@ public function notify(INotification $notification): void { foreach ($apps as $app) { try { $app->notify($notification); + } catch (IncompleteNotificationException) { } catch (\InvalidArgumentException $e) { + // todo 33.0.0 Log as warning + // todo 39.0.0 Log as error + $this->logger->debug(get_class($app) . '::notify() threw \InvalidArgumentException which is deprecated. Throw \OCP\Notification\IncompleteNotificationException when the notification is incomplete for your app and otherwise handle all \InvalidArgumentException yourself.'); } } } @@ -340,12 +345,7 @@ public function getName(): string { } /** - * @param INotification $notification - * @param string $languageCode The code of the language that should be used to prepare the notification - * @return INotification - * @throws \InvalidArgumentException When the notification was not prepared by a notifier - * @throws AlreadyProcessedException When the notification is not needed anymore and should be deleted - * @since 8.2.0 + * {@inheritDoc} */ public function prepare(INotification $notification, string $languageCode): INotification { $notifiers = $this->getNotifiers(); @@ -353,21 +353,44 @@ public function prepare(INotification $notification, string $languageCode): INot foreach ($notifiers as $notifier) { try { $notification = $notifier->prepare($notification, $languageCode); - } catch (\InvalidArgumentException $e) { - continue; } catch (AlreadyProcessedException $e) { $this->markProcessed($notification); - throw new \InvalidArgumentException('The given notification has been processed'); + throw $e; + } catch (UnknownNotificationException) { + continue; + } catch (\InvalidArgumentException $e) { + // todo 33.0.0 Log as warning + // todo 39.0.0 Log as error + $this->logger->debug(get_class($notifier) . '::prepare() threw \InvalidArgumentException which is deprecated. Throw \OCP\Notification\UnknownNotificationException when the notification is not known to your notifier and otherwise handle all \InvalidArgumentException yourself.'); + continue; } if (!$notification->isValidParsed()) { - throw new \InvalidArgumentException('The given notification has not been handled'); + $this->logger->info('Notification was claimed to be parsed, but was not fully parsed by ' . get_class($notifier) . ' [app: ' . $notification->getApp() . ', subject: ' . $notification->getSubject() . ']'); + throw new IncompleteParsedNotificationException(); } } if (!$notification->isValidParsed()) { $this->logger->info('Notification was not parsed by any notifier [app: ' . $notification->getApp() . ', subject: ' . $notification->getSubject() . ']'); - throw new \InvalidArgumentException('The given notification has not been handled'); + throw new IncompleteParsedNotificationException(); + } + + $link = $notification->getLink(); + if ($link !== '' && !str_starts_with($link, 'http://') && !str_starts_with($link, 'https://')) { + $this->logger->warning('Link of notification is not an absolute URL and does not work in mobile and desktop clients [app: ' . $notification->getApp() . ', subject: ' . $notification->getSubject() . ']'); + } + + $icon = $notification->getIcon(); + if ($icon !== '' && !str_starts_with($icon, 'http://') && !str_starts_with($icon, 'https://')) { + $this->logger->warning('Icon of notification is not an absolute URL and does not work in mobile and desktop clients [app: ' . $notification->getApp() . ', subject: ' . $notification->getSubject() . ']'); + } + + foreach ($notification->getParsedActions() as $action) { + $link = $action->getLink(); + if ($link !== '' && !str_starts_with($link, 'http://') && !str_starts_with($link, 'https://')) { + $this->logger->warning('Link of action is not an absolute URL and does not work in mobile and desktop clients [app: ' . $notification->getApp() . ', subject: ' . $notification->getSubject() . ']'); + } } return $notification; @@ -399,6 +422,9 @@ public function getCount(INotification $notification): int { return $count; } + /** + * {@inheritDoc} + */ public function dismissNotification(INotification $notification): void { $notifiers = $this->getNotifiers(); @@ -406,7 +432,12 @@ public function dismissNotification(INotification $notification): void { if ($notifier instanceof IDismissableNotifier) { try { $notifier->dismissNotification($notification); + } catch (UnknownNotificationException) { + continue; } catch (\InvalidArgumentException $e) { + // todo 33.0.0 Log as warning + // todo 39.0.0 Log as error + $this->logger->debug(get_class($notifier) . '::dismissNotification() threw \InvalidArgumentException which is deprecated. Throw \OCP\Notification\UnknownNotificationException when the notification is not known to your notifier and otherwise handle all \InvalidArgumentException yourself.'); continue; } } diff --git a/lib/private/Notification/Notification.php b/lib/private/Notification/Notification.php index ed2a84b0de2f8..2398fd5523473 100644 --- a/lib/private/Notification/Notification.php +++ b/lib/private/Notification/Notification.php @@ -28,6 +28,7 @@ use OCP\Notification\IAction; use OCP\Notification\INotification; +use OCP\Notification\InvalidValueException; use OCP\RichObjectStrings\InvalidObjectExeption; use OCP\RichObjectStrings\IValidator; @@ -62,117 +63,95 @@ public function __construct( } /** - * @param string $app - * @return $this - * @throws \InvalidArgumentException if the app id is invalid - * @since 8.2.0 + * {@inheritDoc} */ public function setApp(string $app): INotification { if ($app === '' || isset($app[32])) { - throw new \InvalidArgumentException('The given app name is invalid'); + throw new InvalidValueException('app'); } $this->app = $app; return $this; } /** - * @return string - * @since 8.2.0 + * {@inheritDoc} */ public function getApp(): string { return $this->app; } /** - * @param string $user - * @return $this - * @throws \InvalidArgumentException if the user id is invalid - * @since 8.2.0 + * {@inheritDoc} */ public function setUser(string $user): INotification { if ($user === '' || isset($user[64])) { - throw new \InvalidArgumentException('The given user id is invalid'); + throw new InvalidValueException('user'); } $this->user = $user; return $this; } /** - * @return string - * @since 8.2.0 + * {@inheritDoc} */ public function getUser(): string { return $this->user; } /** - * @param \DateTime $dateTime - * @return $this - * @throws \InvalidArgumentException if the $dateTime is invalid - * @since 9.0.0 + * {@inheritDoc} */ public function setDateTime(\DateTime $dateTime): INotification { if ($dateTime->getTimestamp() === 0) { - throw new \InvalidArgumentException('The given date time is invalid'); + throw new InvalidValueException('dateTime'); } $this->dateTime = $dateTime; return $this; } /** - * @return \DateTime - * @since 9.0.0 + * {@inheritDoc} */ public function getDateTime(): \DateTime { return $this->dateTime; } /** - * @param string $type - * @param string $id - * @return $this - * @throws \InvalidArgumentException if the object type or id is invalid - * @since 8.2.0 - 9.0.0: Type of $id changed to string + * {@inheritDoc} */ public function setObject(string $type, string $id): INotification { if ($type === '' || isset($type[64])) { - throw new \InvalidArgumentException('The given object type is invalid'); + throw new InvalidValueException('objectType'); } $this->objectType = $type; if ($id === '' || isset($id[64])) { - throw new \InvalidArgumentException('The given object id is invalid'); + throw new InvalidValueException('objectId'); } $this->objectId = $id; return $this; } /** - * @return string - * @since 8.2.0 + * {@inheritDoc} */ public function getObjectType(): string { return $this->objectType; } /** - * @return string - * @since 8.2.0 - 9.0.0: Return type changed to string + * {@inheritDoc} */ public function getObjectId(): string { return $this->objectId; } /** - * @param string $subject - * @param array $parameters - * @return $this - * @throws \InvalidArgumentException if the subject or parameters are invalid - * @since 8.2.0 + * {@inheritDoc} */ public function setSubject(string $subject, array $parameters = []): INotification { if ($subject === '' || isset($subject[64])) { - throw new \InvalidArgumentException('The given subject is invalid'); + throw new InvalidValueException('subject'); } $this->subject = $subject; @@ -182,60 +161,54 @@ public function setSubject(string $subject, array $parameters = []): INotificati } /** - * @return string - * @since 8.2.0 + * {@inheritDoc} */ public function getSubject(): string { return $this->subject; } /** - * @return array - * @since 8.2.0 + * {@inheritDoc} */ public function getSubjectParameters(): array { return $this->subjectParameters; } /** - * @param string $subject - * @return $this - * @throws \InvalidArgumentException if the subject is invalid - * @since 8.2.0 + * {@inheritDoc} */ public function setParsedSubject(string $subject): INotification { if ($subject === '') { - throw new \InvalidArgumentException('The given parsed subject is invalid'); + throw new InvalidValueException('parsedSubject'); } $this->subjectParsed = $subject; return $this; } /** - * @return string - * @since 8.2.0 + * {@inheritDoc} */ public function getParsedSubject(): string { return $this->subjectParsed; } /** - * @param string $subject - * @param array $parameters - * @return $this - * @throws \InvalidArgumentException if the subject or parameters are invalid - * @since 11.0.0 + * {@inheritDoc} */ public function setRichSubject(string $subject, array $parameters = []): INotification { if ($subject === '') { - throw new \InvalidArgumentException('The given parsed subject is invalid'); + throw new InvalidValueException('richSubject'); } $this->subjectRich = $subject; $this->subjectRichParameters = $parameters; if ($this->subjectParsed === '') { - $this->subjectParsed = $this->richToParsed($subject, $parameters); + try { + $this->subjectParsed = $this->richToParsed($subject, $parameters); + } catch (\InvalidArgumentException $e) { + throw new InvalidValueException('richSubjectParameters', $e); + } } return $this; @@ -266,31 +239,25 @@ private function richToParsed(string $message, array $parameters): string { } /** - * @return string - * @since 11.0.0 + * {@inheritDoc} */ public function getRichSubject(): string { return $this->subjectRich; } /** - * @return array[] - * @since 11.0.0 + * {@inheritDoc} */ public function getRichSubjectParameters(): array { return $this->subjectRichParameters; } /** - * @param string $message - * @param array $parameters - * @return $this - * @throws \InvalidArgumentException if the message or parameters are invalid - * @since 8.2.0 + * {@inheritDoc} */ public function setMessage(string $message, array $parameters = []): INotification { if ($message === '' || isset($message[64])) { - throw new \InvalidArgumentException('The given message is invalid'); + throw new InvalidValueException('message'); } $this->message = $message; @@ -300,147 +267,127 @@ public function setMessage(string $message, array $parameters = []): INotificati } /** - * @return string - * @since 8.2.0 + * {@inheritDoc} */ public function getMessage(): string { return $this->message; } /** - * @return array - * @since 8.2.0 + * {@inheritDoc} */ public function getMessageParameters(): array { return $this->messageParameters; } /** - * @param string $message - * @return $this - * @throws \InvalidArgumentException if the message is invalid - * @since 8.2.0 + * {@inheritDoc} */ public function setParsedMessage(string $message): INotification { if ($message === '') { - throw new \InvalidArgumentException('The given parsed message is invalid'); + throw new InvalidValueException('parsedMessage'); } $this->messageParsed = $message; return $this; } /** - * @return string - * @since 8.2.0 + * {@inheritDoc} */ public function getParsedMessage(): string { return $this->messageParsed; } /** - * @param string $message - * @param array $parameters - * @return $this - * @throws \InvalidArgumentException if the message or parameters are invalid - * @since 11.0.0 + * {@inheritDoc} */ public function setRichMessage(string $message, array $parameters = []): INotification { if ($message === '') { - throw new \InvalidArgumentException('The given parsed message is invalid'); + throw new InvalidValueException('richMessage'); } $this->messageRich = $message; $this->messageRichParameters = $parameters; if ($this->messageParsed === '') { - $this->messageParsed = $this->richToParsed($message, $parameters); + try { + $this->messageParsed = $this->richToParsed($message, $parameters); + } catch (\InvalidArgumentException $e) { + throw new InvalidValueException('richMessageParameters', $e); + } } return $this; } /** - * @return string - * @since 11.0.0 + * {@inheritDoc} */ public function getRichMessage(): string { return $this->messageRich; } /** - * @return array[] - * @since 11.0.0 + * {@inheritDoc} */ public function getRichMessageParameters(): array { return $this->messageRichParameters; } /** - * @param string $link - * @return $this - * @throws \InvalidArgumentException if the link is invalid - * @since 8.2.0 + * {@inheritDoc} */ public function setLink(string $link): INotification { if ($link === '' || isset($link[4000])) { - throw new \InvalidArgumentException('The given link is invalid'); + throw new InvalidValueException('link'); } $this->link = $link; return $this; } /** - * @return string - * @since 8.2.0 + * {@inheritDoc} */ public function getLink(): string { return $this->link; } /** - * @param string $icon - * @return $this - * @throws \InvalidArgumentException if the icon is invalid - * @since 11.0.0 + * {@inheritDoc} */ public function setIcon(string $icon): INotification { if ($icon === '' || isset($icon[4000])) { - throw new \InvalidArgumentException('The given icon is invalid'); + throw new InvalidValueException('icon'); } $this->icon = $icon; return $this; } /** - * @return string - * @since 11.0.0 + * {@inheritDoc} */ public function getIcon(): string { return $this->icon; } /** - * @return IAction - * @since 8.2.0 + * {@inheritDoc} */ public function createAction(): IAction { return new Action(); } /** - * @param IAction $action - * @return $this - * @throws \InvalidArgumentException if the action is invalid - * @since 8.2.0 + * {@inheritDoc} */ public function addAction(IAction $action): INotification { if (!$action->isValid()) { - throw new \InvalidArgumentException('The given action is invalid'); + throw new InvalidValueException('action'); } if ($action->isPrimary()) { if ($this->hasPrimaryAction) { - throw new \InvalidArgumentException('The notification already has a primary action'); + throw new InvalidValueException('primaryAction'); } $this->hasPrimaryAction = true; @@ -451,27 +398,23 @@ public function addAction(IAction $action): INotification { } /** - * @return IAction[] - * @since 8.2.0 + * {@inheritDoc} */ public function getActions(): array { return $this->actions; } /** - * @param IAction $action - * @return $this - * @throws \InvalidArgumentException if the action is invalid - * @since 8.2.0 + * {@inheritDoc} */ public function addParsedAction(IAction $action): INotification { if (!$action->isValidParsed()) { - throw new \InvalidArgumentException('The given parsed action is invalid'); + throw new InvalidValueException('action'); } if ($action->isPrimary()) { if ($this->hasPrimaryParsedAction) { - throw new \InvalidArgumentException('The notification already has a primary action'); + throw new InvalidValueException('primaryAction'); } $this->hasPrimaryParsedAction = true; @@ -486,16 +429,14 @@ public function addParsedAction(IAction $action): INotification { } /** - * @return IAction[] - * @since 8.2.0 + * {@inheritDoc} */ public function getParsedActions(): array { return $this->actionsParsed; } /** - * @return bool - * @since 8.2.0 + * {@inheritDoc} */ public function isValid(): bool { return @@ -506,8 +447,7 @@ public function isValid(): bool { } /** - * @return bool - * @since 8.2.0 + * {@inheritDoc} */ public function isValidParsed(): bool { if ($this->getRichSubject() !== '' || !empty($this->getRichSubjectParameters())) { diff --git a/lib/public/Notification/IAction.php b/lib/public/Notification/IAction.php index bcd013f08bc09..3009101fed0cf 100644 --- a/lib/public/Notification/IAction.php +++ b/lib/public/Notification/IAction.php @@ -54,8 +54,9 @@ interface IAction { /** * @param string $label * @return $this - * @throws \InvalidArgumentException if the label is invalid + * @throws InvalidValueException if the label is invalid * @since 9.0.0 + * @since 30.0.0 throws {@see InvalidValueException} instead of \InvalidArgumentException */ public function setLabel(string $label): IAction; @@ -68,8 +69,9 @@ public function getLabel(): string; /** * @param string $label * @return $this - * @throws \InvalidArgumentException if the label is invalid + * @throws InvalidValueException if the label is invalid * @since 9.0.0 + * @since 30.0.0 throws {@see InvalidValueException} instead of \InvalidArgumentException */ public function setParsedLabel(string $label): IAction; @@ -82,7 +84,6 @@ public function getParsedLabel(): string; /** * @param bool $primary * @return $this - * @throws \InvalidArgumentException if $primary is invalid * @since 9.0.0 */ public function setPrimary(bool $primary): IAction; @@ -97,8 +98,9 @@ public function isPrimary(): bool; * @param string $link * @param string $requestType * @return $this - * @throws \InvalidArgumentException if the link is invalid + * @throws InvalidValueException if the link is invalid * @since 9.0.0 + * @since 30.0.0 throws {@see InvalidValueException} instead of \InvalidArgumentException */ public function setLink(string $link, string $requestType): IAction; diff --git a/lib/public/Notification/IApp.php b/lib/public/Notification/IApp.php index 6abb9a823e52d..a3ef2771c8a9c 100644 --- a/lib/public/Notification/IApp.php +++ b/lib/public/Notification/IApp.php @@ -32,8 +32,9 @@ interface IApp { /** * @param INotification $notification - * @throws \InvalidArgumentException When the notification is not valid + * @throws IncompleteNotificationException When the notification does not have all required fields set * @since 9.0.0 + * @since 30.0.0 throws {@see IncompleteNotificationException} instead of \InvalidArgumentException */ public function notify(INotification $notification): void; diff --git a/lib/public/Notification/IDismissableNotifier.php b/lib/public/Notification/IDismissableNotifier.php index c13e880a4a630..45f7a2aa9db3b 100644 --- a/lib/public/Notification/IDismissableNotifier.php +++ b/lib/public/Notification/IDismissableNotifier.php @@ -30,16 +30,19 @@ * that are dismissed by the user. * * This can be useful if dismissing the notification will leave it in an incomplete - * state. The handler can chose to for example do some default action. + * state. The handler can choose to for example do some default action. * * @since 18.0.0 */ interface IDismissableNotifier extends INotifier { /** * @param INotification $notification - * @throws \InvalidArgumentException In case the handler can't handle the notification + * @throws UnknownNotificationException when the notifier is not in charge of the notification * * @since 18.0.0 + * @since 30.0.0 Notifiers should throw {@see UnknownNotificationException} instead of \InvalidArgumentException + * when they did not handle the notification. Throwing \InvalidArgumentException directly is deprecated and will + * be logged as an error in Nextcloud 39. */ public function dismissNotification(INotification $notification): void; } diff --git a/lib/public/Notification/INotification.php b/lib/public/Notification/INotification.php index 0c6625e346d97..b751732658128 100644 --- a/lib/public/Notification/INotification.php +++ b/lib/public/Notification/INotification.php @@ -34,8 +34,9 @@ interface INotification { /** * @param string $app * @return $this - * @throws \InvalidArgumentException if the app id is invalid + * @throws InvalidValueException if the app id is invalid * @since 9.0.0 + * @since 30.0.0 throws {@see InvalidValueException} instead of \InvalidArgumentException */ public function setApp(string $app): INotification; @@ -48,8 +49,9 @@ public function getApp(): string; /** * @param string $user * @return $this - * @throws \InvalidArgumentException if the user id is invalid + * @throws InvalidValueException if the user id is invalid * @since 9.0.0 + * @since 30.0.0 throws {@see InvalidValueException} instead of \InvalidArgumentException */ public function setUser(string $user): INotification; @@ -62,8 +64,9 @@ public function getUser(): string; /** * @param \DateTime $dateTime * @return $this - * @throws \InvalidArgumentException if the $dateTime is invalid + * @throws InvalidValueException if the $dateTime is invalid * @since 9.0.0 + * @since 30.0.0 throws {@see InvalidValueException} instead of \InvalidArgumentException */ public function setDateTime(\DateTime $dateTime): INotification; @@ -77,8 +80,9 @@ public function getDateTime(): \DateTime; * @param string $type * @param string $id * @return $this - * @throws \InvalidArgumentException if the object type or id is invalid + * @throws InvalidValueException if the object type or id is invalid * @since 9.0.0 + * @since 30.0.0 throws {@see InvalidValueException} instead of \InvalidArgumentException */ public function setObject(string $type, string $id): INotification; @@ -98,8 +102,9 @@ public function getObjectId(): string; * @param string $subject * @param array $parameters * @return $this - * @throws \InvalidArgumentException if the subject or parameters are invalid + * @throws InvalidValueException if the subject or parameters are invalid * @since 9.0.0 + * @since 30.0.0 throws {@see InvalidValueException} instead of \InvalidArgumentException */ public function setSubject(string $subject, array $parameters = []): INotification; @@ -127,8 +132,9 @@ public function getSubjectParameters(): array; * * @param string $subject * @return $this - * @throws \InvalidArgumentException if the subject is invalid + * @throws InvalidValueException if the subject is invalid * @since 9.0.0 + * @since 30.0.0 throws {@see InvalidValueException} instead of \InvalidArgumentException */ public function setParsedSubject(string $subject): INotification; @@ -150,8 +156,9 @@ public function getParsedSubject(): string; * @param string $subject * @param array $parameters * @return $this - * @throws \InvalidArgumentException if the subject or parameters are invalid + * @throws InvalidValueException if the subject or parameters are invalid * @since 11.0.0 + * @since 30.0.0 throws {@see InvalidValueException} instead of \InvalidArgumentException */ public function setRichSubject(string $subject, array $parameters = []): INotification; @@ -171,8 +178,9 @@ public function getRichSubjectParameters(): array; * @param string $message * @param array $parameters * @return $this - * @throws \InvalidArgumentException if the message or parameters are invalid + * @throws InvalidValueException if the message or parameters are invalid * @since 9.0.0 + * @since 30.0.0 throws {@see InvalidValueException} instead of \InvalidArgumentException */ public function setMessage(string $message, array $parameters = []): INotification; @@ -200,8 +208,9 @@ public function getMessageParameters(): array; * * @param string $message * @return $this - * @throws \InvalidArgumentException if the message is invalid + * @throws InvalidValueException if the message is invalid * @since 9.0.0 + * @since 30.0.0 throws {@see InvalidValueException} instead of \InvalidArgumentException */ public function setParsedMessage(string $message): INotification; @@ -223,8 +232,9 @@ public function getParsedMessage(): string; * @param string $message * @param array $parameters * @return $this - * @throws \InvalidArgumentException if the message or parameters are invalid + * @throws InvalidValueException if the message or parameters are invalid * @since 11.0.0 + * @since 30.0.0 throws {@see InvalidValueException} instead of \InvalidArgumentException */ public function setRichMessage(string $message, array $parameters = []): INotification; @@ -243,8 +253,9 @@ public function getRichMessageParameters(): array; /** * @param string $link * @return $this - * @throws \InvalidArgumentException if the link is invalid + * @throws InvalidValueException if the link is invalid * @since 9.0.0 + * @since 30.0.0 throws {@see InvalidValueException} instead of \InvalidArgumentException */ public function setLink(string $link): INotification; @@ -257,8 +268,9 @@ public function getLink(): string; /** * @param string $icon * @return $this - * @throws \InvalidArgumentException if the icon is invalid + * @throws InvalidValueException if the icon is invalid * @since 11.0.0 + * @since 30.0.0 throws {@see InvalidValueException} instead of \InvalidArgumentException */ public function setIcon(string $icon): INotification; @@ -277,8 +289,9 @@ public function createAction(): IAction; /** * @param IAction $action * @return $this - * @throws \InvalidArgumentException if the action is invalid + * @throws InvalidValueException if the action is invalid * @since 9.0.0 + * @since 30.0.0 throws {@see InvalidValueException} instead of \InvalidArgumentException */ public function addAction(IAction $action): INotification; @@ -291,8 +304,9 @@ public function getActions(): array; /** * @param IAction $action * @return $this - * @throws \InvalidArgumentException if the action is invalid + * @throws InvalidValueException if the action is invalid * @since 9.0.0 + * @since 30.0.0 throws {@see InvalidValueException} instead of \InvalidArgumentException */ public function addParsedAction(IAction $action): INotification; diff --git a/lib/public/Notification/INotifier.php b/lib/public/Notification/INotifier.php index ba43cc04cf6c0..2014f73d5aae3 100644 --- a/lib/public/Notification/INotifier.php +++ b/lib/public/Notification/INotifier.php @@ -39,7 +39,7 @@ interface INotifier { public function getID(): string; /** - * Human readable name describing the notifier + * Human-readable name describing the notifier * * @return string * @since 17.0.0 @@ -50,9 +50,15 @@ public function getName(): string; * @param INotification $notification * @param string $languageCode The code of the language that should be used to prepare the notification * @return INotification - * @throws \InvalidArgumentException When the notification was not prepared by a notifier + * @throws UnknownNotificationException When the notification was not prepared by a notifier * @throws AlreadyProcessedException When the notification is not needed anymore and should be deleted + * @throws IncompleteParsedNotificationException Only to be thrown by the {@see IManager} * @since 9.0.0 + * @since 30.0.0 Notifiers should throw {@see UnknownNotificationException} instead of \InvalidArgumentException + * when they did not handle the notification. Throwing \InvalidArgumentException directly is deprecated and will + * be logged as an error in Nextcloud 39. + * @since 30.0.0 Throws {@see IncompleteParsedNotificationException} when not all required fields + * are set at the end of the manager or after a INotifier that claimed to have parsed the notification. */ public function prepare(INotification $notification, string $languageCode): INotification; } diff --git a/lib/public/Notification/IncompleteNotificationException.php b/lib/public/Notification/IncompleteNotificationException.php new file mode 100644 index 0000000000000..31551389b432b --- /dev/null +++ b/lib/public/Notification/IncompleteNotificationException.php @@ -0,0 +1,43 @@ + + * + * @author Joas Schilling + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +namespace OCP\Notification; + +/** + * Thrown when {@see \OCP\Notification\IManager::notify()} is called with a notification + * that does not have all required fields set: + * + * - app + * - user + * - dateTime + * - objectType + * - objectId + * - subject + * + * @since 30.0.0 + */ +class IncompleteNotificationException extends \InvalidArgumentException { +} diff --git a/lib/public/Notification/IncompleteParsedNotificationException.php b/lib/public/Notification/IncompleteParsedNotificationException.php new file mode 100644 index 0000000000000..0a8ca8a61e663 --- /dev/null +++ b/lib/public/Notification/IncompleteParsedNotificationException.php @@ -0,0 +1,46 @@ + + * + * @author Joas Schilling + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +namespace OCP\Notification; + +/** + * Thrown when {@see \OCP\Notification\IManager::prepare()} is called with a notification + * that does not have all required fields set at the end of the manager or after a INotifier + * that claimed to have parsed the notification. + * + * Required fields are: + * + * - app + * - user + * - dateTime + * - objectType + * - objectId + * - parsedSubject + * + * @since 30.0.0 + */ +class IncompleteParsedNotificationException extends \InvalidArgumentException { +} diff --git a/lib/public/Notification/InvalidValueException.php b/lib/public/Notification/InvalidValueException.php new file mode 100644 index 0000000000000..6c16ea9503673 --- /dev/null +++ b/lib/public/Notification/InvalidValueException.php @@ -0,0 +1,49 @@ + + * + * @author Joas Schilling + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +namespace OCP\Notification; + +/** + * @since 30.0.0 + */ +class InvalidValueException extends \InvalidArgumentException { + /** + * @since 30.0.0 + */ + public function __construct( + protected string $field, + ?\Throwable $previous = null, + ) { + parent::__construct('Value provided for ' . $field . ' is not valid', previous: $previous); + } + + /** + * @since 30.0.0 + */ + public function getFieldIdentifier(): string { + return $this->field; + } +} diff --git a/lib/public/Notification/UnknownNotificationException.php b/lib/public/Notification/UnknownNotificationException.php new file mode 100644 index 0000000000000..bfeeb6a14c59f --- /dev/null +++ b/lib/public/Notification/UnknownNotificationException.php @@ -0,0 +1,33 @@ + + * + * @author Joas Schilling + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +namespace OCP\Notification; + +/** + * @since 30.0.0 + */ +class UnknownNotificationException extends \InvalidArgumentException { +}