diff --git a/plugins/ActivityStreamsTwo/ActivityStreamsTwo.php b/plugins/ActivityStreamsTwo/ActivityStreamsTwo.php index 3e35c70d8a..4a702fd93c 100644 --- a/plugins/ActivityStreamsTwo/ActivityStreamsTwo.php +++ b/plugins/ActivityStreamsTwo/ActivityStreamsTwo.php @@ -47,13 +47,16 @@ class ActivityStreamsTwo extends Plugin case 'note_view': $response = NoteResponse::handle($vars['note']); return Event::stop; - case 'actor_favourites': + case 'actor_favourites_id': + case 'actor_favourites_nickname': $response = LikeResponse::handle($vars['actor']); return Event::stop; - case 'actor_subscriptions': + case 'actor_subscriptions_id': + case 'actor_subscriptions_nickname': $response = FollowingResponse::handle($vars['actor']); return Event::stop; - case 'actor_subscribers': + case 'actor_subscribers_id': + case 'actor_subscribers_nickname': $response = FollowersResponse::handle($vars['actor']); return Event::stop; default: diff --git a/plugins/ActivityStreamsTwo/Util/Model/AS2ToEntity/AS2ToEntity.php b/plugins/ActivityStreamsTwo/Util/Model/AS2ToEntity/AS2ToEntity.php index bc9f47f011..fffbbdcd10 100644 --- a/plugins/ActivityStreamsTwo/Util/Model/AS2ToEntity/AS2ToEntity.php +++ b/plugins/ActivityStreamsTwo/Util/Model/AS2ToEntity/AS2ToEntity.php @@ -11,10 +11,10 @@ abstract class AS2ToEntity * * @return Entity */ - public static function translate(array $activity): Entity + public static function translate(array $activity, ?string $source = null): Entity { return match ($activity['type']) { - 'Note' => AS2ToNote::translate($activity), + 'Note' => AS2ToNote::translate($activity, $source), default => Entity::create($activity), }; } diff --git a/plugins/ActivityStreamsTwo/Util/Model/AS2ToEntity/AS2ToGSActor.php b/plugins/ActivityStreamsTwo/Util/Model/AS2ToEntity/AS2ToGSActor.php new file mode 100644 index 0000000000..89f06687be --- /dev/null +++ b/plugins/ActivityStreamsTwo/Util/Model/AS2ToEntity/AS2ToGSActor.php @@ -0,0 +1,48 @@ + false, + 'created' => new DateTime($args['published'] ?? 'now'), + 'content' => $args['content'] ?? null, + 'content_type' => 'text/html', + 'rendered' => null, + 'modified' => new DateTime(), + 'source' => $source, + ]; + if ($map['content'] !== null) { + Event::handle('RenderNoteContent', [ + $map['content'], + $map['content_type'], + &$map['rendered'], + Actor::getFromId(1), // just for testing + null, // reply to + ]); + } + + $obj = new Note(); + foreach ($map as $prop => $val) { + $set = Formatting::snakeCaseToCamelCase("set_{$prop}"); + $obj->{$set}($val); + } + return $obj; + } +} \ No newline at end of file diff --git a/plugins/ActivityStreamsTwo/Util/Model/AS2ToEntity/AS2ToNote.php b/plugins/ActivityStreamsTwo/Util/Model/AS2ToEntity/AS2ToNote.php index 4a06fc96a9..69732f1bad 100644 --- a/plugins/ActivityStreamsTwo/Util/Model/AS2ToEntity/AS2ToNote.php +++ b/plugins/ActivityStreamsTwo/Util/Model/AS2ToEntity/AS2ToNote.php @@ -2,8 +2,10 @@ namespace Plugin\ActivityStreamsTwo\Util\Model\AS2ToEntity; -use App\Core\Security; +use App\Core\Event; +use App\Entity\Actor; use App\Entity\Note; +use App\Util\Formatting; use DateTime; abstract class AS2ToNote @@ -15,21 +17,30 @@ abstract class AS2ToNote * * @return Note */ - public static function translate(array $args): Note + public static function translate(array $args, ?string $source = null): Note { $map = [ - 'isLocal' => false, - 'created' => new DateTime($args['published'] ?? 'now'), - 'rendered' => $args['content'] ?? null, - 'modified' => new DateTime(), + 'isLocal' => false, + 'created' => new DateTime($args['published'] ?? 'now'), + 'content' => $args['content'] ?? null, + 'content_type' => 'text/html', + 'rendered' => null, + 'modified' => new DateTime(), + 'source' => $source, ]; - if (!is_null($map['rendered'])) { - $map['content'] = Security::sanitize($map['rendered']); + if ($map['content'] !== null) { + Event::handle('RenderNoteContent', [ + $map['content'], + $map['content_type'], + &$map['rendered'], + Actor::getFromId(1), // just for testing + null, // reply to + ]); } $obj = new Note(); foreach ($map as $prop => $val) { - $set = "set{$prop}"; + $set = Formatting::snakeCaseToCamelCase("set_{$prop}"); $obj->{$set}($val); } return $obj; diff --git a/plugins/ActivityStreamsTwo/Util/Model/EntityToType/GSActorToType.php b/plugins/ActivityStreamsTwo/Util/Model/EntityToType/GSActorToType.php index 9f1fd34693..39b00bfedf 100644 --- a/plugins/ActivityStreamsTwo/Util/Model/EntityToType/GSActorToType.php +++ b/plugins/ActivityStreamsTwo/Util/Model/EntityToType/GSActorToType.php @@ -4,6 +4,8 @@ namespace Plugin\ActivityStreamsTwo\Util\Model\EntityToType; use App\Core\Router\Router; use App\Entity\Actor; +use Component\Avatar\Avatar; +use Component\Avatar\Exception\NoAvatarException; use DateTimeInterface; use Exception; use Plugin\ActivityStreamsTwo\Util\Type; @@ -22,13 +24,13 @@ class GSActorToType { $uri = Router::url('actor_view_id', ['id' => $gsactor->getId()], Router::ABSOLUTE_URL); $attr = [ - '@context' => 'https://www.w3.org/ns/activitystreams', - 'id' => $uri, - //'inbox' => - //'outbox' => - //'following' => - //'followers' => - //'liked' => + '@context' => 'https://www.w3.org/ns/activitystreams', + 'id' => $uri, + 'inbox' => Router::url('activitypub_actor_inbox', ['gsactor_id' => $gsactor->getId()], Router::ABSOLUTE_URL), + 'outbox' => Router::url('activitypub_actor_outbox', ['gsactor_id' => $gsactor->getId()], Router::ABSOLUTE_URL), + 'following' => Router::url('actor_subscriptions_id', ['id' => $gsactor->getId()], Router::ABSOLUTE_URL), + 'followers' => Router::url('actor_subscribers_id', ['id' => $gsactor->getId()], Router::ABSOLUTE_URL), + 'liked' => Router::url('actor_favourites_id', ['id' => $gsactor->getId()], Router::ABSOLUTE_URL), //'streams' => 'preferredUsername' => $gsactor->getNickname(), //'publicKey' => [ @@ -36,15 +38,20 @@ class GSActorToType // 'owner' => $uri, // 'publicKeyPem' => $public_key // ], - 'name' => $gsactor->getFullname(), - //'icon' => - //'location' => + 'name' => $gsactor->getFullname(), + 'location' => $gsactor->getLocation(), 'published' => $gsactor->getCreated()->format(DateTimeInterface::RFC3339), 'summary' => $gsactor->getBio(), - //'tag' => + //'tag' => $gsactor->getSelfTags(), 'updated' => $gsactor->getModified()->format(DateTimeInterface::RFC3339), 'url' => Router::url('actor_view_nickname', ['nickname' => $gsactor->getNickname()], Router::ABSOLUTE_URL), ]; + try { + $attr['icon'] = Avatar::getAvatar($gsactor->getId())->getUrl(type: Router::ABSOLUTE_URL); + } catch (NoAvatarException) { + // No icon for this actor + } + return Type::create(type: 'Person', attributes: $attr); } } diff --git a/plugins/ActivityStreamsTwo/Util/Model/EntityToType/NoteToType.php b/plugins/ActivityStreamsTwo/Util/Model/EntityToType/NoteToType.php index 26d14cc4f1..61458ea6a3 100644 --- a/plugins/ActivityStreamsTwo/Util/Model/EntityToType/NoteToType.php +++ b/plugins/ActivityStreamsTwo/Util/Model/EntityToType/NoteToType.php @@ -19,13 +19,13 @@ class NoteToType public static function translate(Note $note) { $attr = [ - '@context' => 'https://www.w3.org/ns/activitystreams', - 'id' => Router::url('note_view', ['id' => $note->getId()], Router::ABSOLUTE_URL), - 'published' => $note->getCreated()->format(DateTimeInterface::RFC3339), - //'attributedTo' => Router::url('actor', ['id' => $note->getGSActorId()]), + '@context' => 'https://www.w3.org/ns/activitystreams', + 'id' => Router::url('note_view', ['id' => $note->getId()], Router::ABSOLUTE_URL), + 'published' => $note->getCreated()->format(DateTimeInterface::RFC3339), + 'attributedTo' => Router::url('actor_view_id', ['id' => $note->getActorId()], Router::ABSOLUTE_URL), //'to' => $to, //'cc' => $cc, - 'content' => json_encode($note->getContent()), // change to rendered + 'content' => json_encode($note->getRendered()), //'tag' => $tags ]; return Type::create(type: 'Note', attributes: $attr); diff --git a/plugins/Favourite/Favourite.php b/plugins/Favourite/Favourite.php index 4811d49890..d412c5917b 100644 --- a/plugins/Favourite/Favourite.php +++ b/plugins/Favourite/Favourite.php @@ -125,8 +125,8 @@ class Favourite extends NoteHandlerPlugin { $r->connect(id: 'actor_favourites_id', uri_path: '/actor/{id<\d+>}/favourites', target: [Controller\Favourite::class, 'favouritesByActorId']); $r->connect(id: 'actor_reverse_favourites_id', uri_path: '/actor/{id<\d+>}/reverse_favourites', target: [Controller\Favourite::class, 'reverseFavouritesByActorId']); - $r->connect('actor_favourites_nickname', '/@{nickname<' . Nickname::DISPLAY_FMT . '>}/favourites', [Controller\Favourite::class, 'favouritesByActorNickname']); - $r->connect('actor_reverse_favourites_nickname', '/@{nickname<' . Nickname::DISPLAY_FMT . '>}/reverse_favourites', [Controller\Favourite::class, 'reverseFavouritesByActorNickname']); + $r->connect(id:'actor_favourites_nickname', uri_path: '/@{nickname<' . Nickname::DISPLAY_FMT . '>}/favourites', target: [Controller\Favourite::class, 'favouritesByActorNickname']); + $r->connect(id: 'actor_reverse_favourites_nickname', uri_path: '/@{nickname<' . Nickname::DISPLAY_FMT . '>}/reverse_favourites', target: [Controller\Favourite::class, 'reverseFavouritesByActorNickname']); return Event::next; } }