streamRequest = $streamRequest; $this->actionsRequest = $actionsRequest; $this->streamQueueService = $streamQueueService; $this->cacheActorService = $cacheActorService; $this->miscService = $miscService; } /** * @throws InvalidOriginException * @throws Exception */ public function processIncomingRequest(ACore $item): void { /** @var ACore $item */ $item->checkOrigin($item->getId()); $item->checkOrigin($item->getActorId()); $this->save($item); } /** * @throws InvalidOriginException * @throws InvalidResourceException * @throws MalformedArrayException * @throws RedundancyLimitException * @throws RequestContentException * @throws RequestNetworkException * @throws RequestResultNotJsonException * @throws RequestResultSizeException * @throws RequestServerException * @throws UnauthorizedFediverseException */ public function activity(Acore $activity, ACore $item): void { /** @var Announce $announce */ $announce = $item; if ($activity->getType() === Undo::TYPE) { $activity->checkOrigin($announce->getId()); $activity->checkOrigin($announce->getActorId()); $this->delete($announce); } } /** * @throws ItemNotFoundException */ public function getItem(ACore $item): ACore { throw new ItemNotFoundException(); } /** * @throws ItemNotFoundException */ public function getItemById(string $id): ACore { throw new ItemNotFoundException(); } /** * @throws Exception */ public function save(ACore $item): void { /** @var Announce $item */ if ($item->hasActor()) { $actor = $item->getActor(); } else { $actor = $this->cacheActorService->getFromId($item->getActorId()); } try { $knownItem = $this->streamRequest->getStreamByObjectId($item->getObjectId(), Announce::TYPE); $knownItem->setAttributedTo($actor->getId()); if (!$knownItem->hasCc($actor->getFollowers())) { $knownItem->addCc($actor->getFollowers()); $this->streamRequest->update($knownItem, true); } } catch (StreamNotFoundException $e) { $objectId = $item->getObjectId(); $item->addCacheItem($objectId); $item->setAttributedTo($item->getActorId()); $this->streamRequest->save($item); $this->streamQueueService->generateStreamQueue( $item->getRequestToken(), StreamQueue::TYPE_CACHE, $item->getId() ); } try { $post = $this->streamRequest->getStreamById($item->getObjectId(), false, ACore::FORMAT_LOCAL); } catch (StreamNotFoundException $e) { return; // should not happen. } try { $this->actionsRequest->getActionFromItem($item); } catch (ActionDoesNotExistException $e) { $this->actionsRequest->save($item); } $this->updateDetails($post); $this->generateNotification($post, $actor); } /** * @throws InvalidOriginException * @throws InvalidResourceException * @throws RedundancyLimitException * @throws RequestContentException * @throws RequestNetworkException * @throws RequestResultNotJsonException * @throws RequestResultSizeException * @throws RequestServerException * @throws UnauthorizedFediverseException * @throws MalformedArrayException */ public function delete(ACore $item): void { try { $knownItem = $this->streamRequest->getStreamByObjectId($item->getObjectId(), Announce::TYPE); if ($item->hasActor()) { $actor = $item->getActor(); } else { $actor = $this->cacheActorService->getFromId($item->getActorId()); } $knownItem->removeCc($actor->getFollowers()); if (empty($knownItem->getCcArray())) { $this->streamRequest->deleteById($knownItem->getId(), Announce::TYPE); } else { $this->streamRequest->update($knownItem, true); } } catch (StreamNotFoundException|ItemUnknownException|SocialAppConfigException $e) { } $this->undoAnnounceAction($item); } public function event(ACore $item, string $source): void { return; /** @var Stream $item */ switch ($source) { // do we still need this ? case 'updateCache': $objectId = $item->getObjectId(); try { $cachedItem = $item->getCache() ->getItem($objectId); } catch (CacheItemNotFoundException $e) { return; } try { if ($item->hasActor()) { $actor = $item->getActor(); } else { $actor = $this->cacheActorService->getFromId($item->getActorId()); } $post = $this->streamRequest->getStreamById( $item->getObjectId(), false, ACore::FORMAT_LOCAL ); $this->updateDetails($post); $this->generateNotification($post, $actor); } catch (Exception $e) { } break; } } private function undoAnnounceAction(ACore $announce): void { try { $this->actionsRequest->getActionFromItem($announce); $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) { } } private function updateDetails(Stream $post): void { $post->setDetailInt( 'boosts', $this->actionsRequest->countActions($post->getId(), Announce::TYPE) ); $this->streamRequest->updateDetails($post); } /** * @throws ItemUnknownException * @throws SocialAppConfigException */ private function generateNotification(Stream $post, Person $author): void { 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->addDetail('accounts', $author->getAccount()); $notificationInterface->update($notification); } catch (StreamNotFoundException $e) { /** @var SocialAppNotification $notification */ $notification = AP::$activityPub->getItemFromType(SocialAppNotification::TYPE); // $notification->setDetail('url', ''); $notification->setDetailItem('post', $post); $notification->addDetail('accounts', $author->getAccount()); $notification->setAttributedTo($author->getId()) ->setSubType(Announce::TYPE) ->setId($post->getId() . '/notification+boost') ->setSummary('{accounts} boosted your post') ->setObjectId($post->getId()) ->setTo($post->getAttributedTo()) ->setLocal(true); $notificationInterface->save($notification); } } /** * @throws ItemUnknownException * @throws SocialAppConfigException */ private function cancelNotification(Stream $post, Person $author): void { 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) { } } }