summaryrefslogtreecommitdiffstats
path: root/lib/Service/FollowService.php
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Service/FollowService.php')
-rw-r--r--lib/Service/FollowService.php157
1 files changed, 95 insertions, 62 deletions
diff --git a/lib/Service/FollowService.php b/lib/Service/FollowService.php
index 47e1ce59..ee295e45 100644
--- a/lib/Service/FollowService.php
+++ b/lib/Service/FollowService.php
@@ -30,79 +30,118 @@ declare(strict_types=1);
namespace OCA\Social\Service;
-use OCA\Social\Tools\Exceptions\MalformedArrayException;
-use OCA\Social\Tools\Traits\TArrayTools;
+use ActivityPhp\Type;
use OCA\Social\AP;
-use OCA\Social\Db\FollowsRequest;
-use OCA\Social\Exceptions\CacheActorDoesNotExistException;
-use OCA\Social\Exceptions\FollowNotFoundException;
-use OCA\Social\Exceptions\FollowSameAccountException;
-use OCA\Social\Exceptions\InvalidOriginException;
-use OCA\Social\Exceptions\InvalidResourceException;
-use OCA\Social\Exceptions\ItemUnknownException;
-use OCA\Social\Exceptions\RedundancyLimitException;
-use OCA\Social\Tools\Exceptions\RequestContentException;
-use OCA\Social\Tools\Exceptions\RequestNetworkException;
-use OCA\Social\Tools\Exceptions\RequestResultNotJsonException;
-use OCA\Social\Tools\Exceptions\RequestResultSizeException;
-use OCA\Social\Tools\Exceptions\RequestServerException;
-use OCA\Social\Exceptions\RetrieveAccountFormatException;
-use OCA\Social\Exceptions\SocialAppConfigException;
-use OCA\Social\Exceptions\UnauthorizedFediverseException;
-use OCA\Social\Exceptions\UrlCloudException;
-use OCA\Social\Model\ActivityPub\Activity\Undo;
-use OCA\Social\Model\ActivityPub\Actor\Person;
-use OCA\Social\Model\ActivityPub\Object\Follow;
-use OCA\Social\Model\ActivityPub\OrderedCollection;
-use OCA\Social\Model\InstancePath;
+use OCA\Social\Entity\Account;
+use OCA\Social\Entity\Follow;
+use OCA\Social\Entity\FollowRequest;
+use OCA\Social\Service\Feed\FeedManager;
+use OCP\DB\ORM\IEntityManager;
+use OCP\DB\ORM\IEntityRepository;
+
+class FollowOption {
+ /**
+ * Show reblog of the account
+ */
+ public bool $showReblogs = true;
-class FollowService {
- use TArrayTools;
+ /**
+ * Notify about new posts
+ */
+ public bool $notify = false;
+ static public function default(): self {
+ return new FollowOption();
+ }
+}
- private FollowsRequest $followsRequest;
+class FollowService {
+ private IEntityManager $entityManager;
+ /** @var IEntityRepository<Follow> $followRepository */
+ private IEntityRepository $followRepository;
+ /** @var IEntityRepository<FollowRequest> $followRepository */
+ private IEntityRepository $followRequestRepository;
+ private FeedManager $feedManager;
+
+ public function __construct(IEntityManager $entityManager, FeedManager $feedManager) {
+ $this->entityManager = $entityManager;
+ $this->followRepository = $entityManager->getRepository(Follow::class);
+ $this->followRepository = $entityManager->getRepository(FollowRequest::class);
+ $this->feedManager = $feedManager;
+ }
- private ActivityService $activityService;
+ public function follow(Account $sourceAccount, Account $targetAccount, FollowOption $option): void {
+ if ($sourceAccount->following($targetAccount)) {
+ $this->updateFollow($sourceAccount, $targetAccount, $option->notify, $option->showReblogs);
+ return;
+ } elseif ($sourceAccount->followRequested($targetAccount)) {
+ $this->updateFollowRequest($sourceAccount, $targetAccount, $option->notify, $option->showReblogs);
+ return;
+ }
- private CacheActorService $cacheActorService;
+ if ($targetAccount->isLocked() || !$targetAccount->isLocal()) {
+ $this->requestFollow($sourceAccount, $targetAccount);
+ } else {
+ $this->directFollow($sourceAccount, $targetAccount);
+ }
+ }
- private ConfigService $configService;
+ private function updateFollow(Account $sourceAccount, Account $targetAccount, bool $notify, bool $showReblogs): void {
+ /** @var Follow $follow */
+ $follow = $this->followRepository->findOneBy([
+ 'account' => $sourceAccount,
+ 'targetAccount' => $targetAccount,
+ ]);
+ assert($follow);
+
+ $follow->setNotify($notify);
+ $follow->setShowReblogs($showReblogs);
+ $this->entityManager->persist($follow);
+ $this->entityManager->flush();
+ }
- private MiscService $miscService;
+ private function updateFollowRequest(Account $sourceAccount, Account $targetAccount, bool $notify, bool $showReblogs): void {
+ /** @var Follow $follow */
+ $followRequest = $this->followRequestRepository->findOneBy([
+ 'account' => $sourceAccount,
+ 'targetAccount' => $targetAccount,
+ ]);
+ assert($followRequest);
+
+ $followRequest->setNotify($notify);
+ $followRequest->setShowReblogs($showReblogs);
+ $this->entityManager->persist($followRequest);
+ $this->entityManager->flush();
+ }
+ private function directFollow(Account $sourceAccount, Account $targetAccount): Follow {
+ $follow = $sourceAccount->follow($targetAccount);
+ $this->entityManager->persist($sourceAccount);
- private ?Person $viewer = null;
+ // TODO Notify target account they got a new follower
+ $this->feedManager->mergeIntoHome($targetAccount, $sourceAccount);
- /**
- * FollowService constructor.
- *
- * @param FollowsRequest $followsRequest
- * @param ActivityService $activityService
- * @param CacheActorService $cacheActorService
- * @param ConfigService $configService
- * @param MiscService $miscService
- */
- public function __construct(
- FollowsRequest $followsRequest, ActivityService $activityService,
- CacheActorService $cacheActorService, ConfigService $configService, MiscService $miscService
- ) {
- $this->followsRequest = $followsRequest;
- $this->activityService = $activityService;
- $this->cacheActorService = $cacheActorService;
- $this->configService = $configService;
- $this->miscService = $miscService;
+ return $follow;
}
+ private function requestFollow(Account $sourceAccount, Account $targetAccount) {
+ if ($targetAccount->isLocal()) {
+ // Just create an internal follow request
- /**
- * @param Person $viewer
- */
- public function setViewer(Person $viewer) {
- $this->viewer = $viewer;
- $this->followsRequest->setViewer($viewer);
+ } else {
+ $this->createRemoteFollowRequest($sourceAccount, $targetAccount);
+ }
}
+ private function createRemoteFollowRequest(Account $sourceAccount, Account $targetAccount): void {
+ /** @var Type\Extended\Activity\Follow $follow */
+ $follow = Type::create('Follow', [
+ '@context' => 'https://www.w3.org/ns/activitystreams',
+ 'actor' => $sourceAccount->getUri(),
+ 'object' => $targetAccount->getUri(),
+ ]);
+ }
/**
* @param Person $actor
@@ -131,12 +170,6 @@ class FollowService {
throw new FollowSameAccountException("Don't follow yourself, be your own lead");
}
- /** @var Follow $follow */
- $follow = AP::$activityPub->getItemFromType(Follow::TYPE);
- $follow->generateUniqueId();
- $follow->setActorId($actor->getId());
- $follow->setObjectId($remoteActor->getId());
- $follow->setFollowId($remoteActor->getFollowers());
try {
$this->followsRequest->getByPersons($actor->getId(), $remoteActor->getId());