149 lines
5.1 KiB
PHP
149 lines
5.1 KiB
PHP
<?php
|
|
|
|
// SPDX-FileCopyrightText: 2023 /kbin contributors <https://kbin.pub/>
|
|
//
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Factory\ActivityPub;
|
|
|
|
use App\Entity\Contracts\ActivityPubActivityInterface;
|
|
use App\Entity\EntryComment;
|
|
use App\Markdown\MarkdownConverter;
|
|
use App\Markdown\RenderTarget;
|
|
use App\Service\ActivityPub\ApHttpClient;
|
|
use App\Service\ActivityPub\Wrapper\ImageWrapper;
|
|
use App\Service\ActivityPub\Wrapper\MentionsWrapper;
|
|
use App\Service\ActivityPub\Wrapper\TagsWrapper;
|
|
use App\Service\ActivityPubManager;
|
|
use App\Service\MentionManager;
|
|
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
|
|
|
class EntryCommentNoteFactory
|
|
{
|
|
public function __construct(
|
|
private readonly UrlGeneratorInterface $urlGenerator,
|
|
private readonly GroupFactory $groupFactory,
|
|
private readonly ImageWrapper $imageWrapper,
|
|
private readonly TagsWrapper $tagsWrapper,
|
|
private readonly MentionsWrapper $mentionsWrapper,
|
|
private readonly MentionManager $mentionManager,
|
|
private readonly EntryPageFactory $pageFactory,
|
|
private readonly ApHttpClient $client,
|
|
private readonly ActivityPubManager $activityPubManager,
|
|
private readonly MarkdownConverter $markdownConverter
|
|
) {
|
|
}
|
|
|
|
public function create(EntryComment $comment, bool $context = false): array
|
|
{
|
|
if ($context) {
|
|
$note['@context'] = [
|
|
ActivityPubActivityInterface::CONTEXT_URL,
|
|
ActivityPubActivityInterface::SECURITY_URL,
|
|
PostNoteFactory::getContext(),
|
|
];
|
|
}
|
|
|
|
$tags = $comment->tags ?? [];
|
|
if ('random' !== $comment->magazine->name && !$comment->magazine->apId) { // @todo
|
|
$tags[] = $comment->magazine->name;
|
|
}
|
|
|
|
$note = [
|
|
'type' => 'Note',
|
|
'@context' => [ActivityPubActivityInterface::CONTEXT_URL, ActivityPubActivityInterface::SECURITY_URL],
|
|
'id' => $this->getActivityPubId($comment),
|
|
'attributedTo' => $this->activityPubManager->getActorProfileId($comment->user),
|
|
'inReplyTo' => $this->getReplyTo($comment),
|
|
'to' => [
|
|
ActivityPubActivityInterface::PUBLIC_URL,
|
|
],
|
|
'cc' => [
|
|
$this->groupFactory->getActivityPubId($comment->magazine),
|
|
$comment->apId
|
|
? ($this->client->getActorObject($comment->user->apProfileId)['followers']) ?? []
|
|
: $this->urlGenerator->generate(
|
|
'ap_user_followers',
|
|
['username' => $comment->user->username],
|
|
UrlGeneratorInterface::ABSOLUTE_URL
|
|
),
|
|
],
|
|
'content' => $this->markdownConverter->convertToHtml($comment->body, [MarkdownConverter::RENDER_TARGET => RenderTarget::ActivityPub]),
|
|
'mediaType' => 'text/html',
|
|
'url' => $this->getActivityPubId($comment),
|
|
'tag' => array_merge(
|
|
$this->tagsWrapper->build($tags),
|
|
$this->mentionsWrapper->build($comment->mentions ?? [], $comment->body)
|
|
),
|
|
'published' => $comment->createdAt->format(DATE_ATOM),
|
|
];
|
|
|
|
$note['contentMap'] = [
|
|
$comment->lang => $note['content'],
|
|
];
|
|
|
|
if ($comment->image) {
|
|
$note = $this->imageWrapper->build($note, $comment->image, $comment->getShortTitle());
|
|
}
|
|
|
|
$mentions = [];
|
|
foreach ($comment->mentions ?? [] as $mention) {
|
|
try {
|
|
$mentions[] = $this->activityPubManager->webfinger($mention)->getProfileId();
|
|
} catch (\Exception $e) {
|
|
continue;
|
|
}
|
|
}
|
|
|
|
$note['to'] = array_values(
|
|
array_unique(
|
|
array_merge(
|
|
$note['to'],
|
|
$mentions,
|
|
$this->activityPubManager->createCcFromBody($comment->body),
|
|
[$this->getReplyToAuthor($comment)],
|
|
)
|
|
)
|
|
);
|
|
|
|
return $note;
|
|
}
|
|
|
|
public function getActivityPubId(EntryComment $comment): string
|
|
{
|
|
if ($comment->apId) {
|
|
return $comment->apId;
|
|
}
|
|
|
|
return $this->urlGenerator->generate(
|
|
'ap_entry_comment',
|
|
[
|
|
'magazine_name' => $comment->magazine->name,
|
|
'entry_id' => $comment->entry->getId(),
|
|
'comment_id' => $comment->getId(),
|
|
],
|
|
UrlGeneratorInterface::ABSOLUTE_URL
|
|
);
|
|
}
|
|
|
|
private function getReplyTo(EntryComment $comment): string
|
|
{
|
|
if ($comment->apId) {
|
|
return $comment->apId;
|
|
}
|
|
|
|
return $comment->parent ? $this->getActivityPubId($comment->parent) : $this->pageFactory->getActivityPubId(
|
|
$comment->entry
|
|
);
|
|
}
|
|
|
|
private function getReplyToAuthor(EntryComment $comment): string
|
|
{
|
|
return $comment->parent
|
|
? $this->activityPubManager->getActorProfileId($comment->parent->user)
|
|
: $this->activityPubManager->getActorProfileId($comment->entry->user);
|
|
}
|
|
}
|