diff options
author | Maxence Lange <maxence@artificial-owl.com> | 2019-07-03 14:46:09 -0100 |
---|---|---|
committer | Maxence Lange <maxence@artificial-owl.com> | 2019-07-03 14:46:09 -0100 |
commit | dce161e62e108583b936d24b55bc7e3f25ea4b69 (patch) | |
tree | a4fcda05d0645c5dd20a71db740df59db9c6b9a5 /lib | |
parent | 9d27b85c884acbdaad3aa725e47a503d00279cd8 (diff) |
manage notification on unboost/unlike
Signed-off-by: Maxence Lange <maxence@artificial-owl.com>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Db/ActionsRequest.php | 12 | ||||
-rw-r--r-- | lib/Exceptions/ActionDoesNotExistException.php (renamed from lib/Exceptions/LikeDoesNotExistException.php) | 2 | ||||
-rw-r--r-- | lib/Interfaces/Internal/SocialAppNotificationInterface.php | 3 | ||||
-rw-r--r-- | lib/Interfaces/Object/AnnounceInterface.php | 81 | ||||
-rw-r--r-- | lib/Interfaces/Object/LikeInterface.php | 93 | ||||
-rw-r--r-- | lib/Traits/TDetails.php | 63 |
6 files changed, 218 insertions, 36 deletions
diff --git a/lib/Db/ActionsRequest.php b/lib/Db/ActionsRequest.php index b102362d..cb01c5fc 100644 --- a/lib/Db/ActionsRequest.php +++ b/lib/Db/ActionsRequest.php @@ -34,7 +34,7 @@ namespace OCA\Social\Db; use daita\MySmallPhpTools\Traits\TArrayTools; use DateTime; use Exception; -use OCA\Social\Exceptions\LikeDoesNotExistException; +use OCA\Social\Exceptions\ActionDoesNotExistException; use OCA\Social\Model\ActivityPub\ACore; use OCA\Social\Model\ActivityPub\Object\Like; use OCP\DB\QueryBuilder\IQueryBuilder; @@ -84,7 +84,7 @@ class ActionsRequest extends ActionsRequestBuilder { * @param string $type * * @return ACore - * @throws LikeDoesNotExistException + * @throws ActionDoesNotExistException */ public function getAction(string $actorId, string $objectId, string $type): ACore { $qb = $this->getActionsSelectSql(); @@ -96,7 +96,7 @@ class ActionsRequest extends ActionsRequestBuilder { $data = $cursor->fetch(); $cursor->closeCursor(); if ($data === false) { - throw new LikeDoesNotExistException(); + throw new ActionDoesNotExistException(); } return $this->parseActionsSelectSql($data); @@ -144,11 +144,11 @@ class ActionsRequest extends ActionsRequestBuilder { /** - * @param Like $like + * @param ACore $item */ - public function delete(Like $like) { + public function delete(ACore $item) { $qb = $this->getActionsDeleteSql(); - $this->limitToIdString($qb, $like->getId()); + $this->limitToIdString($qb, $item->getId()); $qb->execute(); } diff --git a/lib/Exceptions/LikeDoesNotExistException.php b/lib/Exceptions/ActionDoesNotExistException.php index 66e79da3..b52cd7af 100644 --- a/lib/Exceptions/LikeDoesNotExistException.php +++ b/lib/Exceptions/ActionDoesNotExistException.php @@ -34,7 +34,7 @@ namespace OCA\Social\Exceptions; use Exception; -class LikeDoesNotExistException extends Exception { +class ActionDoesNotExistException extends Exception { } diff --git a/lib/Interfaces/Internal/SocialAppNotificationInterface.php b/lib/Interfaces/Internal/SocialAppNotificationInterface.php index 72e99069..5863cc7d 100644 --- a/lib/Interfaces/Internal/SocialAppNotificationInterface.php +++ b/lib/Interfaces/Internal/SocialAppNotificationInterface.php @@ -36,6 +36,7 @@ use OCA\Social\Exceptions\ItemNotFoundException; use OCA\Social\Interfaces\IActivityPubInterface; use OCA\Social\Model\ActivityPub\ACore; use OCA\Social\Model\ActivityPub\Internal\SocialAppNotification; +use OCA\Social\Model\ActivityPub\Stream; use OCA\Social\Service\ConfigService; use OCA\Social\Service\CurlService; use OCA\Social\Service\MiscService; @@ -144,6 +145,8 @@ class SocialAppNotificationInterface implements IActivityPubInterface { * @param ACore $item */ public function delete(ACore $item) { + /** @var Stream $item */ + $this->streamRequest->deleteStreamById($item->getId(), SocialAppNotification::TYPE); } diff --git a/lib/Interfaces/Object/AnnounceInterface.php b/lib/Interfaces/Object/AnnounceInterface.php index ad261abe..d7f302f1 100644 --- a/lib/Interfaces/Object/AnnounceInterface.php +++ b/lib/Interfaces/Object/AnnounceInterface.php @@ -38,6 +38,7 @@ use Exception; use OCA\Social\AP; use OCA\Social\Db\ActionsRequest; use OCA\Social\Db\StreamRequest; +use OCA\Social\Exceptions\ActionDoesNotExistException; use OCA\Social\Exceptions\InvalidOriginException; use OCA\Social\Exceptions\InvalidResourceException; use OCA\Social\Exceptions\ItemNotFoundException; @@ -116,7 +117,7 @@ class AnnounceInterface implements IActivityPubInterface { /** * @param ACore $activity - * @param ACore $item + * @param ACore $announce * * @throws InvalidOriginException * @throws InvalidResourceException @@ -129,12 +130,14 @@ class AnnounceInterface implements IActivityPubInterface { * @throws RequestServerException * @throws UnauthorizedFediverseException */ - public function activity(Acore $activity, ACore $item) { - $item->checkOrigin($activity->getId()); - + public function activity(Acore $activity, ACore $announce) { + /** @var Announce $announce */ if ($activity->getType() === Undo::TYPE) { - $item->checkOrigin($item->getId()); - $this->delete($item); + $activity->checkOrigin($announce->getId()); + $activity->checkOrigin($announce->getActorId()); + + $this->undoAnnounceAction($announce); + $this->delete($announce); } } @@ -202,7 +205,7 @@ class AnnounceInterface implements IActivityPubInterface { } $this->updateDetails($post); - $this->updateNotification($post, $actor); + $this->generateNotification($post, $actor); } catch (StreamNotFoundException $e) { $objectId = $item->getObjectId(); $item->addCacheItem($objectId); @@ -292,7 +295,7 @@ class AnnounceInterface implements IActivityPubInterface { $post = $this->streamRequest->getStreamById($item->getObjectId()); $this->updateDetails($post); - $this->updateNotification($post, $actor); + $this->generateNotification($post, $actor); } catch (Exception $e) { } @@ -302,6 +305,33 @@ class AnnounceInterface implements IActivityPubInterface { /** + * @param Announce $announce + */ + private function undoAnnounceAction(Announce $announce) { + try { + $this->actionsRequest->getAction( + $announce->getActorId(), $announce->getObjectId(), Announce::TYPE + ); + $this->actionsRequest->delete($announce); + } catch (ActionDoesNotExistException $e) { + } + + try { + if ($announce->hasActor()) { + $actor = $announce->getActor(); + } else { + $actor = $this->cacheActorService->getFromId($announce->getActorId()); + } + + $post = $this->streamRequest->getStreamById($announce->getObjectId()); + $this->updateDetails($post); + $this->cancelNotification($post, $actor); + } catch (Exception $e) { + } + } + + + /** * @param Stream $post */ private function updateDetails(Stream $post) { @@ -323,7 +353,7 @@ class AnnounceInterface implements IActivityPubInterface { * @throws ItemUnknownException * @throws SocialAppConfigException */ - private function updateNotification(Stream $post, Person $author) { + private function generateNotification(Stream $post, Person $author) { if (!$post->isLocal()) { return; } @@ -358,5 +388,38 @@ class AnnounceInterface implements IActivityPubInterface { } } + + /** + * @param Stream $post + * @param Person $author + * + * @throws ItemUnknownException + * @throws SocialAppConfigException + */ + private function cancelNotification(Stream $post, Person $author) { + if (!$post->isLocal()) { + return; + } + + /** @var SocialAppNotificationInterface $notificationInterface */ + $notificationInterface = + AP::$activityPub->getInterfaceFromType(SocialAppNotification::TYPE); + + try { + $notification = $this->streamRequest->getStreamByObjectId( + $post->getId(), SocialAppNotification::TYPE, Announce::TYPE + ); + + $notification->removeDetail('accounts', $author->getAccount()); + if (empty($notification->getDetails('accounts'))) { + $notificationInterface->delete($notification); + } else { + $notificationInterface->update($notification); + } + } catch (StreamNotFoundException $e) { + } + } + + } diff --git a/lib/Interfaces/Object/LikeInterface.php b/lib/Interfaces/Object/LikeInterface.php index 65579e87..e7747677 100644 --- a/lib/Interfaces/Object/LikeInterface.php +++ b/lib/Interfaces/Object/LikeInterface.php @@ -38,7 +38,7 @@ use OCA\Social\Db\StreamRequest; use OCA\Social\Exceptions\InvalidOriginException; use OCA\Social\Exceptions\ItemNotFoundException; use OCA\Social\Exceptions\ItemUnknownException; -use OCA\Social\Exceptions\LikeDoesNotExistException; +use OCA\Social\Exceptions\ActionDoesNotExistException; use OCA\Social\Exceptions\SocialAppConfigException; use OCA\Social\Exceptions\StreamNotFoundException; use OCA\Social\Interfaces\IActivityPubInterface; @@ -103,7 +103,7 @@ class LikeInterface implements IActivityPubInterface { try { $this->actionsRequest->getAction($like->getActorId(), $like->getObjectId(), Like::TYPE); - } catch (LikeDoesNotExistException $e) { + } catch (ActionDoesNotExistException $e) { $this->actionsRequest->save($like); try { @@ -113,14 +113,9 @@ class LikeInterface implements IActivityPubInterface { $actor = $this->cacheActorService->getFromId($like->getActorId()); } - try { - $post = $this->streamRequest->getStreamById($like->getObjectId()); - $this->updateDetails($post); - $this->generateNotification($post, $actor); - } catch (StreamNotFoundException $e) { - return; // should not happens. - } - + $post = $this->streamRequest->getStreamById($like->getObjectId()); + $this->updateDetails($post); + $this->generateNotification($post, $actor); } catch (Exception $e) { } } @@ -128,6 +123,23 @@ class LikeInterface implements IActivityPubInterface { /** + * @param ACore $activity + * @param ACore $like + * + * @throws InvalidOriginException + */ + public function activity(ACore $activity, ACore $like) { + /** @var Like $like */ + if ($activity->getType() === Undo::TYPE) { + $activity->checkOrigin($like->getId()); + $activity->checkOrigin($like->getActorId()); + + $this->undoLike($like); + } + } + + + /** * @param ACore $item */ public function processResult(ACore $item) { @@ -175,17 +187,26 @@ class LikeInterface implements IActivityPubInterface { /** - * @param ACore $activity - * @param ACore $item - * - * @throws InvalidOriginException + * @param Like $like */ - public function activity(ACore $activity, ACore $item) { - /** @var Like $item */ - if ($activity->getType() === Undo::TYPE) { - $activity->checkOrigin($item->getId()); - $activity->checkOrigin($item->getActorId()); - $this->actionsRequest->delete($item); + private function undoLike(Like $like) { + try { + $this->actionsRequest->getAction($like->getActorId(), $like->getObjectId(), Like::TYPE); + $this->actionsRequest->delete($like); + } catch (ActionDoesNotExistException $e) { + } + + try { + if ($like->hasActor()) { + $actor = $like->getActor(); + } else { + $actor = $this->cacheActorService->getFromId($like->getActorId()); + } + + $post = $this->streamRequest->getStreamById($like->getObjectId()); + $this->updateDetails($post); + $this->cancelNotification($post, $actor); + } catch (Exception $e) { } } @@ -247,5 +268,37 @@ class LikeInterface implements IActivityPubInterface { $notificationInterface->save($notification); } } + + + /** + * @param Stream $post + * @param Person $author + * + * @throws ItemUnknownException + * @throws SocialAppConfigException + */ + private function cancelNotification(Stream $post, Person $author) { + if (!$post->isLocal()) { + return; + } + + /** @var SocialAppNotificationInterface $notificationInterface */ + $notificationInterface = + AP::$activityPub->getInterfaceFromType(SocialAppNotification::TYPE); + + try { + $notification = $this->streamRequest->getStreamByObjectId( + $post->getId(), SocialAppNotification::TYPE, Like::TYPE + ); + + $notification->removeDetail('accounts', $author->getAccount()); + if (empty($notification->getDetails('accounts'))) { + $notificationInterface->delete($notification); + } else { + $notificationInterface->update($notification); + } + } catch (StreamNotFoundException $e) { + } + } } diff --git a/lib/Traits/TDetails.php b/lib/Traits/TDetails.php index 00a9602e..0135cd38 100644 --- a/lib/Traits/TDetails.php +++ b/lib/Traits/TDetails.php @@ -59,6 +59,7 @@ trait TDetails { $this->details = $details; } + /** * @param string $detail * @param string $value @@ -102,6 +103,20 @@ trait TDetails { /** * @param string $detail + * + * @return array + */ + public function getDetails(string $detail): array { + if (!array_key_exists($detail, $this->details) || !is_array($this->details[$detail])) { + return []; + } + + return $this->details[$detail]; + } + + + /** + * @param string $detail * @param string $value */ public function addDetail(string $detail, string $value) { @@ -149,5 +164,53 @@ trait TDetails { } + /** + * @param string $detail + * @param string $value + */ + public function removeDetail(string $detail, string $value) { + if (!array_key_exists($detail, $this->details) || !is_array($this->details[$detail])) { + return; + } + + $this->details[$detail] = array_diff($this->details[$detail], [$value]); + } + + /** + * @param string $detail + * @param int $value + */ + public function removeDetailInt(string $detail, int $value) { + if (!array_key_exists($detail, $this->details) || !is_array($this->details[$detail])) { + return; + } + + $this->details[$detail] = array_diff($this->details, [$value]); + } + + /** + * @param string $detail + * @param array $value + */ + public function removeDetailArray(string $detail, array $value) { + if (!array_key_exists($detail, $this->details) || !is_array($this->details[$detail])) { + return; + } + + $this->details[$detail] = array_diff($this->details, [$value]); + } + + /** + * @param string $detail + * @param bool $value + */ + public function removeDetailBool(string $detail, bool $value) { + if (!array_key_exists($detail, $this->details) || !is_array($this->details[$detail])) { + return; + } + + $this->details[$detail] = array_diff($this->details, [$value]); + } + } |