forked from GNUsocial/gnu-social
Compare commits
71 Commits
v3
...
experiment
Author | SHA1 | Date | |
---|---|---|---|
539104ec33
|
|||
74ffd261b8
|
|||
ca9945a4be
|
|||
08587b6942
|
|||
1664293cf7
|
|||
94ab4ce8c4
|
|||
dd70de20da
|
|||
ded9c86054
|
|||
20e07c9140
|
|||
4e2f6545ec
|
|||
f6a8f44420
|
|||
fd71d6ee7d
|
|||
dfc5918c2c
|
|||
83599ef866
|
|||
fa82306f6f
|
|||
10f71e9fed
|
|||
e2501ee927
|
|||
a9665177ea
|
|||
41861d284c
|
|||
bd868a2675
|
|||
87e35716c1
|
|||
dac94f53cd
|
|||
b10c359dec
|
|||
483983790a
|
|||
60af9f5e9b
|
|||
abe35428da
|
|||
ca5520edbf
|
|||
e3e14c53ef
|
|||
be33c20614
|
|||
7305a725cb
|
|||
fd4c3b0e68
|
|||
16f51e5143
|
|||
ba4230447e
|
|||
7463044971
|
|||
7027633ed5
|
|||
48b42c539c
|
|||
d41a67a9f9
|
|||
13f22c911c
|
|||
56b8710b26
|
|||
e63c310d70
|
|||
03f449035a
|
|||
8808195a80
|
|||
45344c80d1
|
|||
7eddbd343d
|
|||
259d2da05a
|
|||
2f7fdf6ee4
|
|||
6955872e05
|
|||
23e88b30a6
|
|||
60713878f0
|
|||
06c67b31c2
|
|||
a08b661779
|
|||
0649a5154c
|
|||
91fecd77ba
|
|||
e22fe55bbe
|
|||
dd62825169
|
|||
27706d63f4
|
|||
20f690c532
|
|||
888c3798b7
|
|||
e1cceac150
|
|||
63ef9292f3
|
|||
cbae649991
|
|||
1d8bba3949
|
|||
18864ca9fa
|
|||
390c532456
|
|||
636cb681d6
|
|||
7d84323df4
|
|||
2d7850ccfb
|
|||
d8108dbc32
|
|||
cf05d3dbb0
|
|||
eb3c848fc8
|
|||
5c708af272
|
@@ -3,4 +3,4 @@ KERNEL_CLASS='App\Kernel'
|
||||
APP_SECRET='$ecretf0rt3st'
|
||||
SYMFONY_DEPRECATIONS_HELPER=999999
|
||||
PANTHER_APP_ENV=panther
|
||||
DATABASE_URL=postgresql://postgres:password@db:5432/social
|
||||
DATABASE_URL=postgresql://postgres:password@db:5432/test
|
||||
|
@@ -22,10 +22,10 @@ declare(strict_types = 1);
|
||||
namespace Component\Attachment;
|
||||
|
||||
use App\Core\Cache;
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\DB;
|
||||
use App\Core\Event;
|
||||
use App\Core\Modules\Component;
|
||||
use App\Core\Router\RouteLoader;
|
||||
use App\Core\Router;
|
||||
use App\Entity\Actor;
|
||||
use App\Entity\Note;
|
||||
use App\Util\Formatting;
|
||||
@@ -37,7 +37,7 @@ use Doctrine\ORM\QueryBuilder;
|
||||
|
||||
class Attachment extends Component
|
||||
{
|
||||
public function onAddRoute(RouteLoader $r): bool
|
||||
public function onAddRoute(Router $r): bool
|
||||
{
|
||||
$r->connect('note_attachment_show', '/object/note/{note_id<\d+>}/attachment/{attachment_id<\d+>}', [C\Attachment::class, 'attachmentShowWithNote']);
|
||||
$r->connect('note_attachment_view', '/object/note/{note_id<\d+>}/attachment/{attachment_id<\d+>}/view', [C\Attachment::class, 'attachmentViewWithNote']);
|
||||
|
@@ -24,7 +24,7 @@ declare(strict_types = 1);
|
||||
namespace Component\Attachment\Controller;
|
||||
|
||||
use App\Core\Controller;
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\DB;
|
||||
use App\Core\Event;
|
||||
use App\Core\GSFile;
|
||||
use function App\Core\I18n\_m;
|
||||
|
@@ -21,7 +21,7 @@ declare(strict_types = 1);
|
||||
|
||||
namespace Component\Attachment\Entity;
|
||||
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\DB;
|
||||
use App\Core\Entity;
|
||||
use DateTimeInterface;
|
||||
|
||||
|
@@ -24,13 +24,13 @@ declare(strict_types = 1);
|
||||
namespace Component\Attachment\Entity;
|
||||
|
||||
use App\Core\Cache;
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\DB;
|
||||
use App\Core\Entity;
|
||||
use App\Core\Event;
|
||||
use App\Core\GSFile;
|
||||
use function App\Core\I18n\_m;
|
||||
use App\Core\Log;
|
||||
use App\Core\Router\Router;
|
||||
use App\Core\Router;
|
||||
use App\Entity\Note;
|
||||
use App\Util\Common;
|
||||
use App\Util\Exception\ClientException;
|
||||
|
@@ -24,12 +24,12 @@ declare(strict_types = 1);
|
||||
namespace Component\Attachment\Entity;
|
||||
|
||||
use App\Core\Cache;
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\DB;
|
||||
use App\Core\Entity;
|
||||
use App\Core\Event;
|
||||
use App\Core\GSFile;
|
||||
use App\Core\Log;
|
||||
use App\Core\Router\Router;
|
||||
use App\Core\Router;
|
||||
use App\Entity\Note;
|
||||
use App\Util\Common;
|
||||
use App\Util\Exception\ClientException;
|
||||
|
@@ -21,7 +21,7 @@ declare(strict_types = 1);
|
||||
|
||||
namespace Component\Attachment\Entity;
|
||||
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\DB;
|
||||
use App\Core\Entity;
|
||||
use DateTimeInterface;
|
||||
|
||||
|
@@ -21,7 +21,7 @@ declare(strict_types = 1);
|
||||
|
||||
namespace Component\Attachment\Entity;
|
||||
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\DB;
|
||||
use App\Core\Entity;
|
||||
use DateTimeInterface;
|
||||
|
||||
|
@@ -23,7 +23,7 @@ declare(strict_types = 1);
|
||||
|
||||
namespace Component\Attachment\tests\Controller;
|
||||
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\DB;
|
||||
use App\Util\GNUsocialTestCase;
|
||||
use Component\Attachment\Entity\Attachment;
|
||||
use Component\Attachment\Entity\AttachmentToNote;
|
||||
|
@@ -21,10 +21,10 @@ declare(strict_types = 1);
|
||||
|
||||
namespace Component\Attachment\tests\Entity;
|
||||
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\DB;
|
||||
use App\Core\Event;
|
||||
use App\Core\GSFile;
|
||||
use App\Core\Router\Router;
|
||||
use App\Core\Router;
|
||||
use App\Entity\Note;
|
||||
use App\Util\GNUsocialTestCase;
|
||||
use App\Util\TemporaryFile;
|
||||
@@ -107,7 +107,7 @@ class AttachmentTest extends GNUsocialTestCase
|
||||
static::assertSame('Untitled attachment', $attachment->getBestTitle());
|
||||
$attachment->setFilename($filename);
|
||||
|
||||
$actor = DB::findOneBy('actor', ['nickname' => 'taken_user']);
|
||||
$actor = DB::findOneBy('actor', ['nickname' => 'taken_user']);
|
||||
DB::persist($note = Note::create(['actor_id' => $actor->getId(), 'content' => 'attachment: some content', 'content_type' => 'text/plain', 'is_local' => true]));
|
||||
Conversation::assignLocalConversation($note, null);
|
||||
DB::persist(AttachmentToNote::create(['attachment_id' => $attachment->getId(), 'note_id' => $note->getId(), 'title' => 'A title']));
|
||||
|
@@ -21,7 +21,7 @@ declare(strict_types = 1);
|
||||
|
||||
namespace Component\Attachment\tests\Entity;
|
||||
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\DB;
|
||||
use App\Core\Event;
|
||||
use App\Util\Exception\NotStoredLocallyException;
|
||||
use App\Util\GNUsocialTestCase;
|
||||
|
@@ -22,12 +22,11 @@ declare(strict_types = 1);
|
||||
namespace Component\Avatar;
|
||||
|
||||
use App\Core\Cache;
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\DB;
|
||||
use App\Core\Event;
|
||||
use App\Core\GSFile;
|
||||
use App\Core\Modules\Component;
|
||||
use App\Core\Router\RouteLoader;
|
||||
use App\Core\Router\Router;
|
||||
use App\Core\Router;
|
||||
use App\Util\Common;
|
||||
use Component\Attachment\Entity\Attachment;
|
||||
use Component\Attachment\Entity\AttachmentThumbnail;
|
||||
@@ -41,7 +40,7 @@ class Avatar extends Component
|
||||
{
|
||||
}
|
||||
|
||||
public function onAddRoute(RouteLoader $r): bool
|
||||
public function onAddRoute(Router $r): bool
|
||||
{
|
||||
$r->connect('avatar_actor', '/actor/{actor_id<\d+>}/avatar/{size<full|big|medium|small>?medium}', [Controller\Avatar::class, 'avatar_view']);
|
||||
$r->connect('avatar_default', '/avatar/default/{size<full|big|medium|small>?medium}', [Controller\Avatar::class, 'default_avatar_view']);
|
||||
|
@@ -24,7 +24,7 @@ declare(strict_types = 1);
|
||||
namespace Component\Avatar\Controller;
|
||||
|
||||
use App\Core\Controller;
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\DB;
|
||||
use App\Core\Event;
|
||||
use App\Core\Form;
|
||||
use App\Core\GSFile;
|
||||
|
@@ -24,10 +24,10 @@ declare(strict_types = 1);
|
||||
namespace Component\Avatar\Entity;
|
||||
|
||||
use App\Core\Cache;
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\DB;
|
||||
use App\Core\Entity;
|
||||
use App\Core\Event;
|
||||
use App\Core\Router\Router;
|
||||
use App\Core\Router;
|
||||
use App\Util\Common;
|
||||
use Component\Attachment\Entity\Attachment;
|
||||
use Component\Attachment\Entity\AttachmentThumbnail;
|
||||
|
@@ -24,16 +24,14 @@ declare(strict_types = 1);
|
||||
namespace Component\Circle;
|
||||
|
||||
use App\Core\Cache;
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\DB;
|
||||
use App\Core\Event;
|
||||
use function App\Core\I18n\_m;
|
||||
use App\Core\Modules\Component;
|
||||
use App\Core\Router\RouteLoader;
|
||||
use App\Core\Router\Router;
|
||||
use App\Core\Router;
|
||||
use App\Entity\Actor;
|
||||
use App\Entity\Feed;
|
||||
use App\Entity\LocalUser;
|
||||
use App\Util\Common;
|
||||
use App\Util\Nickname;
|
||||
use Component\Circle\Controller as CircleController;
|
||||
use Component\Circle\Entity\ActorCircle;
|
||||
@@ -60,7 +58,7 @@ class Circle extends Component
|
||||
protected const SLUG = 'circle';
|
||||
protected const PLURAL_SLUG = 'circles';
|
||||
|
||||
public function onAddRoute(RouteLoader $r): bool
|
||||
public function onAddRoute(Router $r): bool
|
||||
{
|
||||
$r->connect('actor_circle_view_by_circle_id', '/circle/{circle_id<\d+>}', [CircleController\Circle::class, 'circleById']);
|
||||
// View circle members by (tagger id or nickname) and tag
|
||||
@@ -99,10 +97,10 @@ class Circle extends Component
|
||||
{
|
||||
if ($section === 'profile' && \in_array($request->get('_route'), ['person_actor_settings', 'group_actor_settings'])) {
|
||||
$tabs[] = [
|
||||
'title' => 'Self tags',
|
||||
'desc' => 'Add or remove tags on yourself',
|
||||
'title' => _m('Self tags'),
|
||||
'desc' => _m('Add or remove tags to this actor'),
|
||||
'id' => 'settings-self-tags',
|
||||
'controller' => CircleController\SelfTagsSettings::settingsSelfTags($request, Common::actor(), 'settings-self-tags-details'),
|
||||
'controller' => CircleController\SelfTagsSettings::settingsSelfTags($request, Actor::getById((int) $request->get('id')), 'settings-self-tags-details'),
|
||||
];
|
||||
}
|
||||
return Event::next;
|
||||
|
@@ -24,8 +24,8 @@ declare(strict_types = 1);
|
||||
namespace Component\Circle\Controller;
|
||||
|
||||
use App\Core\Cache;
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\Router\Router;
|
||||
use App\Core\DB;
|
||||
use App\Core\Router;
|
||||
use App\Entity\Actor;
|
||||
use App\Entity\LocalUser;
|
||||
use Component\Circle\Entity\ActorCircle;
|
||||
|
@@ -6,7 +6,7 @@ namespace Component\Circle\Controller;
|
||||
|
||||
use App\Core\Cache;
|
||||
use App\Core\Controller;
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\DB;
|
||||
use function App\Core\I18n\_m;
|
||||
use App\Entity as E;
|
||||
use App\Util\Common;
|
||||
@@ -45,7 +45,7 @@ class SelfTagsSettings extends Controller
|
||||
foreach ($tags as $tag) {
|
||||
$tag = CompTag::sanitize($tag);
|
||||
|
||||
[$actor_tag, $actor_tag_existed] = ActorTag::createOrUpdate([
|
||||
[$actor_tag, $actor_tag_existed] = ActorTag::checkExistingAndCreateOrUpdate([
|
||||
'tagger' => $target->getId(), // self tag means tagger = tagger in ActorTag
|
||||
'tagged' => $target->getId(),
|
||||
'tag' => $tag,
|
||||
|
@@ -22,9 +22,9 @@ declare(strict_types = 1);
|
||||
namespace Component\Circle\Entity;
|
||||
|
||||
use App\Core\Cache;
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\DB;
|
||||
use App\Core\Entity;
|
||||
use App\Core\Router\Router;
|
||||
use App\Core\Router;
|
||||
use DateTimeInterface;
|
||||
|
||||
/**
|
||||
|
@@ -21,9 +21,9 @@ declare(strict_types = 1);
|
||||
|
||||
namespace Component\Circle\Entity;
|
||||
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\DB;
|
||||
use App\Core\Entity;
|
||||
use App\Core\Router\Router;
|
||||
use App\Core\Router;
|
||||
use App\Entity\Actor;
|
||||
use Component\Tag\Tag;
|
||||
use DateTimeInterface;
|
||||
|
@@ -34,7 +34,7 @@ abstract class SelfTagsForm
|
||||
$existing_form = !empty($form_definition) ? Form::create($form_definition) : null;
|
||||
|
||||
$add_form = Form::create([
|
||||
['new-tags', TextType::class, ['label' => ' ', 'data' => [], 'required' => false, 'help' => _m('Tags for yourself (letters, numbers, -, ., and _), comma- or space-separated.'), 'transformer' => ArrayTransformer::class]],
|
||||
['new-tags', TextType::class, ['label' => ' ', 'data' => [], 'required' => false, 'help' => _m('Tags for this actor (letters, numbers, -, ., and _), comma- or space-separated.'), 'transformer' => ArrayTransformer::class]],
|
||||
[$add_form_name = 'new-tags-add', SubmitType::class, ['label' => $add_label]],
|
||||
]);
|
||||
|
||||
|
@@ -4,7 +4,7 @@ declare(strict_types = 1);
|
||||
|
||||
namespace Component\Collection;
|
||||
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\DB;
|
||||
use App\Core\Event;
|
||||
use App\Core\Modules\Component;
|
||||
use App\Entity\Actor;
|
||||
|
@@ -31,7 +31,7 @@ declare(strict_types = 1);
|
||||
|
||||
namespace Component\Collection\Util\Controller;
|
||||
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\DB;
|
||||
use App\Core\Form;
|
||||
use function App\Core\I18n\_m;
|
||||
use App\Entity\LocalUser;
|
||||
|
@@ -31,7 +31,7 @@ declare(strict_types = 1);
|
||||
|
||||
namespace Component\Collection\Util;
|
||||
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\DB;
|
||||
use App\Core\Event;
|
||||
use App\Core\Form;
|
||||
use function App\Core\I18n\_m;
|
||||
@@ -137,7 +137,7 @@ trait MetaCollectionTrait
|
||||
if ($add_form->isSubmitted() && $add_form->isValid()) {
|
||||
$selected = $add_form->getData()['collections'];
|
||||
$removed = array_filter($already_selected, fn ($x) => !\in_array($x, $selected));
|
||||
$added = array_filter($selected, fn ($x) => !\in_array($x, $already_selected));
|
||||
$added = array_filter($selected, fn ($x) => !\in_array($x, $already_selected));
|
||||
if (\count($removed) > 0) {
|
||||
$this->removeItem($user, $vars, $removed, $collections);
|
||||
}
|
||||
|
@@ -28,11 +28,11 @@ declare(strict_types = 1);
|
||||
namespace Component\Conversation\Controller;
|
||||
|
||||
use App\Core\Cache;
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\DB;
|
||||
use App\Core\Form;
|
||||
use function App\Core\I18n\_m;
|
||||
use App\Core\Log;
|
||||
use App\Core\Router\Router;
|
||||
use App\Core\Router;
|
||||
use App\Entity\Note;
|
||||
use App\Util\Common;
|
||||
use App\Util\Exception\ClientException;
|
||||
|
@@ -28,12 +28,11 @@ declare(strict_types = 1);
|
||||
namespace Component\Conversation;
|
||||
|
||||
use App\Core\Cache;
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\DB;
|
||||
use App\Core\Event;
|
||||
use function App\Core\I18n\_m;
|
||||
use App\Core\Modules\Component;
|
||||
use App\Core\Router\RouteLoader;
|
||||
use App\Core\Router\Router;
|
||||
use App\Core\Router;
|
||||
use App\Entity\Activity;
|
||||
use App\Entity\Actor;
|
||||
use App\Entity\Note;
|
||||
@@ -46,7 +45,7 @@ use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
class Conversation extends Component
|
||||
{
|
||||
public function onAddRoute(RouteLoader $r): bool
|
||||
public function onAddRoute(Router $r): bool
|
||||
{
|
||||
$r->connect('conversation', '/conversation/{conversation_id<\d+>}', [Controller\Conversation::class, 'showConversation']);
|
||||
$r->connect('conversation_mute', '/conversation/{conversation_id<\d+>}/mute', [Controller\Conversation::class, 'muteConversation']);
|
||||
@@ -137,28 +136,6 @@ class Conversation extends Component
|
||||
return Event::next;
|
||||
}
|
||||
|
||||
/**
|
||||
* Posting event to add extra information to Component\Posting form data
|
||||
*
|
||||
* @param array $data Transport data to be filled with reply_to_id
|
||||
*
|
||||
* @throws \App\Util\Exception\ClientException
|
||||
* @throws \App\Util\Exception\NoSuchNoteException
|
||||
*
|
||||
* @return bool EventHook
|
||||
*/
|
||||
public function onPostingModifyData(Request $request, Actor $actor, array &$data): bool
|
||||
{
|
||||
$data['reply_to_id'] = $request->get('_route') === 'conversation_reply_to' && $request->query->has('reply_to_id')
|
||||
? $request->query->getInt('reply_to_id')
|
||||
: null;
|
||||
|
||||
if (!\is_null($data['reply_to_id'])) {
|
||||
Note::ensureCanInteract(Note::getById($data['reply_to_id']), $actor);
|
||||
}
|
||||
return Event::next;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append on note information about user actions.
|
||||
*
|
||||
@@ -194,6 +171,22 @@ class Conversation extends Component
|
||||
return Event::next;
|
||||
}
|
||||
|
||||
private function getReplyToIdFromRequest(Request $request): ?int
|
||||
{
|
||||
if (!\is_array($request->get('post_note')) || !\array_key_exists('_next', $request->get('post_note'))) {
|
||||
return null;
|
||||
}
|
||||
$next = parse_url($request->get('post_note')['_next']);
|
||||
if (!\array_key_exists('query', $next)) {
|
||||
return null;
|
||||
}
|
||||
parse_str($next['query'], $query);
|
||||
if (!\array_key_exists('reply_to_id', $query)) {
|
||||
return null;
|
||||
}
|
||||
return (int) $query['reply_to_id'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Informs **\App\Component\Posting::onAppendRightPostingBlock**, of the **current page context** in which the given
|
||||
* Actor is in. This is valuable when posting within a group route, allowing \App\Component\Posting to create a
|
||||
@@ -206,7 +199,7 @@ class Conversation extends Component
|
||||
*/
|
||||
public function onPostingGetContextActor(Request $request, Actor $actor, ?Actor &$context_actor): bool
|
||||
{
|
||||
$to_note_id = $request->query->get('reply_to_id');
|
||||
$to_note_id = $this->getReplyToIdFromRequest($request);
|
||||
if (!\is_null($to_note_id)) {
|
||||
// Getting the actor itself
|
||||
$context_actor = Actor::getById(Note::getById((int) $to_note_id)->getActorId());
|
||||
@@ -215,6 +208,27 @@ class Conversation extends Component
|
||||
return Event::next;
|
||||
}
|
||||
|
||||
/**
|
||||
* Posting event to add extra information to Component\Posting form data
|
||||
*
|
||||
* @param array $data Transport data to be filled with reply_to_id
|
||||
*
|
||||
* @throws \App\Util\Exception\ClientException
|
||||
* @throws \App\Util\Exception\NoSuchNoteException
|
||||
*
|
||||
* @return bool EventHook
|
||||
*/
|
||||
public function onPostingModifyData(Request $request, Actor $actor, array &$data): bool
|
||||
{
|
||||
$to_note_id = $this->getReplyToIdFromRequest($request);
|
||||
if (!\is_null($to_note_id)) {
|
||||
Note::ensureCanInteract(Note::getById($to_note_id), $actor);
|
||||
$data['reply_to_id'] = $to_note_id;
|
||||
}
|
||||
|
||||
return Event::next;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add minimal Note card to RightPanel template
|
||||
*/
|
||||
|
@@ -23,9 +23,9 @@ declare(strict_types = 1);
|
||||
|
||||
namespace Component\Conversation\Entity;
|
||||
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\DB;
|
||||
use App\Core\Entity;
|
||||
use App\Core\Router\Router;
|
||||
use App\Core\Router;
|
||||
|
||||
/**
|
||||
* Entity class for Conversations
|
||||
|
@@ -24,7 +24,7 @@ declare(strict_types = 1);
|
||||
namespace Component\Conversation\Entity;
|
||||
|
||||
use App\Core\Cache;
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\DB;
|
||||
use App\Core\Entity;
|
||||
use App\Entity\Activity;
|
||||
use App\Entity\Actor;
|
||||
|
@@ -25,12 +25,12 @@ namespace Component\Feed;
|
||||
|
||||
use App\Core\Event;
|
||||
use App\Core\Modules\Component;
|
||||
use App\Core\Router\RouteLoader;
|
||||
use App\Core\Router;
|
||||
use Component\Feed\Controller as C;
|
||||
|
||||
class Feed extends Component
|
||||
{
|
||||
public function onAddRoute(RouteLoader $r): bool
|
||||
public function onAddRoute(Router $r): bool
|
||||
{
|
||||
$r->connect('feed_public', '/feed/public', [C\Feeds::class, 'public']);
|
||||
$r->connect('feed_home', '/feed/home', [C\Feeds::class, 'home']);
|
||||
|
@@ -23,7 +23,7 @@ declare(strict_types = 1);
|
||||
|
||||
namespace Component\Feed\tests\Controller;
|
||||
|
||||
use App\Core\Router\Router;
|
||||
use App\Core\Router;
|
||||
use App\Util\GNUsocialTestCase;
|
||||
use Component\Feed\Controller\Feeds;
|
||||
use Jchook\AssertThrows\AssertThrows;
|
||||
|
@@ -34,7 +34,7 @@ declare(strict_types = 1);
|
||||
|
||||
namespace Component\FreeNetwork\Controller;
|
||||
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\DB;
|
||||
use function App\Core\I18n\_m;
|
||||
use App\Util\Common;
|
||||
use Component\Collection\Util\Controller\FeedController;
|
||||
|
@@ -32,7 +32,7 @@ declare(strict_types = 1);
|
||||
|
||||
namespace Component\FreeNetwork\Entity;
|
||||
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\DB;
|
||||
use App\Core\Entity;
|
||||
use App\Entity\Actor;
|
||||
use Component\FreeNetwork\Util\Discovery;
|
||||
|
@@ -21,15 +21,14 @@ declare(strict_types = 1);
|
||||
|
||||
namespace Component\FreeNetwork;
|
||||
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\DB;
|
||||
use App\Core\Event;
|
||||
use App\Core\GSFile;
|
||||
use App\Core\HTTPClient;
|
||||
use function App\Core\I18n\_m;
|
||||
use App\Core\Log;
|
||||
use App\Core\Modules\Component;
|
||||
use App\Core\Router\RouteLoader;
|
||||
use App\Core\Router\Router;
|
||||
use App\Core\Router;
|
||||
use App\Entity\Activity;
|
||||
use App\Entity\Actor;
|
||||
use App\Entity\LocalUser;
|
||||
@@ -86,7 +85,7 @@ class FreeNetwork extends Component
|
||||
return Event::next;
|
||||
}
|
||||
|
||||
public function onAddRoute(RouteLoader $m): bool
|
||||
public function onAddRoute(Router $m): bool
|
||||
{
|
||||
// Feeds
|
||||
$m->connect('feed_network', '/feed/network', [Feeds::class, 'network']);
|
||||
|
@@ -6,7 +6,7 @@ namespace Component\FreeNetwork\Util\WebfingerResource;
|
||||
|
||||
use App\Core\Event;
|
||||
use App\Core\Log;
|
||||
use App\Core\Router\Router;
|
||||
use App\Core\Router;
|
||||
use App\Entity\Actor;
|
||||
use App\Util\Common;
|
||||
use Component\FreeNetwork\Exception\WebfingerReconstructionException;
|
||||
|
@@ -26,7 +26,7 @@ namespace Component\Group\Controller;
|
||||
use App\Core\ActorLocalRoles;
|
||||
use App\Core\Cache;
|
||||
use App\Core\Controller;
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\DB;
|
||||
use App\Core\Form;
|
||||
use function App\Core\I18n\_m;
|
||||
use App\Core\Log;
|
||||
|
@@ -24,10 +24,10 @@ declare(strict_types = 1);
|
||||
namespace Component\Group\Controller;
|
||||
|
||||
use App\Core\Cache;
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\DB;
|
||||
use App\Core\Form;
|
||||
use function App\Core\I18n\_m;
|
||||
use App\Core\Router\Router;
|
||||
use App\Core\Router;
|
||||
use App\Entity\Actor;
|
||||
use App\Entity as E;
|
||||
use App\Util\Common;
|
||||
@@ -80,6 +80,7 @@ class GroupFeed extends FeedController
|
||||
WHERE act.object_type = 'note' AND act.id IN
|
||||
(SELECT att.activity_id FROM \Component\Notification\Entity\Notification AS att WHERE att.target_id = :id)
|
||||
)
|
||||
ORDER BY n.created DESC
|
||||
EOF, ['id' => $group->getId()]);
|
||||
|
||||
return [
|
||||
|
@@ -21,7 +21,7 @@ declare(strict_types = 1);
|
||||
|
||||
namespace Component\Group\Entity;
|
||||
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\DB;
|
||||
use App\Core\Entity;
|
||||
use App\Entity\Actor;
|
||||
use App\Util\Exception\NicknameEmptyException;
|
||||
|
@@ -24,8 +24,7 @@ namespace Component\Group;
|
||||
use App\Core\Event;
|
||||
use function App\Core\I18n\_m;
|
||||
use App\Core\Modules\Component;
|
||||
use App\Core\Router\RouteLoader;
|
||||
use App\Core\Router\Router;
|
||||
use App\Core\Router;
|
||||
use App\Entity\Activity;
|
||||
use App\Entity\Actor;
|
||||
use App\Util\Common;
|
||||
@@ -38,7 +37,7 @@ use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
class Group extends Component
|
||||
{
|
||||
public function onAddRoute(RouteLoader $r): bool
|
||||
public function onAddRoute(Router $r): bool
|
||||
{
|
||||
$r->connect(id: 'group_actor_view_id', uri_path: '/group/{id<\d+>}', target: [C\GroupFeed::class, 'groupViewId']);
|
||||
$r->connect(id: 'group_actor_view_nickname', uri_path: '/!{nickname<' . Nickname::DISPLAY_FMT . '>}', target: [C\GroupFeed::class, 'groupViewNickname']);
|
||||
@@ -51,12 +50,17 @@ class Group extends Component
|
||||
* Enqueues a notification for an Actor (such as person or group) which means
|
||||
* it shows up in their home feed and such.
|
||||
*/
|
||||
public function onNewNotificationWithTargets(Actor $sender, Activity $activity, array $targets = [], ?string $reason = null): bool
|
||||
public function onNewNotificationStart(Actor $sender, Activity $activity, array $targets = [], ?string $reason = null): bool
|
||||
{
|
||||
foreach ($targets as $target) {
|
||||
if ($target->isGroup()) {
|
||||
// The Group announces to its subscribers
|
||||
Notification::notify($target, $activity, $target->getSubscribers(), $reason);
|
||||
Notification::notify(
|
||||
sender: $target,
|
||||
activity: $activity,
|
||||
targets: $target->getSubscribers(),
|
||||
reason: $reason,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,7 +79,6 @@ class Group extends Component
|
||||
$url = Router::url('group_actor_settings', ['id' => $group->getId()]);
|
||||
$res[] = HTML::html(['a' => ['attrs' => ['href' => $url, 'title' => _m('Edit group settings'), 'class' => 'profile-extra-actions'], _m('Group settings')]]);
|
||||
}
|
||||
$res[] = HTML::html(['a' => ['attrs' => ['href' => Router::url('blog_post', ['in' => $group->getId()]), 'title' => _m('Make a new blog post'), 'class' => 'profile-extra-actions'], _m('Post in blog')]]);
|
||||
}
|
||||
return Event::next;
|
||||
}
|
||||
@@ -85,13 +88,21 @@ class Group extends Component
|
||||
*/
|
||||
private function getGroupFromContext(Request $request): ?Actor
|
||||
{
|
||||
if (str_starts_with($request->get('_route'), 'group_actor_view_')) {
|
||||
if (!\is_null($id = $request->get('id'))) {
|
||||
return Actor::getById((int) $id);
|
||||
}
|
||||
|
||||
if (!\is_null($nickname = $request->get('nickname'))) {
|
||||
return LocalGroup::getActorByNickname($nickname);
|
||||
if (\is_array($request->get('post_note')) && \array_key_exists('_next', $request->get('post_note'))) {
|
||||
$next = parse_url($request->get('post_note')['_next']);
|
||||
$match = Router::match($next['path']);
|
||||
$route = $match['_route'];
|
||||
$identifier = $match['id'] ?? $match['nickname'] ?? null;
|
||||
} else {
|
||||
$route = $request->get('_route');
|
||||
$identifier = $request->get('id') ?? $request->get('nickname');
|
||||
}
|
||||
if (str_starts_with($route, 'group_actor_view_')) {
|
||||
switch ($route) {
|
||||
case 'group_actor_view_nickname':
|
||||
return LocalGroup::getActorByNickname($identifier);
|
||||
case 'group_actor_view_id':
|
||||
return Actor::getById((int) $identifier);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<h1>Settings</h1>
|
||||
<ul>
|
||||
<li>
|
||||
{% set profile_tabs = [{'title': 'Personal Info', 'desc': 'Nickname, Homepage, Bio, Self Tags and more.', 'id': 'settings-personal-info', 'form': personal_info_form}] %}
|
||||
{% set profile_tabs = [{'title': 'Personal Info', 'desc': 'Nickname, Homepage, Bio and more.', 'id': 'settings-personal-info', 'form': personal_info_form}] %}
|
||||
{% set profile_tabs = profile_tabs|merge(handle_event('PopulateSettingsTabs', app.request, 'profile')) %}
|
||||
{{ macros.settings_details_container('Profile', 'Personal Information, Avatar and Profile', 'settings-profile-details', profile_tabs, _context) }}
|
||||
</li>
|
||||
|
@@ -21,7 +21,7 @@ declare(strict_types = 1);
|
||||
|
||||
namespace Component\Group\tests\Entity;
|
||||
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\DB;
|
||||
use App\Entity\Actor;
|
||||
use App\Util\GNUsocialTestCase;
|
||||
use Component\Group\Entity\LocalGroup;
|
||||
|
@@ -25,7 +25,7 @@ namespace Component\Language\Controller;
|
||||
|
||||
use App\Core\Cache;
|
||||
use App\Core\Controller;
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\DB;
|
||||
use App\Core\Form;
|
||||
use function App\Core\I18n\_m;
|
||||
use App\Util\Common;
|
||||
@@ -70,7 +70,7 @@ class Language extends Controller
|
||||
['actor_id' => $user->getId()],
|
||||
);
|
||||
|
||||
$new_langs = array_udiff($selected_langs, $existing_langs, fn ($l, $r) => $l->getId() <=> $r->getId());
|
||||
$new_langs = array_udiff($selected_langs, $existing_langs, fn ($l, $r) => $l->getId() <=> $r->getId());
|
||||
$removing_langs = array_udiff($existing_langs, $selected_langs, fn ($l, $r) => $l->getId() <=> $r->getId());
|
||||
foreach ($new_langs as $l) {
|
||||
DB::persist(ActorLanguage::create(['actor_id' => $user->getId(), 'language_id' => $l->getId(), 'ordering' => 0]));
|
||||
|
@@ -24,7 +24,7 @@ declare(strict_types = 1);
|
||||
namespace Component\Language\Entity;
|
||||
|
||||
use App\Core\Cache;
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\DB;
|
||||
use App\Core\Entity;
|
||||
use App\Entity\Actor;
|
||||
use App\Entity\LocalUser;
|
||||
|
@@ -24,7 +24,7 @@ declare(strict_types = 1);
|
||||
namespace Component\Language\Entity;
|
||||
|
||||
use App\Core\Cache;
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\DB;
|
||||
use App\Core\Entity;
|
||||
use function App\Core\I18n\_m;
|
||||
use App\Entity\Actor;
|
||||
@@ -116,7 +116,7 @@ class Language extends Entity
|
||||
return Cache::getHashMapKey(
|
||||
map_key: 'languages-id',
|
||||
key: (string) $id,
|
||||
calculate_map: fn () => F\reindex(DB::dql('select l from language l'), fn (self $l) => (string) $l->getId()),
|
||||
calculate_map: fn () => F\reindex(DB::dql('SELECT l FROM \Component\Language\Entity\Language AS l'), fn (self $l) => (string) $l->getId()),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -125,7 +125,7 @@ class Language extends Entity
|
||||
return Cache::getHashMapKey(
|
||||
'languages',
|
||||
$locale,
|
||||
calculate_map: fn () => F\reindex(DB::dql('select l from language l'), fn (self $l) => $l->getLocale()),
|
||||
calculate_map: fn () => F\reindex(DB::dql('SELECT l FROM \Component\Language\Entity\Language AS l'), fn (self $l) => $l->getLocale()),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -138,7 +138,7 @@ class Language extends Entity
|
||||
{
|
||||
$langs = Cache::getHashMap(
|
||||
'languages',
|
||||
fn () => F\reindex(DB::dql('select l from language l'), fn (self $l) => $l->getLocale()),
|
||||
fn () => F\reindex(DB::dql('SELECT l FROM \Component\Language\Entity\Language AS l'), fn (self $l) => $l->getLocale()),
|
||||
);
|
||||
|
||||
return array_merge(...F\map(array_values($langs), fn ($l) => $l->toChoiceFormat()));
|
||||
|
@@ -23,7 +23,7 @@ namespace Component\Language;
|
||||
|
||||
use App\Core\Event;
|
||||
use App\Core\Modules\Component;
|
||||
use App\Core\Router\RouteLoader;
|
||||
use App\Core\Router;
|
||||
use App\Entity\Actor;
|
||||
use App\Entity\Note;
|
||||
use App\Util\Formatting;
|
||||
@@ -38,7 +38,7 @@ use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
class Language extends Component
|
||||
{
|
||||
public function onAddRoute(RouteLoader $r): bool
|
||||
public function onAddRoute(Router $r): bool
|
||||
{
|
||||
$r->connect('settings_sort_languages', '/settings/sort_languages', [C\Language::class, 'sortLanguages']);
|
||||
return Event::next;
|
||||
|
@@ -25,10 +25,10 @@ namespace Component\LeftPanel\Controller;
|
||||
|
||||
use App\Core\Cache;
|
||||
use App\Core\Controller;
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\DB;
|
||||
use App\Core\Form;
|
||||
use function App\Core\I18n\_m;
|
||||
use App\Core\Router\Router;
|
||||
use App\Core\Router;
|
||||
use App\Entity\Feed;
|
||||
use App\Util\Common;
|
||||
use App\Util\Exception\ClientException;
|
||||
|
@@ -22,12 +22,11 @@ declare(strict_types = 1);
|
||||
namespace Component\LeftPanel;
|
||||
|
||||
use App\Core\Cache;
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\DB;
|
||||
use App\Core\Event;
|
||||
use function App\Core\I18n\_m;
|
||||
use App\Core\Modules\Component;
|
||||
use App\Core\Router\RouteLoader;
|
||||
use App\Core\Router\Router;
|
||||
use App\Core\Router;
|
||||
use App\Entity\Actor;
|
||||
use App\Entity\Feed;
|
||||
use App\Util\Exception\ClientException;
|
||||
@@ -36,7 +35,7 @@ use Component\LeftPanel\Controller as C;
|
||||
|
||||
class LeftPanel extends Component
|
||||
{
|
||||
public function onAddRoute(RouteLoader $r): bool
|
||||
public function onAddRoute(Router $r): bool
|
||||
{
|
||||
$r->connect('edit_feeds', '/edit-feeds', C\EditFeeds::class);
|
||||
return Event::next;
|
||||
|
@@ -21,7 +21,7 @@ declare(strict_types = 1);
|
||||
|
||||
namespace Component\Link\Entity;
|
||||
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\DB;
|
||||
use App\Core\Entity;
|
||||
use App\Core\Event;
|
||||
use App\Core\GSFile;
|
||||
|
@@ -21,7 +21,7 @@ declare(strict_types = 1);
|
||||
|
||||
namespace Component\Link\Entity;
|
||||
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\DB;
|
||||
use App\Core\Entity;
|
||||
use App\Core\Event;
|
||||
use DateTimeInterface;
|
||||
@@ -84,16 +84,14 @@ class NoteToLink extends Entity
|
||||
* Create an instance of NoteToLink or fill in the
|
||||
* properties of $obj with the associative array $args. Doesn't
|
||||
* persist the result
|
||||
*
|
||||
* @param null|mixed $obj
|
||||
*/
|
||||
public static function create(array $args, $obj = null)
|
||||
public static function create(array $args, bool $_delegated_call = false): static
|
||||
{
|
||||
$link = DB::find('link', ['id' => $args['link_id']]);
|
||||
$note = DB::find('note', ['id' => $args['note_id']]);
|
||||
Event::handle('NewLinkFromNote', [$link, $note]);
|
||||
$obj = new self();
|
||||
return parent::create($args, $obj);
|
||||
return parent::createOrUpdate(obj: $obj, args: $args);
|
||||
}
|
||||
|
||||
public static function removeWhereNoteId(int $note_id): mixed
|
||||
|
@@ -23,7 +23,7 @@ declare(strict_types = 1);
|
||||
|
||||
namespace Component\Link;
|
||||
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\DB;
|
||||
use App\Core\Event;
|
||||
use App\Core\Modules\Component;
|
||||
use App\Entity\Actor;
|
||||
@@ -35,6 +35,22 @@ use InvalidArgumentException;
|
||||
|
||||
class Link extends Component
|
||||
{
|
||||
/**
|
||||
* Note that this persists both a Link and a NoteToLink
|
||||
*
|
||||
* @return [Entity\Link, NoteToLink]
|
||||
*/
|
||||
public static function maybeCreateLink(string $url, int $note_id): array
|
||||
{
|
||||
try {
|
||||
$link = Entity\Link::getOrCreate($url);
|
||||
DB::persist($note_link = NoteToLink::create(['link_id' => $link->getId(), 'note_id' => $note_id]));
|
||||
return ['link' => $link, 'note_to_link' => $note_link];
|
||||
} catch (InvalidArgumentException) {
|
||||
return ['link' => null, 'note_to_link' => null];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract URLs from $content and create the appropriate Link and NoteToLink entities
|
||||
*/
|
||||
@@ -49,12 +65,7 @@ class Link extends Component
|
||||
if (\in_array($match, $ignore)) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
$link_id = Entity\Link::getOrCreate($match)->getId();
|
||||
DB::persist(NoteToLink::create(['link_id' => $link_id, 'note_id' => $note->getId()]));
|
||||
} catch (InvalidArgumentException) {
|
||||
continue;
|
||||
}
|
||||
self::maybeCreateLink($match, $note_id);
|
||||
}
|
||||
}
|
||||
return Event::next;
|
||||
|
@@ -35,7 +35,7 @@ declare(strict_types = 1);
|
||||
namespace Component\Notification\Controller;
|
||||
|
||||
use App\Core\Controller;
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\DB;
|
||||
use function App\Core\I18n\_m;
|
||||
use App\Util\Common;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
@@ -53,9 +53,9 @@ class Feed extends Controller
|
||||
WHERE n.id IN (
|
||||
SELECT act.object_id FROM \App\Entity\Activity AS act
|
||||
WHERE act.object_type = 'note' AND act.id IN
|
||||
(SELECT att.activity_id FROM \Component\Notification\Entity\Notification AS att WHERE att.target_id = :id)
|
||||
(SELECT att.activity_id FROM \Component\Notification\Entity\Notification AS att WHERE att.target_id = :target_id)
|
||||
)
|
||||
EOF, ['id' => $user->getId()]);
|
||||
EOF, [':target_id' => $user->getId()]);
|
||||
return [
|
||||
'_template' => 'collection/notes.html.twig',
|
||||
'page_title' => _m('Notifications'),
|
||||
|
@@ -24,31 +24,51 @@ namespace Component\Notification\Entity;
|
||||
use App\Core\Entity;
|
||||
|
||||
/**
|
||||
* Entity for note attentions
|
||||
* Entity for object attentions
|
||||
*
|
||||
* An attention is a form of persistent notification.
|
||||
* It exists together and for as long as the object it belongs to.
|
||||
* Creating an attention requires creating a Notification.
|
||||
*
|
||||
* @category DB
|
||||
* @package GNUsocial
|
||||
*
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2010 StatusNet Inc.
|
||||
* @author Mikael Nordfeldth <mmn@hethane.se>
|
||||
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @author Diogo Peralta Cordeiro <@diogo.site>
|
||||
* @copyright 2022 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @copyright 2021-2022 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
class Attention extends Entity
|
||||
{
|
||||
// {{{ Autocode
|
||||
// @codeCoverageIgnoreStart
|
||||
private int $note_id;
|
||||
private string $object_type;
|
||||
private int $object_id;
|
||||
private int $target_id;
|
||||
|
||||
public function setNoteId(int $note_id): self
|
||||
public function setObjectType(string $object_type): self
|
||||
{
|
||||
$this->note_id = $note_id;
|
||||
$this->object_type = mb_substr($object_type, 0, 32);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getNoteId(): int
|
||||
public function getObjectType(): string
|
||||
{
|
||||
return $this->note_id;
|
||||
return $this->object_type;
|
||||
}
|
||||
|
||||
public function setObjectId(int $object_id): self
|
||||
{
|
||||
$this->object_id = $object_id;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getObjectId(): int
|
||||
{
|
||||
return $this->object_id;
|
||||
}
|
||||
|
||||
public function setTargetId(int $target_id): self
|
||||
@@ -68,15 +88,16 @@ class Attention extends Entity
|
||||
public static function schemaDef(): array
|
||||
{
|
||||
return [
|
||||
'name' => 'note_attention',
|
||||
'description' => 'Note attentions to actors (that are not a mention)',
|
||||
'name' => 'attention',
|
||||
'description' => 'Attentions to actors (these are not mentions)',
|
||||
'fields' => [
|
||||
'note_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'Note.id', 'multiplicity' => 'one to one', 'not null' => true, 'description' => 'note_id to give attention'],
|
||||
'target_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'Actor.id', 'multiplicity' => 'one to one', 'not null' => true, 'description' => 'actor_id for feed receiver'],
|
||||
'object_type' => ['type' => 'varchar', 'length' => 32, 'not null' => true, 'description' => 'the name of the table this object refers to'],
|
||||
'object_id' => ['type' => 'int', 'not null' => true, 'description' => 'id in the referenced table'],
|
||||
'target_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'Actor.id', 'multiplicity' => 'one to one', 'not null' => true, 'description' => 'actor_id for feed receiver'],
|
||||
],
|
||||
'primary key' => ['note_id', 'target_id'],
|
||||
'primary key' => ['object_type', 'object_id', 'target_id'],
|
||||
'indexes' => [
|
||||
'attention_note_id_idx' => ['note_id'],
|
||||
'attention_object_id_idx' => ['object_id'],
|
||||
'attention_target_id_idx' => ['target_id'],
|
||||
],
|
||||
];
|
||||
|
@@ -21,24 +21,24 @@ declare(strict_types = 1);
|
||||
|
||||
namespace Component\Notification\Entity;
|
||||
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\DB;
|
||||
use App\Core\Entity;
|
||||
use App\Entity\Activity;
|
||||
use App\Entity\Actor;
|
||||
use DateTimeInterface;
|
||||
|
||||
/**
|
||||
* Entity for attentions
|
||||
* Entity for Notifications
|
||||
*
|
||||
* A Notification when isolated is a form of transient notification.
|
||||
* When together with a persistent form of notification such as attentions or mentions,
|
||||
* it records that the target was notified - which avoids re-notifying upon objects reconstructions.
|
||||
*
|
||||
* @category DB
|
||||
* @package GNUsocial
|
||||
*
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2010 StatusNet Inc.
|
||||
* @author Mikael Nordfeldth <mmn@hethane.se>
|
||||
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @author Hugo Sales <hugo@hsal.es>
|
||||
* @copyright 2020-2021 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @author Diogo Peralta Cordeiro <@diogo.site>
|
||||
* @copyright 2021-2022 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||
*/
|
||||
class Notification extends Entity
|
||||
|
@@ -21,14 +21,13 @@ declare(strict_types = 1);
|
||||
|
||||
namespace Component\Notification;
|
||||
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\DB;
|
||||
use App\Core\Event;
|
||||
use function App\Core\I18n\_m;
|
||||
use App\Core\Log;
|
||||
use App\Core\Modules\Component;
|
||||
use App\Core\Queue\Queue;
|
||||
use App\Core\Router\RouteLoader;
|
||||
use App\Core\Router\Router;
|
||||
use App\Core\Queue;
|
||||
use App\Core\Router;
|
||||
use App\Entity\Activity;
|
||||
use App\Entity\Actor;
|
||||
use App\Entity\LocalUser;
|
||||
@@ -40,7 +39,7 @@ use Throwable;
|
||||
|
||||
class Notification extends Component
|
||||
{
|
||||
public function onAddRoute(RouteLoader $m): bool
|
||||
public function onAddRoute(Router $m): bool
|
||||
{
|
||||
$m->connect('feed_notifications', '/feed/notifications', [Feed::class, 'notifications']);
|
||||
return Event::next;
|
||||
@@ -64,14 +63,42 @@ class Notification extends Component
|
||||
/**
|
||||
* Enqueues a notification for an Actor (such as person or group) which means
|
||||
* it shows up in their home feed and such.
|
||||
* WARNING: It's highly advisable to have flushed any relevant objects before triggering this event.
|
||||
*
|
||||
* $targets should be of the shape:
|
||||
* (int|Actor)[] // Prefer Actor whenever possible
|
||||
* Example of $targets:
|
||||
* [42, $actor_alice, $actor_bob] // Avoid repeating actors or ids
|
||||
*
|
||||
* @param Actor $sender The one responsible for this activity, take care not to include it in targets
|
||||
* @param Activity $activity The activity responsible for the object being given to known to targets
|
||||
* @param array $targets Attentions, Mentions, any other source. Should never be empty, you usually want to register an attention to every $sender->getSubscribers()
|
||||
* @param null|string $reason An optional reason explaining why this notification exists
|
||||
*/
|
||||
public function onNewNotification(Actor $sender, Activity $activity, array $ids_already_known = [], ?string $reason = null): bool
|
||||
public function onNewNotification(Actor $sender, Activity $activity, array $targets, ?string $reason = null): bool
|
||||
{
|
||||
$targets = $activity->getNotificationTargets(ids_already_known: $ids_already_known, sender_id: $sender->getId());
|
||||
if (Event::handle('NewNotificationWithTargets', [$sender, $activity, $targets, $reason]) === Event::next) {
|
||||
self::notify($sender, $activity, $targets, $reason);
|
||||
// Ensure targets are all actor objects and unique
|
||||
$effective_targets = [];
|
||||
foreach ($targets as $target) {
|
||||
if (\is_int($target)) {
|
||||
$target_id = $target;
|
||||
$target_object = null;
|
||||
} else {
|
||||
$target_id = $target->getId();
|
||||
$target_object = $target;
|
||||
}
|
||||
if (!\array_key_exists(key: $target_id, array: $effective_targets)) {
|
||||
$target_object ??= Actor::getById($target_id);
|
||||
$effective_targets[$target_id] = $target_object;
|
||||
}
|
||||
}
|
||||
unset($targets);
|
||||
|
||||
if (Event::handle('NewNotificationStart', [$sender, $activity, $effective_targets, $reason]) === Event::next) {
|
||||
self::notify($sender, $activity, $effective_targets, $reason);
|
||||
}
|
||||
|
||||
Event::handle('NewNotificationEnd', [$sender, $activity, $effective_targets, $reason]);
|
||||
return Event::next;
|
||||
}
|
||||
|
||||
@@ -91,7 +118,8 @@ class Notification extends Component
|
||||
}
|
||||
|
||||
/**
|
||||
* Bring given Activity to Targets's attention
|
||||
* Bring given Activity to Targets' knowledge.
|
||||
* This will flush a Notification to DB.
|
||||
*
|
||||
* @return true if successful, false otherwise
|
||||
*/
|
||||
@@ -100,8 +128,8 @@ class Notification extends Component
|
||||
$remote_targets = [];
|
||||
foreach ($targets as $target) {
|
||||
if ($target->getIsLocal()) {
|
||||
if ($target->hasBlocked($activity->getActor())) {
|
||||
Log::info("Not saving reply to actor {$target->getId()} from sender {$sender->getId()} because of a block.");
|
||||
if ($target->hasBlocked($author = $activity->getActor())) {
|
||||
Log::info("Not saving notification to actor {$target->getId()} from sender {$sender->getId()} because receiver blocked author {$author->getId()}.");
|
||||
continue;
|
||||
}
|
||||
if (Event::handle('NewNotificationShould', [$activity, $target]) === Event::next) {
|
||||
@@ -113,7 +141,7 @@ class Notification extends Component
|
||||
}
|
||||
Queue::enqueue(
|
||||
payload: [$sender, $activity, $target, $reason],
|
||||
queue: 'notification_local',
|
||||
queue: 'NotificationLocal',
|
||||
priority: true,
|
||||
);
|
||||
} else {
|
||||
@@ -124,7 +152,7 @@ class Notification extends Component
|
||||
}
|
||||
// XXX: Unideal as in failures the rollback will leave behind a false notification,
|
||||
// but most notifications (all) require flushing the objects first
|
||||
// Should be okay as long as implementors bear this in mind
|
||||
// Should be okay as long as implementations bear this in mind
|
||||
try {
|
||||
DB::wrapInTransaction(fn () => DB::persist(Entity\Notification::create([
|
||||
'activity_id' => $activity->getId(),
|
||||
@@ -132,7 +160,7 @@ class Notification extends Component
|
||||
'reason' => $reason,
|
||||
])));
|
||||
} catch (Exception|Throwable $e) {
|
||||
// We do our best not to record duplicated notifications, but it's not insane that can happen
|
||||
// We do our best not to record duplicate notifications, but it's not insane that can happen
|
||||
Log::error('It was attempted to record an invalid notification!', [$e]);
|
||||
}
|
||||
}
|
||||
@@ -140,7 +168,7 @@ class Notification extends Component
|
||||
if ($remote_targets !== []) {
|
||||
Queue::enqueue(
|
||||
payload: [$sender, $activity, $remote_targets, $reason],
|
||||
queue: 'notification_remote',
|
||||
queue: 'NotificationRemote',
|
||||
priority: false,
|
||||
);
|
||||
}
|
||||
|
@@ -24,7 +24,7 @@ declare(strict_types = 1);
|
||||
namespace Component\Person\Controller;
|
||||
|
||||
use function App\Core\I18n\_m;
|
||||
use App\Core\Router\Router;
|
||||
use App\Core\Router;
|
||||
use App\Entity\Actor;
|
||||
use App\Entity as E;
|
||||
use App\Entity\LocalUser;
|
||||
|
@@ -38,11 +38,12 @@ namespace Component\Person\Controller;
|
||||
// {{{ Imports
|
||||
|
||||
use App\Core\Controller;
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\DB;
|
||||
use App\Core\Event;
|
||||
use App\Core\Form;
|
||||
use function App\Core\I18n\_m;
|
||||
use App\Core\Log;
|
||||
use App\Entity\Actor;
|
||||
use App\Util\Common;
|
||||
use App\Util\Exception\AuthenticationException;
|
||||
use App\Util\Exception\NicknameEmptyException;
|
||||
@@ -91,8 +92,9 @@ class PersonSettings extends Controller
|
||||
public function allSettings(Request $request, LanguageController $language): array
|
||||
{
|
||||
// Ensure the user is logged in and retrieve Actor object for given user
|
||||
$user = Common::ensureLoggedIn();
|
||||
$actor = $user->getActor();
|
||||
$user = Common::ensureLoggedIn();
|
||||
// Must be persisted
|
||||
$actor = DB::findOneBy(Actor::class, ['id' => $user->getId()]);
|
||||
|
||||
$personal_form = ActorForms::personalInfo(request: $request, scope: $actor, target: $actor);
|
||||
$email_form = self::email($request);
|
||||
@@ -101,7 +103,7 @@ class PersonSettings extends Controller
|
||||
$language_form = $language->settings($request);
|
||||
|
||||
return [
|
||||
'_template' => 'settings/base.html.twig',
|
||||
'_template' => 'person/settings.html.twig',
|
||||
'personal_info_form' => $personal_form->createView(),
|
||||
'email_form' => $email_form->createView(),
|
||||
'password_form' => $password_form->createView(),
|
||||
@@ -284,7 +286,7 @@ class PersonSettings extends Controller
|
||||
$data = $form->getData();
|
||||
unset($data['translation_domain']);
|
||||
try {
|
||||
[$entity, $is_update] = UserNotificationPrefs::createOrUpdate(
|
||||
[$entity, $is_update] = UserNotificationPrefs::checkExistingAndCreateOrUpdate(
|
||||
array_merge(['user_id' => $user->getId(), 'transport' => $transport_name], $data),
|
||||
find_by_keys: ['user_id', 'transport'],
|
||||
);
|
||||
|
@@ -23,13 +23,13 @@ namespace Component\Person;
|
||||
|
||||
use App\Core\Event;
|
||||
use App\Core\Modules\Component;
|
||||
use App\Core\Router\RouteLoader;
|
||||
use App\Core\Router;
|
||||
use App\Util\Nickname;
|
||||
use Component\Person\Controller as C;
|
||||
|
||||
class Person extends Component
|
||||
{
|
||||
public function onAddRoute(RouteLoader $r): bool
|
||||
public function onAddRoute(Router $r): bool
|
||||
{
|
||||
$r->connect(id: 'person_actor_view_id', uri_path: '/person/{id<\d+>}', target: [C\PersonFeed::class, 'personViewId']);
|
||||
$r->connect(id: 'person_actor_view_nickname', uri_path: '/@{nickname<' . Nickname::DISPLAY_FMT . '>}', target: [C\PersonFeed::class, 'personViewNickname'], options: ['is_system_path' => false]);
|
||||
|
@@ -33,6 +33,10 @@
|
||||
<li>
|
||||
{{ macros.settings_details_container('Notifications', 'Enable/disable notifications (Email, XMPP, Replies...)', 'notifications', tabbed_forms_notify, _context) }}
|
||||
</li>
|
||||
<li>
|
||||
{% set other_tabs = handle_event('PopulateSettingsTabs', app.request, 'api') %}
|
||||
{{ macros.settings_details_container('API', 'API settings', 'settings-other-details', other_tabs, _context) }}
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
{% endblock body %}
|
@@ -23,8 +23,8 @@ declare(strict_types = 1);
|
||||
|
||||
namespace Component\Person\tests\Controller;
|
||||
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\Router\Router;
|
||||
use App\Core\DB;
|
||||
use App\Core\Router;
|
||||
use App\Entity\LocalUser;
|
||||
use App\Util\GNUsocialTestCase;
|
||||
use Jchook\AssertThrows\AssertThrows;
|
||||
@@ -55,13 +55,13 @@ class PersonSettingsTest extends GNUsocialTestCase
|
||||
]);
|
||||
$changed_user = DB::findOneBy(LocalUser::class, ['id' => $user->getId()]);
|
||||
$actor = $changed_user->getActor();
|
||||
static::assertSame($changed_user->getNickname(), 'form_test_user_new_nickname');
|
||||
static::assertSame($actor->getNickname(), 'form_test_user_new_nickname');
|
||||
static::assertSame($actor->getFullName(), 'Form User');
|
||||
static::assertSame($actor->getHomepage(), 'https://gnu.org');
|
||||
static::assertSame($actor->getBio(), 'I was born at a very young age');
|
||||
static::assertSame($actor->getLocation(), 'right here');
|
||||
// static::assertSame($changed_user->getPhoneNumber()->getNationalNumber(), '908555842');
|
||||
static::assertSame('form_test_user_new_nickname', $changed_user->getNickname());
|
||||
static::assertSame('form_test_user_new_nickname', $actor->getNickname());
|
||||
static::assertSame('Form User', $actor->getFullName());
|
||||
static::assertSame('https://gnu.org', $actor->getHomepage());
|
||||
static::assertSame('I was born at a very young age', $actor->getBio());
|
||||
static::assertSame('right here', $actor->getLocation());
|
||||
// static::assertSame('908555842', $changed_user->getPhoneNumber()->getNationalNumber());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -52,8 +52,8 @@ class Posting extends Controller
|
||||
content_type: $data['content_type'],
|
||||
locale: $data['language'],
|
||||
scope: VisibilityScope::from($data['visibility']),
|
||||
targets: isset($target) ? [$target] : [],
|
||||
reply_to: $data['reply_to_id'],
|
||||
attentions: isset($target) ? [$target] : [],
|
||||
reply_to: \array_key_exists('reply_to_id', $data) ? $data['reply_to_id'] : null,
|
||||
attachments: $data['attachments'],
|
||||
process_note_content_extra_args: $extra_args,
|
||||
);
|
||||
@@ -61,9 +61,9 @@ class Posting extends Controller
|
||||
return Core\Form::forceRedirect($form, $request);
|
||||
}
|
||||
} catch (FormSizeFileException $e) {
|
||||
throw new ClientException(_m('Invalid file size given'), previous: $e);
|
||||
throw new ClientException(_m('Invalid file size given.'), previous: $e);
|
||||
}
|
||||
}
|
||||
throw new ClientException(_m('Invalid form submission'));
|
||||
throw new ClientException(_m('Invalid form submission.'));
|
||||
}
|
||||
}
|
||||
|
@@ -8,7 +8,7 @@ use App\Core\ActorLocalRoles;
|
||||
use App\Core\Event;
|
||||
use App\Core\Form;
|
||||
use function App\Core\I18n\_m;
|
||||
use App\Core\Router\Router;
|
||||
use App\Core\Router;
|
||||
use App\Core\VisibilityScope;
|
||||
use App\Entity\Actor;
|
||||
use App\Util\Common;
|
||||
|
@@ -24,13 +24,12 @@ declare(strict_types = 1);
|
||||
namespace Component\Posting;
|
||||
|
||||
use App\Core\Cache;
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\DB;
|
||||
use App\Core\Event;
|
||||
use App\Core\GSFile;
|
||||
use function App\Core\I18n\_m;
|
||||
use App\Core\Modules\Component;
|
||||
use App\Core\Router\RouteLoader;
|
||||
use App\Core\Router\Router;
|
||||
use App\Core\Router;
|
||||
use App\Core\VisibilityScope;
|
||||
use App\Entity\Activity;
|
||||
use App\Entity\Actor;
|
||||
@@ -48,7 +47,6 @@ use Component\Attachment\Entity\AttachmentToNote;
|
||||
use Component\Conversation\Conversation;
|
||||
use Component\Language\Entity\Language;
|
||||
use Component\Notification\Entity\Attention;
|
||||
use Functional as F;
|
||||
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
@@ -56,7 +54,7 @@ class Posting extends Component
|
||||
{
|
||||
public const route = 'posting_form_action';
|
||||
|
||||
public function onAddRoute(RouteLoader $r): bool
|
||||
public function onAddRoute(Router $r): bool
|
||||
{
|
||||
$r->connect(self::route, '/form/posting', Controller\Posting::class);
|
||||
return Event::next;
|
||||
@@ -88,13 +86,13 @@ class Posting extends Component
|
||||
* @throws DuplicateFoundException
|
||||
* @throws ServerException
|
||||
*/
|
||||
public static function storeLocalPage(
|
||||
public static function storeLocalArticle(
|
||||
Actor $actor,
|
||||
?string $content,
|
||||
string $content_type,
|
||||
?string $locale = null,
|
||||
?VisibilityScope $scope = null,
|
||||
array $targets = [],
|
||||
array $attentions = [],
|
||||
null|int|Note $reply_to = null,
|
||||
array $attachments = [],
|
||||
array $processed_attachments = [],
|
||||
@@ -104,13 +102,13 @@ class Posting extends Component
|
||||
string $source = 'web',
|
||||
?string $title = null,
|
||||
): array {
|
||||
[$activity, $note, $attention_ids] = self::storeLocalNote(
|
||||
[$activity, $note, $effective_attentions] = self::storeLocalNote(
|
||||
actor: $actor,
|
||||
content: $content,
|
||||
content_type: $content_type,
|
||||
locale: $locale,
|
||||
scope: $scope,
|
||||
targets: $targets,
|
||||
attentions: $attentions,
|
||||
reply_to: $reply_to,
|
||||
attachments: $attachments,
|
||||
processed_attachments: $processed_attachments,
|
||||
@@ -119,16 +117,24 @@ class Posting extends Component
|
||||
rendered: $rendered,
|
||||
source: $source,
|
||||
);
|
||||
$note->setType('page');
|
||||
$note->setType('article');
|
||||
$note->setTitle($title);
|
||||
|
||||
if ($flush_and_notify) {
|
||||
// Flush before notification
|
||||
DB::flush();
|
||||
Event::handle('NewNotification', [$actor, $activity, ['object' => $attention_ids], _m('{nickname} created a page {note_id}.', ['{nickname}' => $actor->getNickname(), '{note_id}' => $activity->getObjectId()])]);
|
||||
Event::handle('NewNotification', [
|
||||
$actor,
|
||||
$activity,
|
||||
$effective_attentions,
|
||||
_m('Actor {actor_id} created article {note_id}.', [
|
||||
'{actor_id}' => $actor->getId(),
|
||||
'{note_id}' => $activity->getObjectId(),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
|
||||
return [$activity, $note, $attention_ids];
|
||||
return [$activity, $note, $effective_attentions];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -141,7 +147,7 @@ class Posting extends Component
|
||||
* @param string $content_type Indicating one of the various supported content format (Plain Text, Markdown, LaTeX...)
|
||||
* @param null|string $locale Note's written text language, set by the default Actor language or upon filling
|
||||
* @param null|VisibilityScope $scope The visibility of this Note
|
||||
* @param array $targets Actor|int[]: In Group/To Person or Bot, registers an attention between note and target
|
||||
* @param array $attentions Actor|int[]: In Group/To Person or Bot, registers an attention between note and target
|
||||
* @param null|int|Note $reply_to The soon-to-be Note parent's id, if it's a Reply itself
|
||||
* @param array $attachments UploadedFile[] to be stored as GSFiles associated to this note
|
||||
* @param array $processed_attachments Array of [Attachment, Attachment's name][] to be associated to this $actor and Note
|
||||
@@ -154,7 +160,7 @@ class Posting extends Component
|
||||
* @throws DuplicateFoundException
|
||||
* @throws ServerException
|
||||
*
|
||||
* @return array [Activity, Note, int[]] Activity, Note, Attention Ids
|
||||
* @return array [Activity, Note, Effective Attentions]
|
||||
*/
|
||||
public static function storeLocalNote(
|
||||
Actor $actor,
|
||||
@@ -162,7 +168,7 @@ class Posting extends Component
|
||||
string $content_type,
|
||||
?string $locale = null,
|
||||
?VisibilityScope $scope = null,
|
||||
array $targets = [],
|
||||
array $attentions = [],
|
||||
null|int|Note $reply_to = null,
|
||||
array $attachments = [],
|
||||
array $processed_attachments = [],
|
||||
@@ -209,7 +215,7 @@ class Posting extends Component
|
||||
if (!\is_null($reply_to_id)) {
|
||||
Cache::incr(Note::cacheKeys($reply_to_id)['replies-count']);
|
||||
// Not having them cached doesn't mean replies don't exist, but don't push it to the
|
||||
// list, as that means they need to be refetched, or some would be missed
|
||||
// list, as that means they need to be re-fetched, or some would be missed
|
||||
if (Cache::exists(Note::cacheKeys($reply_to_id)['replies'])) {
|
||||
Cache::listPushRight(Note::cacheKeys($reply_to_id)['replies'], $note);
|
||||
}
|
||||
@@ -221,12 +227,12 @@ class Posting extends Component
|
||||
Event::handle('ProcessNoteContent', [$note, $content, $content_type, $process_note_content_extra_args]);
|
||||
}
|
||||
|
||||
// These are note attachments now, and not just attachments, ensure these relations are ensured
|
||||
// These are note attachments now, and not just attachments, ensure these relations are respected
|
||||
if ($processed_attachments !== []) {
|
||||
foreach ($processed_attachments as [$a, $fname]) {
|
||||
// Most attachments should already be associated with its author, but maybe it didn't make sense
|
||||
//for this attachment, or it's simply a repost of an attachment by a different actor
|
||||
if (DB::count('actor_to_attachment', $args = ['attachment_id' => $a->getId(), 'actor_id' => $actor->getId()]) === 0) {
|
||||
if (DB::count(ActorToAttachment::class, $args = ['attachment_id' => $a->getId(), 'actor_id' => $actor->getId()]) === 0) {
|
||||
DB::persist(ActorToAttachment::create($args));
|
||||
}
|
||||
DB::persist(AttachmentToNote::create(['attachment_id' => $a->getId(), 'note_id' => $note->getId(), 'title' => $fname]));
|
||||
@@ -242,13 +248,38 @@ class Posting extends Component
|
||||
]);
|
||||
DB::persist($activity);
|
||||
|
||||
$attention_ids = [];
|
||||
foreach ($targets as $target) {
|
||||
$target_id = \is_int($target) ? $target : $target->getId();
|
||||
DB::persist(Attention::create(['note_id' => $note->getId(), 'target_id' => $target_id]));
|
||||
$attention_ids[$target_id] = true;
|
||||
$effective_attentions = [];
|
||||
foreach ($attentions as $target) {
|
||||
if (\is_int($target)) {
|
||||
$target_id = $target;
|
||||
$add = !\array_key_exists($target_id, $effective_attentions);
|
||||
$effective_attentions[$target_id] = $target;
|
||||
} else {
|
||||
$target_id = $target->getId();
|
||||
if ($add = !\array_key_exists($target_id, $effective_attentions)) {
|
||||
$effective_attentions[$target_id] = $target_id;
|
||||
}
|
||||
}
|
||||
if ($add) {
|
||||
DB::persist(Attention::create(['object_type' => Note::schemaName(), 'object_id' => $note->getId(), 'target_id' => $target_id]));
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($mentions as $m) {
|
||||
foreach ($m['mentioned'] ?? [] as $mentioned) {
|
||||
$target_id = $mentioned->getId();
|
||||
if (!\array_key_exists($target_id, $effective_attentions)) {
|
||||
DB::persist(Attention::create(['object_type' => Note::schemaName(), 'object_id' => $note->getId(), 'target_id' => $target_id]));
|
||||
}
|
||||
$effective_attentions[$target_id] = $mentioned;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($actor->getSubscribers() as $subscriber) {
|
||||
$target_id = $subscriber->getId();
|
||||
DB::persist(Attention::create(['object_type' => Activity::schemaName(), 'object_id' => $activity->getId(), 'target_id' => $target_id]));
|
||||
$effective_attentions[$target_id] = $subscriber;
|
||||
}
|
||||
$attention_ids = array_keys($attention_ids);
|
||||
|
||||
if ($flush_and_notify) {
|
||||
// Flush before notification
|
||||
@@ -256,18 +287,15 @@ class Posting extends Component
|
||||
Event::handle('NewNotification', [
|
||||
$actor,
|
||||
$activity,
|
||||
[
|
||||
'note-attention' => $attention_ids,
|
||||
'object' => F\unique(F\flat_map($mentions, fn (array $m) => F\map($m['mentioned'] ?? [], fn (Actor $a) => $a->getId()))),
|
||||
],
|
||||
_m('{nickname} created a note {note_id}.', [
|
||||
'{nickname}' => $actor->getNickname(),
|
||||
$effective_attentions,
|
||||
_m('Actor {actor_id} created note {note_id}.', [
|
||||
'{actor_id}' => $actor->getId(),
|
||||
'{note_id}' => $activity->getObjectId(),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
|
||||
return [$activity, $note, $attention_ids];
|
||||
return [$activity, $note, $effective_attentions];
|
||||
}
|
||||
|
||||
public function onRenderNoteContent(string $content, string $content_type, ?string &$rendered, Actor $author, ?string $language = null, array &$mentions = [])
|
||||
|
@@ -23,11 +23,11 @@ declare(strict_types = 1);
|
||||
|
||||
namespace Component\Subscription\Controller;
|
||||
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\DB;
|
||||
use App\Core\Form;
|
||||
use function App\Core\I18n\_m;
|
||||
use App\Core\Log;
|
||||
use App\Core\Router\Router;
|
||||
use App\Core\Router;
|
||||
use App\Entity\Actor;
|
||||
use App\Util\Common;
|
||||
use App\Util\Exception\ClientException;
|
||||
|
@@ -114,27 +114,6 @@ class ActorSubscription extends Entity
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Entity->getNotificationTargetIds
|
||||
*/
|
||||
public function getNotificationTargetIds(array $ids_already_known = [], ?int $sender_id = null, bool $include_additional = true): array
|
||||
{
|
||||
if (!\array_key_exists('object', $ids_already_known)) {
|
||||
$target_ids = [$this->getSubscribedId()]; // The object of any subscription is the one subscribed (or unsubscribed)
|
||||
} else {
|
||||
$target_ids = $ids_already_known['object'];
|
||||
}
|
||||
|
||||
// Additional actors that should know about this
|
||||
if ($include_additional && \array_key_exists('additional', $ids_already_known)) {
|
||||
array_push($target_ids, ...$ids_already_known['additional']);
|
||||
} else {
|
||||
return $target_ids;
|
||||
}
|
||||
|
||||
return array_unique($target_ids);
|
||||
}
|
||||
|
||||
public static function schemaDef(): array
|
||||
{
|
||||
return [
|
||||
|
@@ -24,12 +24,11 @@ declare(strict_types = 1);
|
||||
namespace Component\Subscription;
|
||||
|
||||
use App\Core\Cache;
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\DB;
|
||||
use App\Core\Event;
|
||||
use function App\Core\I18n\_m;
|
||||
use App\Core\Modules\Component;
|
||||
use App\Core\Router\RouteLoader;
|
||||
use App\Core\Router\Router;
|
||||
use App\Core\Router;
|
||||
use App\Entity\Activity;
|
||||
use App\Entity\Actor;
|
||||
use App\Entity\LocalUser;
|
||||
@@ -37,14 +36,14 @@ use App\Util\Common;
|
||||
use App\Util\Exception\DuplicateFoundException;
|
||||
use App\Util\Exception\NotFoundException;
|
||||
use App\Util\Exception\ServerException;
|
||||
use Component\Notification\Entity\Attention;
|
||||
use Component\Subscription\Controller\Subscribers as SubscribersController;
|
||||
use Component\Subscription\Controller\Subscriptions as SubscriptionsController;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
class Subscription extends Component
|
||||
{
|
||||
public function onAddRoute(RouteLoader $r): bool
|
||||
public function onAddRoute(Router $r): bool
|
||||
{
|
||||
$r->connect(id: 'actor_subscribe_add', uri_path: '/actor/subscribe/{object_id<\d+>}', target: [SubscribersController::class, 'subscribersAdd']);
|
||||
$r->connect(id: 'actor_subscribe_remove', uri_path: '/actor/unsubscribe/{object_id<\d+>}', target: [SubscribersController::class, 'subscribersRemove']);
|
||||
@@ -97,22 +96,24 @@ class Subscription extends Component
|
||||
$subscription = DB::findOneBy(table: Entity\ActorSubscription::class, criteria: $opts, return_null: true);
|
||||
$activity = null;
|
||||
if (\is_null($subscription)) {
|
||||
DB::persist(Entity\ActorSubscription::create($opts));
|
||||
$activity = Activity::create([
|
||||
DB::persist($subscription = Entity\ActorSubscription::create($opts));
|
||||
$activity = Activity::create([
|
||||
'actor_id' => $subscriber_id,
|
||||
'verb' => 'subscribe',
|
||||
'object_type' => 'actor',
|
||||
'object_type' => Actor::schemaName(),
|
||||
'object_id' => $subscribed_id,
|
||||
'source' => $source,
|
||||
]);
|
||||
DB::persist($activity);
|
||||
DB::persist(Attention::create(['object_type' => Activity::schemaName(), 'object_id' => $activity->getId(), 'target_id' => $subscribed_id]));
|
||||
|
||||
Event::handle('NewNotification', [
|
||||
\is_int($subject) ? $subject : Actor::getById($subscriber_id),
|
||||
$activity,
|
||||
['object' => [$activity->getObjectId()]],
|
||||
_m('{subject} subscribed to {object}.', ['{subject}' => $activity->getActorId(), '{object}' => $activity->getObjectId()]),
|
||||
[$subscribed_id],
|
||||
$reason = _m('{subject} subscribed to {object}.', ['{subject}' => $activity->getActorId(), '{object}' => $activity->getObjectId()]),
|
||||
]);
|
||||
Event::handle('NewSubscriptionEnd', [$subject, $activity, $object, $reason]);
|
||||
}
|
||||
return $activity;
|
||||
}
|
||||
@@ -146,21 +147,22 @@ class Subscription extends Component
|
||||
if (!\is_null($subscription)) {
|
||||
// Remove Subscription
|
||||
DB::remove($subscription);
|
||||
$previous_follow_activity = DB::findBy('activity', ['verb' => 'subscribe', 'object_type' => 'actor', 'object_id' => $subscribed_id], order_by: ['created' => 'DESC'])[0];
|
||||
$previous_follow_activity = DB::findBy(Activity::class, ['verb' => 'subscribe', 'object_type' => Actor::schemaName(), 'object_id' => $subscribed_id], order_by: ['created' => 'DESC'])[0];
|
||||
// Store Activity
|
||||
$activity = Activity::create([
|
||||
'actor_id' => $subscriber_id,
|
||||
'verb' => 'undo',
|
||||
'object_type' => 'activity',
|
||||
'object_type' => Activity::schemaName(),
|
||||
'object_id' => $previous_follow_activity->getId(),
|
||||
'source' => $source,
|
||||
]);
|
||||
DB::persist($activity);
|
||||
|
||||
DB::persist(Attention::create(['object_type' => Activity::schemaName(), 'object_id' => $activity->getId(), 'target_id' => $subscribed_id]));
|
||||
Event::handle('NewNotification', [
|
||||
\is_int($subject) ? $subject : Actor::getById($subscriber_id),
|
||||
$activity,
|
||||
['object' => [$previous_follow_activity->getObjectId()]],
|
||||
[$subscribed_id],
|
||||
_m('{subject} unsubscribed from {object}.', ['{subject}' => $activity->getActorId(), '{object}' => $previous_follow_activity->getObjectId()]),
|
||||
]);
|
||||
}
|
||||
|
@@ -22,9 +22,9 @@ declare(strict_types = 1);
|
||||
namespace Component\Tag\Entity;
|
||||
|
||||
use App\Core\Cache;
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\DB;
|
||||
use App\Core\Entity;
|
||||
use App\Core\Router\Router;
|
||||
use App\Core\Router;
|
||||
use App\Entity\Actor;
|
||||
use App\Entity\Note;
|
||||
use Component\Language\Entity\Language;
|
||||
|
@@ -22,7 +22,7 @@ declare(strict_types = 1);
|
||||
namespace Component\Tag\Entity;
|
||||
|
||||
use App\Core\Cache;
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\DB;
|
||||
use App\Core\Entity;
|
||||
use Component\Tag\Tag;
|
||||
use DateTimeInterface;
|
||||
|
@@ -24,11 +24,11 @@ declare(strict_types = 1);
|
||||
namespace Component\Tag;
|
||||
|
||||
use App\Core\Cache;
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\DB;
|
||||
use App\Core\Event;
|
||||
use function App\Core\I18n\_m;
|
||||
use App\Core\Modules\Component;
|
||||
use App\Core\Router\Router;
|
||||
use App\Core\Router;
|
||||
use App\Entity\Actor;
|
||||
use App\Entity\Note;
|
||||
use App\Util\Common;
|
||||
@@ -67,6 +67,54 @@ class Tag extends Component
|
||||
return Event::next;
|
||||
}
|
||||
|
||||
public static function maybeCreateTag(string $tag, int $note_id, ?int $lang_id): ?NoteTag
|
||||
{
|
||||
if (!self::validate($tag)) {
|
||||
return null; // Ignore invalid tag candidates
|
||||
}
|
||||
$canonical_tag = self::canonicalTag($tag, \is_null($lang_id) ? null : Language::getById($lang_id)->getLocale());
|
||||
DB::persist($note_tag = NoteTag::create([
|
||||
'tag' => $tag,
|
||||
'canonical' => $canonical_tag,
|
||||
'note_id' => $note_id,
|
||||
'use_canonical' => $extra_args['tag_use_canonical'] ?? false,
|
||||
'language_id' => $lang_id,
|
||||
]));
|
||||
foreach (self::cacheKeys($canonical_tag) as $key) {
|
||||
Cache::delete($key);
|
||||
}
|
||||
return $note_tag;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return NoteTag[]
|
||||
*/
|
||||
public static function getNoteTags(int $actor_id, ?string $note_type): array
|
||||
{
|
||||
$query = <<<'EOF'
|
||||
select nt from \App\Entity\Note n
|
||||
join \Component\Tag\Entity\NoteTag nt with n.id = nt.note_id
|
||||
where n.actor_id = :id
|
||||
EOF;
|
||||
if (\is_null($note_type)) {
|
||||
return Cache::getList(
|
||||
Actor::cacheKeys($actor_id, 'any')['note-tags'],
|
||||
fn () => DB::dql(
|
||||
$query,
|
||||
['id' => $actor_id],
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return Cache::getList(
|
||||
Actor::cacheKeys($actor_id, $note_type)['note-tags'],
|
||||
fn () => DB::dql(
|
||||
$query . ' and n.type = :type',
|
||||
['id' => $actor_id, 'type' => $note_type],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process note by extracting any tags present
|
||||
*/
|
||||
@@ -82,21 +130,7 @@ class Tag extends Component
|
||||
$matched_tags = array_unique(F\map($matched_tags, fn ($m) => $m[2]));
|
||||
foreach ($matched_tags as $match) {
|
||||
$tag = self::extract($match);
|
||||
if (!self::validate($tag)) {
|
||||
continue; // Ignore invalid tag candidates
|
||||
}
|
||||
$canonical_tag = self::canonicalTag($tag, \is_null($lang_id = $note->getLanguageId()) ? null : Language::getById($lang_id)->getLocale());
|
||||
DB::persist(NoteTag::create([
|
||||
'tag' => $tag,
|
||||
'canonical' => $canonical_tag,
|
||||
'note_id' => $note->getId(),
|
||||
'use_canonical' => $extra_args['tag_use_canonical'] ?? false,
|
||||
'language_id' => $lang_id,
|
||||
]));
|
||||
Cache::listPushLeft("tag-{$canonical_tag}", $note);
|
||||
foreach (self::cacheKeys($canonical_tag) as $key) {
|
||||
Cache::delete($key);
|
||||
}
|
||||
self::maybeCreateTag(tag: $tag, note_id: $note->getId(), lang_id: $note->getLanguageId());
|
||||
}
|
||||
return Event::next;
|
||||
}
|
||||
|
@@ -112,7 +112,8 @@
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"App\\Tests\\": "tests/"
|
||||
"App\\Test\\Fixtures\\": "tests/fixtures/",
|
||||
"App\\Test\\": "tests/"
|
||||
}
|
||||
},
|
||||
"replace": {
|
||||
|
231
composer.lock
generated
231
composer.lock
generated
@@ -553,16 +553,16 @@
|
||||
},
|
||||
{
|
||||
"name": "doctrine/dbal",
|
||||
"version": "3.3.2",
|
||||
"version": "3.3.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/doctrine/dbal.git",
|
||||
"reference": "35eae239ef515d55ebb24e9d4715cad09a4f58ed"
|
||||
"reference": "83f779beaea1893c0bece093ab2104c6d15a7f26"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/doctrine/dbal/zipball/35eae239ef515d55ebb24e9d4715cad09a4f58ed",
|
||||
"reference": "35eae239ef515d55ebb24e9d4715cad09a4f58ed",
|
||||
"url": "https://api.github.com/repos/doctrine/dbal/zipball/83f779beaea1893c0bece093ab2104c6d15a7f26",
|
||||
"reference": "83f779beaea1893c0bece093ab2104c6d15a7f26",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -577,14 +577,14 @@
|
||||
"require-dev": {
|
||||
"doctrine/coding-standard": "9.0.0",
|
||||
"jetbrains/phpstorm-stubs": "2021.1",
|
||||
"phpstan/phpstan": "1.4.0",
|
||||
"phpstan/phpstan": "1.4.6",
|
||||
"phpstan/phpstan-strict-rules": "^1.1",
|
||||
"phpunit/phpunit": "9.5.11",
|
||||
"phpunit/phpunit": "9.5.16",
|
||||
"psalm/plugin-phpunit": "0.16.1",
|
||||
"squizlabs/php_codesniffer": "3.6.2",
|
||||
"symfony/cache": "^5.2|^6.0",
|
||||
"symfony/console": "^2.7|^3.0|^4.0|^5.0|^6.0",
|
||||
"vimeo/psalm": "4.16.1"
|
||||
"vimeo/psalm": "4.22.0"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/console": "For helpful console commands such as SQL execution and import of files."
|
||||
@@ -644,7 +644,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/doctrine/dbal/issues",
|
||||
"source": "https://github.com/doctrine/dbal/tree/3.3.2"
|
||||
"source": "https://github.com/doctrine/dbal/tree/3.3.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -660,7 +660,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-02-05T16:33:45+00:00"
|
||||
"time": "2022-03-20T18:37:29+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/deprecations",
|
||||
@@ -1342,16 +1342,16 @@
|
||||
},
|
||||
{
|
||||
"name": "doctrine/orm",
|
||||
"version": "2.11.1",
|
||||
"version": "2.11.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/doctrine/orm.git",
|
||||
"reference": "4b88ce787d3916c8366abf52f6c658a7a27ed3a6"
|
||||
"reference": "9c351e044478135aec1755e2c0c0493a4b6309db"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/doctrine/orm/zipball/4b88ce787d3916c8366abf52f6c658a7a27ed3a6",
|
||||
"reference": "4b88ce787d3916c8366abf52f6c658a7a27ed3a6",
|
||||
"url": "https://api.github.com/repos/doctrine/orm/zipball/9c351e044478135aec1755e2c0c0493a4b6309db",
|
||||
"reference": "9c351e044478135aec1755e2c0c0493a4b6309db",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1367,7 +1367,6 @@
|
||||
"doctrine/lexer": "^1.0",
|
||||
"doctrine/persistence": "^2.2",
|
||||
"ext-ctype": "*",
|
||||
"ext-pdo": "*",
|
||||
"php": "^7.1 || ^8.0",
|
||||
"psr/cache": "^1 || ^2 || ^3",
|
||||
"symfony/console": "^3.0 || ^4.0 || ^5.0 || ^6.0",
|
||||
@@ -1381,12 +1380,12 @@
|
||||
"doctrine/annotations": "^1.13",
|
||||
"doctrine/coding-standard": "^9.0",
|
||||
"phpbench/phpbench": "^0.16.10 || ^1.0",
|
||||
"phpstan/phpstan": "1.4.3",
|
||||
"phpstan/phpstan": "1.4.6",
|
||||
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.4",
|
||||
"squizlabs/php_codesniffer": "3.6.2",
|
||||
"symfony/cache": "^4.4 || ^5.4 || ^6.0",
|
||||
"symfony/yaml": "^3.4 || ^4.0 || ^5.0 || ^6.0",
|
||||
"vimeo/psalm": "4.19.0"
|
||||
"vimeo/psalm": "4.22.0"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/cache": "Provides cache support for Setup Tool with doctrine/cache 2.0",
|
||||
@@ -1435,22 +1434,22 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/doctrine/orm/issues",
|
||||
"source": "https://github.com/doctrine/orm/tree/2.11.1"
|
||||
"source": "https://github.com/doctrine/orm/tree/2.11.2"
|
||||
},
|
||||
"time": "2022-01-30T21:47:06+00:00"
|
||||
"time": "2022-03-09T15:23:58+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/persistence",
|
||||
"version": "2.3.0",
|
||||
"version": "2.4.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/doctrine/persistence.git",
|
||||
"reference": "f8af155c1e7963f3d2b4415097d55757bbaa53d8"
|
||||
"reference": "092a52b71410ac1795287bb5135704ef07d18dd0"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/doctrine/persistence/zipball/f8af155c1e7963f3d2b4415097d55757bbaa53d8",
|
||||
"reference": "f8af155c1e7963f3d2b4415097d55757bbaa53d8",
|
||||
"url": "https://api.github.com/repos/doctrine/persistence/zipball/092a52b71410ac1795287bb5135704ef07d18dd0",
|
||||
"reference": "092a52b71410ac1795287bb5135704ef07d18dd0",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1463,23 +1462,23 @@
|
||||
},
|
||||
"conflict": {
|
||||
"doctrine/annotations": "<1.0 || >=2.0",
|
||||
"doctrine/common": "<2.10@dev"
|
||||
"doctrine/common": "<2.10"
|
||||
},
|
||||
"require-dev": {
|
||||
"composer/package-versions-deprecated": "^1.11",
|
||||
"doctrine/annotations": "^1.0",
|
||||
"doctrine/coding-standard": "^6.0 || ^9.0",
|
||||
"doctrine/coding-standard": "^9.0",
|
||||
"doctrine/common": "^3.0",
|
||||
"phpstan/phpstan": "1.2.0",
|
||||
"phpunit/phpunit": "^7.5.20 || ^8.0 || ^9.0",
|
||||
"symfony/cache": "^4.4 || ^5.0 || ^6.0",
|
||||
"vimeo/psalm": "4.13.1"
|
||||
"phpstan/phpstan": "1.4.6",
|
||||
"phpunit/phpunit": "^7.5.20 || ^8.5 || ^9.5",
|
||||
"symfony/cache": "^4.4 || ^5.4 || ^6.0",
|
||||
"vimeo/psalm": "4.21.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Doctrine\\Common\\": "lib/Doctrine/Common",
|
||||
"Doctrine\\Persistence\\": "lib/Doctrine/Persistence"
|
||||
"Doctrine\\Common\\": "src/Common",
|
||||
"Doctrine\\Persistence\\": "src/Persistence"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
@@ -1523,9 +1522,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/doctrine/persistence/issues",
|
||||
"source": "https://github.com/doctrine/persistence/tree/2.3.0"
|
||||
"source": "https://github.com/doctrine/persistence/tree/2.4.1"
|
||||
},
|
||||
"time": "2022-01-09T19:58:46+00:00"
|
||||
"time": "2022-03-22T06:44:40+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/sql-formatter",
|
||||
@@ -1649,16 +1648,16 @@
|
||||
},
|
||||
{
|
||||
"name": "embed/embed",
|
||||
"version": "v4.4.2",
|
||||
"version": "v4.4.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/oscarotero/Embed.git",
|
||||
"reference": "84631fa16f2a669de66218774a20b6c1c5f9ba03"
|
||||
"reference": "2ac32581a8617c3bbe593e3d7799ca9db6974471"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/oscarotero/Embed/zipball/84631fa16f2a669de66218774a20b6c1c5f9ba03",
|
||||
"reference": "84631fa16f2a669de66218774a20b6c1c5f9ba03",
|
||||
"url": "https://api.github.com/repos/oscarotero/Embed/zipball/2ac32581a8617c3bbe593e3d7799ca9db6974471",
|
||||
"reference": "2ac32581a8617c3bbe593e3d7799ca9db6974471",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1718,7 +1717,7 @@
|
||||
"support": {
|
||||
"email": "oom@oscarotero.com",
|
||||
"issues": "https://github.com/oscarotero/Embed/issues",
|
||||
"source": "https://github.com/oscarotero/Embed/tree/v4.4.2"
|
||||
"source": "https://github.com/oscarotero/Embed/tree/v4.4.3"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -1734,7 +1733,7 @@
|
||||
"type": "patreon"
|
||||
}
|
||||
],
|
||||
"time": "2022-02-13T16:03:59+00:00"
|
||||
"time": "2022-03-13T01:27:51+00:00"
|
||||
},
|
||||
{
|
||||
"name": "erusev/parsedown",
|
||||
@@ -1917,16 +1916,16 @@
|
||||
},
|
||||
{
|
||||
"name": "giggsey/libphonenumber-for-php",
|
||||
"version": "8.12.44",
|
||||
"version": "8.12.45",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/giggsey/libphonenumber-for-php.git",
|
||||
"reference": "a726990faf05bfffdd826f75d9b41a1580dad4a7"
|
||||
"reference": "7f494fd3b87c7d83472e8b6126eedc6b72dd3f3e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/giggsey/libphonenumber-for-php/zipball/a726990faf05bfffdd826f75d9b41a1580dad4a7",
|
||||
"reference": "a726990faf05bfffdd826f75d9b41a1580dad4a7",
|
||||
"url": "https://api.github.com/repos/giggsey/libphonenumber-for-php/zipball/7f494fd3b87c7d83472e8b6126eedc6b72dd3f3e",
|
||||
"reference": "7f494fd3b87c7d83472e8b6126eedc6b72dd3f3e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1986,7 +1985,7 @@
|
||||
"issues": "https://github.com/giggsey/libphonenumber-for-php/issues",
|
||||
"source": "https://github.com/giggsey/libphonenumber-for-php"
|
||||
},
|
||||
"time": "2022-02-24T09:38:54+00:00"
|
||||
"time": "2022-03-10T10:28:34+00:00"
|
||||
},
|
||||
{
|
||||
"name": "giggsey/locale",
|
||||
@@ -2044,16 +2043,16 @@
|
||||
},
|
||||
{
|
||||
"name": "guzzlehttp/guzzle",
|
||||
"version": "7.4.1",
|
||||
"version": "7.4.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/guzzle/guzzle.git",
|
||||
"reference": "ee0a041b1760e6a53d2a39c8c34115adc2af2c79"
|
||||
"reference": "ac1ec1cd9b5624694c3a40be801d94137afb12b4"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/ee0a041b1760e6a53d2a39c8c34115adc2af2c79",
|
||||
"reference": "ee0a041b1760e6a53d2a39c8c34115adc2af2c79",
|
||||
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/ac1ec1cd9b5624694c3a40be801d94137afb12b4",
|
||||
"reference": "ac1ec1cd9b5624694c3a40be801d94137afb12b4",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2148,7 +2147,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/guzzle/guzzle/issues",
|
||||
"source": "https://github.com/guzzle/guzzle/tree/7.4.1"
|
||||
"source": "https://github.com/guzzle/guzzle/tree/7.4.2"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -2164,7 +2163,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2021-12-06T18:43:05+00:00"
|
||||
"time": "2022-03-20T14:16:28+00:00"
|
||||
},
|
||||
{
|
||||
"name": "guzzlehttp/promises",
|
||||
@@ -2252,16 +2251,16 @@
|
||||
},
|
||||
{
|
||||
"name": "guzzlehttp/psr7",
|
||||
"version": "2.1.0",
|
||||
"version": "2.2.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/guzzle/psr7.git",
|
||||
"reference": "089edd38f5b8abba6cb01567c2a8aaa47cec4c72"
|
||||
"reference": "c94a94f120803a18554c1805ef2e539f8285f9a2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/guzzle/psr7/zipball/089edd38f5b8abba6cb01567c2a8aaa47cec4c72",
|
||||
"reference": "089edd38f5b8abba6cb01567c2a8aaa47cec4c72",
|
||||
"url": "https://api.github.com/repos/guzzle/psr7/zipball/c94a94f120803a18554c1805ef2e539f8285f9a2",
|
||||
"reference": "c94a94f120803a18554c1805ef2e539f8285f9a2",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2285,7 +2284,7 @@
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.1-dev"
|
||||
"dev-master": "2.2-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@@ -2347,7 +2346,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/guzzle/psr7/issues",
|
||||
"source": "https://github.com/guzzle/psr7/tree/2.1.0"
|
||||
"source": "https://github.com/guzzle/psr7/tree/2.2.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -2363,7 +2362,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2021-10-06T17:43:30+00:00"
|
||||
"time": "2022-03-20T21:55:58+00:00"
|
||||
},
|
||||
{
|
||||
"name": "jcupitt/vips",
|
||||
@@ -3322,16 +3321,16 @@
|
||||
},
|
||||
{
|
||||
"name": "monolog/monolog",
|
||||
"version": "2.3.5",
|
||||
"version": "2.4.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Seldaek/monolog.git",
|
||||
"reference": "fd4380d6fc37626e2f799f29d91195040137eba9"
|
||||
"reference": "d7fd7450628561ba697b7097d86db72662f54aef"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/fd4380d6fc37626e2f799f29d91195040137eba9",
|
||||
"reference": "fd4380d6fc37626e2f799f29d91195040137eba9",
|
||||
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/d7fd7450628561ba697b7097d86db72662f54aef",
|
||||
"reference": "d7fd7450628561ba697b7097d86db72662f54aef",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3353,7 +3352,7 @@
|
||||
"phpstan/phpstan": "^0.12.91",
|
||||
"phpunit/phpunit": "^8.5",
|
||||
"predis/predis": "^1.1",
|
||||
"rollbar/rollbar": "^1.3",
|
||||
"rollbar/rollbar": "^1.3 || ^2 || ^3",
|
||||
"ruflin/elastica": ">=0.90@dev",
|
||||
"swiftmailer/swiftmailer": "^5.3|^6.0"
|
||||
},
|
||||
@@ -3405,7 +3404,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/Seldaek/monolog/issues",
|
||||
"source": "https://github.com/Seldaek/monolog/tree/2.3.5"
|
||||
"source": "https://github.com/Seldaek/monolog/tree/2.4.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -3417,7 +3416,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2021-10-01T21:08:31+00:00"
|
||||
"time": "2022-03-14T12:44:37+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nikic/php-parser",
|
||||
@@ -3850,21 +3849,21 @@
|
||||
},
|
||||
{
|
||||
"name": "php-ds/php-ds",
|
||||
"version": "v1.4.0",
|
||||
"version": "v1.4.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-ds/polyfill.git",
|
||||
"reference": "298cafa4e0e20aeba4d63644e3de694e7cf83ffd"
|
||||
"reference": "43d2df301a9e2017f67b8c11d94a5222f9c00fd1"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-ds/polyfill/zipball/298cafa4e0e20aeba4d63644e3de694e7cf83ffd",
|
||||
"reference": "298cafa4e0e20aeba4d63644e3de694e7cf83ffd",
|
||||
"url": "https://api.github.com/repos/php-ds/polyfill/zipball/43d2df301a9e2017f67b8c11d94a5222f9c00fd1",
|
||||
"reference": "43d2df301a9e2017f67b8c11d94a5222f9c00fd1",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"php": "^7.3 || ~8.0.0 || ~8.1.0"
|
||||
"php": ">=7.0"
|
||||
},
|
||||
"provide": {
|
||||
"ext-ds": "1.3.0"
|
||||
@@ -3899,9 +3898,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/php-ds/polyfill/issues",
|
||||
"source": "https://github.com/php-ds/polyfill/tree/v1.4.0"
|
||||
"source": "https://github.com/php-ds/polyfill/tree/v1.4.1"
|
||||
},
|
||||
"time": "2021-11-17T19:52:15+00:00"
|
||||
"time": "2022-03-09T20:39:30+00:00"
|
||||
},
|
||||
{
|
||||
"name": "php-ffmpeg/php-ffmpeg",
|
||||
@@ -5021,16 +5020,16 @@
|
||||
},
|
||||
{
|
||||
"name": "spatie/temporary-directory",
|
||||
"version": "2.0.0",
|
||||
"version": "2.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/spatie/temporary-directory.git",
|
||||
"reference": "06fe0f10d068fdf145c9b2235030e568c913bb61"
|
||||
"reference": "79f138f2b81adae583d04d3727a4538dd394023f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/spatie/temporary-directory/zipball/06fe0f10d068fdf145c9b2235030e568c913bb61",
|
||||
"reference": "06fe0f10d068fdf145c9b2235030e568c913bb61",
|
||||
"url": "https://api.github.com/repos/spatie/temporary-directory/zipball/79f138f2b81adae583d04d3727a4538dd394023f",
|
||||
"reference": "79f138f2b81adae583d04d3727a4538dd394023f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -5066,7 +5065,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/spatie/temporary-directory/issues",
|
||||
"source": "https://github.com/spatie/temporary-directory/tree/2.0.0"
|
||||
"source": "https://github.com/spatie/temporary-directory/tree/2.1.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -5078,7 +5077,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2021-03-30T19:46:13+00:00"
|
||||
"time": "2022-03-11T08:16:01+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/asset",
|
||||
@@ -10716,16 +10715,16 @@
|
||||
},
|
||||
{
|
||||
"name": "twig/twig",
|
||||
"version": "v3.3.8",
|
||||
"version": "v3.3.9",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/twigphp/Twig.git",
|
||||
"reference": "972d8604a92b7054828b539f2febb0211dd5945c"
|
||||
"reference": "6ff9b0e440fa66f97f207e181c41340ddfa5683d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/twigphp/Twig/zipball/972d8604a92b7054828b539f2febb0211dd5945c",
|
||||
"reference": "972d8604a92b7054828b539f2febb0211dd5945c",
|
||||
"url": "https://api.github.com/repos/twigphp/Twig/zipball/6ff9b0e440fa66f97f207e181c41340ddfa5683d",
|
||||
"reference": "6ff9b0e440fa66f97f207e181c41340ddfa5683d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -10776,7 +10775,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/twigphp/Twig/issues",
|
||||
"source": "https://github.com/twigphp/Twig/tree/v3.3.8"
|
||||
"source": "https://github.com/twigphp/Twig/tree/v3.3.9"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -10788,7 +10787,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-02-04T06:59:48+00:00"
|
||||
"time": "2022-03-25T09:37:52+00:00"
|
||||
},
|
||||
{
|
||||
"name": "voku/portable-ascii",
|
||||
@@ -11243,16 +11242,16 @@
|
||||
},
|
||||
{
|
||||
"name": "composer/semver",
|
||||
"version": "3.2.9",
|
||||
"version": "3.3.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/composer/semver.git",
|
||||
"reference": "a951f614bd64dcd26137bc9b7b2637ddcfc57649"
|
||||
"reference": "5d8e574bb0e69188786b8ef77d43341222a41a71"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/composer/semver/zipball/a951f614bd64dcd26137bc9b7b2637ddcfc57649",
|
||||
"reference": "a951f614bd64dcd26137bc9b7b2637ddcfc57649",
|
||||
"url": "https://api.github.com/repos/composer/semver/zipball/5d8e574bb0e69188786b8ef77d43341222a41a71",
|
||||
"reference": "5d8e574bb0e69188786b8ef77d43341222a41a71",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -11304,7 +11303,7 @@
|
||||
"support": {
|
||||
"irc": "irc://irc.freenode.org/composer",
|
||||
"issues": "https://github.com/composer/semver/issues",
|
||||
"source": "https://github.com/composer/semver/tree/3.2.9"
|
||||
"source": "https://github.com/composer/semver/tree/3.3.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -11320,7 +11319,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-02-04T13:58:43+00:00"
|
||||
"time": "2022-03-16T11:22:07+00:00"
|
||||
},
|
||||
{
|
||||
"name": "composer/xdebug-handler",
|
||||
@@ -11555,16 +11554,16 @@
|
||||
},
|
||||
{
|
||||
"name": "friendsofphp/php-cs-fixer",
|
||||
"version": "v3.7.0",
|
||||
"version": "v3.8.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git",
|
||||
"reference": "7705d5a985132a40282d18a176eb9a4a0497747c"
|
||||
"reference": "cbad1115aac4b5c3c5540e7210d3c9fba2f81fa3"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/7705d5a985132a40282d18a176eb9a4a0497747c",
|
||||
"reference": "7705d5a985132a40282d18a176eb9a4a0497747c",
|
||||
"url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/cbad1115aac4b5c3c5540e7210d3c9fba2f81fa3",
|
||||
"reference": "cbad1115aac4b5c3c5540e7210d3c9fba2f81fa3",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -11632,7 +11631,7 @@
|
||||
"description": "A tool to automatically fix PHP code style",
|
||||
"support": {
|
||||
"issues": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/issues",
|
||||
"source": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/tree/v3.7.0"
|
||||
"source": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/tree/v3.8.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -11640,7 +11639,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2022-03-07T16:59:59+00:00"
|
||||
"time": "2022-03-18T17:20:59+00:00"
|
||||
},
|
||||
{
|
||||
"name": "jchook/phpunit-assert-throws",
|
||||
@@ -11999,12 +11998,12 @@
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpstan/phpstan.git",
|
||||
"reference": "996a6c62b7e832903b4cf60e5c5744a4521ff2cc"
|
||||
"reference": "a9503c3474dfca53db977ebd14987264e8e8d6bf"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/996a6c62b7e832903b4cf60e5c5744a4521ff2cc",
|
||||
"reference": "996a6c62b7e832903b4cf60e5c5744a4521ff2cc",
|
||||
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/a9503c3474dfca53db977ebd14987264e8e8d6bf",
|
||||
"reference": "a9503c3474dfca53db977ebd14987264e8e8d6bf",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -12013,17 +12012,11 @@
|
||||
"conflict": {
|
||||
"phpstan/phpstan-shim": "*"
|
||||
},
|
||||
"default-branch": true,
|
||||
"bin": [
|
||||
"phpstan",
|
||||
"phpstan.phar"
|
||||
],
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.4-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"bootstrap.php"
|
||||
@@ -12056,7 +12049,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-03-08T14:11:13+00:00"
|
||||
"time": "2022-03-12T12:05:50+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-code-coverage",
|
||||
@@ -12378,16 +12371,16 @@
|
||||
},
|
||||
{
|
||||
"name": "phpunit/phpunit",
|
||||
"version": "9.5.18",
|
||||
"version": "9.5.19",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
||||
"reference": "1b5856028273bfd855e60a887278857d872ec67a"
|
||||
"reference": "35ea4b7f3acabb26f4bb640f8c30866c401da807"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/1b5856028273bfd855e60a887278857d872ec67a",
|
||||
"reference": "1b5856028273bfd855e60a887278857d872ec67a",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/35ea4b7f3acabb26f4bb640f8c30866c401da807",
|
||||
"reference": "35ea4b7f3acabb26f4bb640f8c30866c401da807",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -12417,7 +12410,7 @@
|
||||
"sebastian/global-state": "^5.0.1",
|
||||
"sebastian/object-enumerator": "^4.0.3",
|
||||
"sebastian/resource-operations": "^3.0.3",
|
||||
"sebastian/type": "^2.3.4",
|
||||
"sebastian/type": "^3.0",
|
||||
"sebastian/version": "^3.0.2"
|
||||
},
|
||||
"require-dev": {
|
||||
@@ -12465,7 +12458,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
|
||||
"source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.18"
|
||||
"source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.19"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -12477,7 +12470,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2022-03-08T06:52:28+00:00"
|
||||
"time": "2022-03-15T09:57:31+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/cli-parser",
|
||||
@@ -13336,28 +13329,28 @@
|
||||
},
|
||||
{
|
||||
"name": "sebastian/type",
|
||||
"version": "2.3.4",
|
||||
"version": "3.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/type.git",
|
||||
"reference": "b8cd8a1c753c90bc1a0f5372170e3e489136f914"
|
||||
"reference": "b233b84bc4465aff7b57cf1c4bc75c86d00d6dad"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/type/zipball/b8cd8a1c753c90bc1a0f5372170e3e489136f914",
|
||||
"reference": "b8cd8a1c753c90bc1a0f5372170e3e489136f914",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/type/zipball/b233b84bc4465aff7b57cf1c4bc75c86d00d6dad",
|
||||
"reference": "b233b84bc4465aff7b57cf1c4bc75c86d00d6dad",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9.3"
|
||||
"phpunit/phpunit": "^9.5"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.3-dev"
|
||||
"dev-master": "3.0-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@@ -13380,7 +13373,7 @@
|
||||
"homepage": "https://github.com/sebastianbergmann/type",
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/type/issues",
|
||||
"source": "https://github.com/sebastianbergmann/type/tree/2.3.4"
|
||||
"source": "https://github.com/sebastianbergmann/type/tree/3.0.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -13388,7 +13381,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2021-06-15T12:49:02+00:00"
|
||||
"time": "2022-03-15T09:54:48+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/version",
|
||||
|
@@ -20,15 +20,13 @@ security:
|
||||
dev:
|
||||
pattern: ^/(_(profiler|wdt)|css|images|js)/
|
||||
security: false
|
||||
oauth:
|
||||
pattern: ^/oauth
|
||||
security: false
|
||||
main:
|
||||
lazy: true
|
||||
provider: local_user
|
||||
form_login:
|
||||
login_path: security_login
|
||||
check_path: security_login
|
||||
default_target_path: root
|
||||
logout:
|
||||
path: security_logout
|
||||
# where to redirect after logout
|
||||
|
@@ -15,13 +15,16 @@ services:
|
||||
resource: '../src/*'
|
||||
exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php,Routes}'
|
||||
|
||||
App\Test\Fixtures\:
|
||||
resource: '../tests/fixtures/*'
|
||||
|
||||
# controllers are imported separately to make sure services can be injected
|
||||
# as action arguments even if you don't extend any base controller class
|
||||
App\Controller\:
|
||||
resource: '../src/Controller'
|
||||
tags: ['controller.service_arguments']
|
||||
|
||||
App\Core\Router\RouteLoader:
|
||||
App\Core\Router:
|
||||
tags: ['routing.loader']
|
||||
|
||||
# Wrapper around Doctrine's StaticPHP metadata driver
|
||||
|
@@ -1,3 +1,18 @@
|
||||
server {
|
||||
# Listen only on port 81 for localhost, and nothing else.
|
||||
server_name 127.0.0.1;
|
||||
listen 127.0.0.1:81 default_server;
|
||||
|
||||
charset utf-8;
|
||||
|
||||
# Certbot's folder used for the ACME challenge response.
|
||||
location ^~ /.well-known/acme-challenge {
|
||||
default_type text/plain;
|
||||
root /var/www/certbot;
|
||||
try_files $uri =404;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
|
||||
listen [::]:80;
|
||||
@@ -5,6 +20,10 @@ server {
|
||||
|
||||
server_name %hostname%;
|
||||
|
||||
location '/.well-known/acme-challenge' {
|
||||
proxy_pass http://localhost:81;
|
||||
}
|
||||
|
||||
# redirect all traffic to HTTPS
|
||||
rewrite ^ https://$host$request_uri? permanent;
|
||||
}
|
||||
@@ -35,6 +54,13 @@ server {
|
||||
root /var/www/social;
|
||||
}
|
||||
|
||||
location /.well-known/acme-challenge/ {
|
||||
allow all;
|
||||
root /var/www/certbot;
|
||||
try_files $uri =404;
|
||||
break;
|
||||
}
|
||||
|
||||
# PHP
|
||||
location ~ ^/(index|install)\.php(/.*)?$ {
|
||||
include fastcgi_params;
|
||||
|
@@ -2,8 +2,7 @@
|
||||
|
||||
case "${DBMS}" in
|
||||
'postgres')
|
||||
PGPASSWORD="${POSTGRES_PASSWORD}" psql -ltq -Upostgres -hdb | \
|
||||
cut -d '|' -f1 | grep -Fwq "${SOCIAL_DB}"
|
||||
test "$(PGPASSWORD="${POSTGRES_PASSWORD}" psql -Upostgres -hdb -tAc "select 1 from pg_database where datname='${SOCIAL_DB}'")" = "1"
|
||||
DB_EXISTS=$?
|
||||
;;
|
||||
'mariadb')
|
||||
@@ -28,7 +27,8 @@ if [ ${DB_EXISTS} -ne 0 ]; then
|
||||
chmod g+w -R .
|
||||
chown -R :www-data .
|
||||
|
||||
php bin/console doctrine:database:create || exit 1
|
||||
php bin/console doctrine:database:drop -f
|
||||
php bin/console doctrine:database:create
|
||||
php bin/console doctrine:schema:create || exit 1
|
||||
php bin/console app:populate_initial_values || exit 1
|
||||
|
||||
|
@@ -3,8 +3,10 @@
|
||||
cd /var/www/social || exit 1
|
||||
|
||||
printf "Cleaning Redis cache: " && echo "FLUSHALL" | nc redis 6379
|
||||
yes yes | php bin/console doctrine:fixtures:load || exit 1
|
||||
php bin/console app:populate_initial_values # since loading fixtures purges the DB
|
||||
bin/console doctrine:database:drop --force || exit 1
|
||||
bin/console doctrine:database:create || exit 1
|
||||
bin/console doctrine:schema:update --force || exit 1
|
||||
yes yes | bin/console doctrine:fixtures:load || exit 1
|
||||
|
||||
if [ "$#" -eq 0 ] || [ -z "$*" ]; then
|
||||
vendor/bin/simple-phpunit -vvv --coverage-html .test_coverage_report
|
||||
|
@@ -34,15 +34,14 @@ namespace Plugin\ActivityPub;
|
||||
|
||||
use ActivityPhp\Type;
|
||||
use ActivityPhp\Type\AbstractObject;
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\DB;
|
||||
use App\Core\Event;
|
||||
use App\Core\HTTPClient;
|
||||
use function App\Core\I18n\_m;
|
||||
use App\Core\Log;
|
||||
use App\Core\Modules\Plugin;
|
||||
use App\Core\Queue\Queue;
|
||||
use App\Core\Router\RouteLoader;
|
||||
use App\Core\Router\Router;
|
||||
use App\Core\Queue;
|
||||
use App\Core\Router;
|
||||
use App\Entity\Activity;
|
||||
use App\Entity\Actor;
|
||||
use App\Entity\Note;
|
||||
@@ -104,7 +103,7 @@ class ActivityPub extends Plugin
|
||||
'User-Agent' => 'GNUsocialBot ' . GNUSOCIAL_VERSION . ' - ' . GNUSOCIAL_PROJECT_URL,
|
||||
];
|
||||
|
||||
public function version(): string
|
||||
public static function version(): string
|
||||
{
|
||||
return '3.0.0';
|
||||
}
|
||||
@@ -141,14 +140,12 @@ class ActivityPub extends Plugin
|
||||
$ap_actor->getActorId(),
|
||||
Discovery::normalize($actor->getNickname() . '@' . parse_url($ap_actor->getInboxUri(), \PHP_URL_HOST)),
|
||||
);
|
||||
$already_known_ids = [];
|
||||
if (!empty($ap_act->_object_mention_ids)) {
|
||||
$already_known_ids = $ap_act->_object_mention_ids;
|
||||
}
|
||||
|
||||
DB::flush();
|
||||
if (Event::handle('ActivityPubNewNotification', [$actor, $ap_act->getActivity(), $already_known_ids, _m('{nickname} attentioned you.', ['{nickname}' => $actor->getNickname()])]) === Event::next) {
|
||||
Event::handle('NewNotification', [$actor, $ap_act->getActivity(), $already_known_ids, _m('{nickname} attentioned you.', ['{nickname}' => $actor->getNickname()])]);
|
||||
if (($att_targets = $ap_act->getAttentionTargets()) !== []) {
|
||||
if (Event::handle('ActivityPubNewNotification', [$actor, ($act = $ap_act->getActivity()), $att_targets, _m('{actor_id} triggered a notification via ActivityPub.', ['{actor_id}' => $actor->getId()])]) === Event::next) {
|
||||
Event::handle('NewNotification', [$actor, $act, $att_targets, _m('{actor_id} triggered a notification via ActivityPub.', ['{nickname}' => $actor->getId()])]);
|
||||
}
|
||||
}
|
||||
|
||||
return Event::stop;
|
||||
@@ -158,9 +155,9 @@ class ActivityPub extends Plugin
|
||||
* This code executes when GNU social creates the page routing, and we hook
|
||||
* on this event to add our Inbox and Outbox handler for ActivityPub.
|
||||
*
|
||||
* @param RouteLoader $r the router that was initialized
|
||||
* @param Router $r the router that was initialized
|
||||
*/
|
||||
public function onAddRoute(RouteLoader $r): bool
|
||||
public function onAddRoute(Router $r): bool
|
||||
{
|
||||
$r->connect(
|
||||
'activitypub_inbox',
|
||||
@@ -324,15 +321,24 @@ class ActivityPub extends Plugin
|
||||
string $inbox,
|
||||
array $to_actors,
|
||||
array &$retry_args,
|
||||
): bool
|
||||
{
|
||||
): bool {
|
||||
try {
|
||||
$data = Model::toJson($activity);
|
||||
if ($sender->isGroup()) {
|
||||
// When the sender is a group, we have to wrap it in an Announce activity
|
||||
$data = Type::create('Announce', ['object' => $data])->toJson();
|
||||
$data = Model::toType($activity);
|
||||
if ($sender->isGroup()) { // When the sender is a group,
|
||||
if ($activity->getVerb() === 'subscribe') {
|
||||
// Regular postman happens
|
||||
} elseif ($activity->getVerb() === 'undo' && $data->get('object')->get('type') === 'Follow') {
|
||||
// Regular postman happens
|
||||
} else {
|
||||
// For every other activity sent by a Group, we have to wrap it in a transient Announce activity
|
||||
$data = Type::create('Announce', [
|
||||
'@context' => 'https:\/\/www.w3.org\/ns\/activitystreams',
|
||||
'actor' => $sender->getUri(type: Router::ABSOLUTE_URL),
|
||||
'object' => $data,
|
||||
]);
|
||||
}
|
||||
}
|
||||
$res = self::postman($sender, $data, $inbox);
|
||||
$res = self::postman($sender, $data->toJson(), $inbox);
|
||||
|
||||
// accumulate errors for later use, if needed
|
||||
$status_code = $res->getStatusCode();
|
||||
@@ -380,6 +386,7 @@ class ActivityPub extends Plugin
|
||||
// the actor, that could for example mean that OStatus handled this actor while we were deactivated
|
||||
// On next interaction this should be resolved, for now continue
|
||||
if (\is_null($ap_target = DB::findOneBy(ActivitypubActor::class, ['actor_id' => $actor->getId()], return_null: true))) {
|
||||
Log::info('FreeNetwork wrongly told ActivityPub that it can handle actor id: ' . $actor->getId() . ' you might want to keep an eye on it.');
|
||||
continue;
|
||||
}
|
||||
$to_addr[$ap_target->getInboxSharedUri() ?? $ap_target->getInboxUri()][] = $actor;
|
||||
@@ -391,7 +398,7 @@ class ActivityPub extends Plugin
|
||||
foreach ($to_addr as $inbox => $to_actors) {
|
||||
Queue::enqueue(
|
||||
payload: [$sender, $activity, $inbox, $to_actors],
|
||||
queue: 'activitypub_postman',
|
||||
queue: 'ActivitypubPostman',
|
||||
priority: false,
|
||||
);
|
||||
}
|
||||
@@ -471,7 +478,7 @@ class ActivityPub extends Plugin
|
||||
try {
|
||||
if (FreeNetworkActorProtocol::canIAddr('activitypub', $addr = Discovery::normalize($target))) {
|
||||
$ap_actor = DB::wrapInTransaction(fn () => ActivitypubActor::getByAddr($addr));
|
||||
$actor = Actor::getById($ap_actor->getActorId());
|
||||
$actor = Actor::getById($ap_actor->getActorId());
|
||||
FreeNetworkActorProtocol::protocolSucceeded('activitypub', $actor->getId(), $addr);
|
||||
return Event::stop;
|
||||
} else {
|
||||
@@ -530,7 +537,7 @@ class ActivityPub extends Plugin
|
||||
*
|
||||
* @return null|Actor|mixed|Note got from URI
|
||||
*/
|
||||
public static function getObjectByUri(string $resource, bool $try_online = true)
|
||||
public static function getObjectByUri(string $resource, bool $try_online = true): mixed
|
||||
{
|
||||
// Try known object
|
||||
$known_object = DB::findOneBy(ActivitypubObject::class, ['object_uri' => $resource], return_null: true);
|
||||
@@ -544,18 +551,6 @@ class ActivityPub extends Plugin
|
||||
return $known_activity->getActivity();
|
||||
}
|
||||
|
||||
// Try local Note
|
||||
if (Common::isValidHttpUrl($resource)) {
|
||||
$resource_parts = parse_url($resource);
|
||||
// TODO: Use URLMatcher
|
||||
if ($resource_parts['host'] === Common::config('site', 'server')) {
|
||||
$local_note = DB::findOneBy('note', ['url' => $resource], return_null: true);
|
||||
if (!\is_null($local_note)) {
|
||||
return $local_note;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Try Actor
|
||||
try {
|
||||
return Explorer::getOneFromUri($resource, try_online: false);
|
||||
@@ -563,20 +558,50 @@ class ActivityPub extends Plugin
|
||||
// Ignore, this is brute forcing, it's okay not to find
|
||||
}
|
||||
|
||||
// Try remote
|
||||
if (!$try_online) {
|
||||
return;
|
||||
// Is it a HTTP URL?
|
||||
if (Common::isValidHttpUrl($resource)) {
|
||||
$resource_parts = parse_url($resource);
|
||||
// If it is local
|
||||
if ($resource_parts['host'] === Common::config('site', 'server')) {
|
||||
// Try Local Note
|
||||
$local_note = DB::findOneBy(Note::class, ['url' => $resource], return_null: true);
|
||||
if (!\is_null($local_note)) {
|
||||
return $local_note;
|
||||
}
|
||||
|
||||
// Try local Activity
|
||||
try {
|
||||
$match = Router::match($resource_parts['path']);
|
||||
$local_activity = DB::findOneBy(Activity::class, ['id' => $match['id']], return_null: true);
|
||||
if (!\is_null($local_activity)) {
|
||||
return $local_activity;
|
||||
} else {
|
||||
throw new InvalidArgumentException('Tried to retrieve a non-existent local activity.');
|
||||
}
|
||||
} catch (\Exception) {
|
||||
// Ignore, this is brute forcing, it's okay not to find
|
||||
}
|
||||
|
||||
throw new BugFoundException('ActivityPub failed to retrieve local resource: "' . $resource . '". This is a big issue.');
|
||||
} else {
|
||||
// Then it's remote
|
||||
if (!$try_online) {
|
||||
throw new Exception("Remote resource {$resource} not found without online resources.");
|
||||
}
|
||||
|
||||
$response = HTTPClient::get($resource, ['headers' => self::HTTP_CLIENT_HEADERS]);
|
||||
// If it was deleted
|
||||
if ($response->getStatusCode() == 410) {
|
||||
//$obj = Type::create('Tombstone', ['id' => $resource]);
|
||||
return null;
|
||||
} elseif (!HTTPClient::statusCodeIsOkay($response)) { // If it is unavailable
|
||||
throw new Exception('Non Ok Status Code for given Object id.');
|
||||
} else {
|
||||
return Model::jsonToType($response->getContent());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$response = HTTPClient::get($resource, ['headers' => self::HTTP_CLIENT_HEADERS]);
|
||||
// If it was deleted
|
||||
if ($response->getStatusCode() == 410) {
|
||||
//$obj = Type::create('Tombstone', ['id' => $resource]);
|
||||
return;
|
||||
} elseif (!HTTPClient::statusCodeIsOkay($response)) { // If it is unavailable
|
||||
throw new Exception('Non Ok Status Code for given Object id.');
|
||||
} else {
|
||||
return Model::jsonToType($response->getContent());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@@ -33,12 +33,11 @@ declare(strict_types = 1);
|
||||
namespace Plugin\ActivityPub\Controller;
|
||||
|
||||
use App\Core\Controller;
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\DB;
|
||||
use function App\Core\I18n\_m;
|
||||
use App\Core\Log;
|
||||
use App\Core\Queue\Queue;
|
||||
use App\Core\Router\Router;
|
||||
use App\Entity\Actor;
|
||||
use App\Core\Queue;
|
||||
use App\Core\Router;
|
||||
use App\Util\Common;
|
||||
use App\Util\Exception\ClientException;
|
||||
use Exception;
|
||||
@@ -99,7 +98,7 @@ class Inbox extends Controller
|
||||
try {
|
||||
$resource_parts = parse_url($type->get('actor'));
|
||||
if ($resource_parts['host'] !== Common::config('site', 'server')) {
|
||||
$actor = DB::wrapInTransaction(fn () => Explorer::getOneFromUri($type->get('actor')));
|
||||
$actor = DB::wrapInTransaction(fn () => Explorer::getOneFromUri($type->get('actor')));
|
||||
$ap_actor = DB::findOneBy(ActivitypubActor::class, ['actor_id' => $actor->getId()]);
|
||||
} else {
|
||||
throw new Exception('Only remote actors can use this endpoint.');
|
||||
@@ -164,7 +163,7 @@ class Inbox extends Controller
|
||||
|
||||
Queue::enqueue(
|
||||
payload: [$ap_actor, $actor, $type],
|
||||
queue: 'activitypub_inbox',
|
||||
queue: 'ActivitypubInbox',
|
||||
priority: false,
|
||||
);
|
||||
|
||||
|
@@ -34,7 +34,7 @@ namespace Plugin\ActivityPub\Controller;
|
||||
|
||||
use function App\Core\I18n\_m;
|
||||
use App\Core\Log;
|
||||
use App\Core\Router\Router;
|
||||
use App\Core\Router;
|
||||
use App\Entity\Activity;
|
||||
use App\Entity\Actor;
|
||||
use App\Util\Exception\ClientException;
|
||||
|
@@ -32,7 +32,7 @@ declare(strict_types = 1);
|
||||
|
||||
namespace Plugin\ActivityPub\Entity;
|
||||
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\DB;
|
||||
use App\Core\Entity;
|
||||
use App\Entity\Activity;
|
||||
use DateTimeInterface;
|
||||
@@ -101,27 +101,17 @@ class ActivitypubActivity extends Entity
|
||||
|
||||
public function getActivity(): Activity
|
||||
{
|
||||
return DB::findOneBy('activity', ['id' => $this->getActivityId()]);
|
||||
return DB::findOneBy(Activity::class, ['id' => $this->getActivityId()]);
|
||||
}
|
||||
|
||||
public array $_object_mention_ids = [];
|
||||
public function setObjectMentionIds(array $mentions): self
|
||||
public function getAttentionTargetIds(): array
|
||||
{
|
||||
$this->_object_mention_ids = $mentions;
|
||||
return $this;
|
||||
return $this->getActivity()->getAttentionTargetIds();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Entity->getNotificationTargetIds
|
||||
*/
|
||||
public function getNotificationTargetIds(array $ids_already_known = [], ?int $sender_id = null, bool $include_additional = true): array
|
||||
public function getAttentionTargets(): array
|
||||
{
|
||||
// Additional actors that should know about this
|
||||
if (\array_key_exists('additional', $ids_already_known)) {
|
||||
return $ids_already_known['additional'];
|
||||
} else {
|
||||
return $this->_object_mention_ids;
|
||||
}
|
||||
return $this->getActivity()->getAttentionTargets();
|
||||
}
|
||||
|
||||
public static function schemaDef(): array
|
||||
|
@@ -33,7 +33,7 @@ declare(strict_types = 1);
|
||||
namespace Plugin\ActivityPub\Entity;
|
||||
|
||||
use App\Core\Cache;
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\DB;
|
||||
use App\Core\Entity;
|
||||
use function App\Core\I18n\_m;
|
||||
use App\Core\Log;
|
||||
|
@@ -32,7 +32,7 @@ declare(strict_types = 1);
|
||||
|
||||
namespace Plugin\ActivityPub\Entity;
|
||||
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\DB;
|
||||
use App\Core\Entity;
|
||||
use DateTimeInterface;
|
||||
|
||||
@@ -115,6 +115,16 @@ class ActivitypubObject extends Entity
|
||||
return DB::findOneBy($this->getObjectType(), ['id' => $this->getObjectId()]);
|
||||
}
|
||||
|
||||
public function getAttentionTargetIds(): array
|
||||
{
|
||||
return $this->getObject()->getAttentionTargetIds();
|
||||
}
|
||||
|
||||
public function getAttentionTargets(): array
|
||||
{
|
||||
return $this->getObject()->getAttentionTargets();
|
||||
}
|
||||
|
||||
public static function schemaDef(): array
|
||||
{
|
||||
return [
|
||||
|
@@ -32,7 +32,7 @@ declare(strict_types = 1);
|
||||
|
||||
namespace Plugin\ActivityPub\Entity;
|
||||
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\DB;
|
||||
use App\Core\Entity;
|
||||
use App\Core\Log;
|
||||
use App\Entity\Actor;
|
||||
|
70
plugins/ActivityPub/Test/Fixtures/ActivityPubFixtures.php
Normal file
70
plugins/ActivityPub/Test/Fixtures/ActivityPubFixtures.php
Normal file
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace Plugin\ActivityPub\Test\Fixtures;
|
||||
|
||||
use App\Core\DB;
|
||||
use Doctrine\Bundle\FixturesBundle\Fixture;
|
||||
use Doctrine\Persistence\ObjectManager;
|
||||
use Plugin\ActivityPub\Util\Model\Activity;
|
||||
use Plugin\ActivityPub\Util\Model\Actor;
|
||||
use Plugin\ActivityPub\Util\Model\Note;
|
||||
|
||||
class ActivityPubFixtures extends Fixture
|
||||
{
|
||||
private static string $fixtures_path = __DIR__ . \DIRECTORY_SEPARATOR;
|
||||
|
||||
public static function fixturesPath(string $path, string $ontology = 'gnusocial'): string
|
||||
{
|
||||
return self::$fixtures_path . $ontology . \DIRECTORY_SEPARATOR . $path;
|
||||
}
|
||||
|
||||
public function load(ObjectManager $manager)
|
||||
{
|
||||
/*
|
||||
* Beware that it's important to Load Actors, Objects, Activities in this sequence
|
||||
* because we're running offline tests here.
|
||||
*/
|
||||
$ontology = 'gnusocial';
|
||||
|
||||
// Load Actors
|
||||
$person_path = self::fixturesPath('objects/person.jsonld', $ontology);
|
||||
$person = Actor::fromJson(fread(fopen($person_path, 'r'), filesize($person_path)));
|
||||
DB::flush();
|
||||
$another_person_path = self::fixturesPath('objects/another_person.jsonld', $ontology);
|
||||
$another_person = Actor::fromJson(fread(fopen($another_person_path, 'r'), filesize($another_person_path)));
|
||||
DB::flush();
|
||||
$group_path = self::fixturesPath('objects/group.jsonld', $ontology);
|
||||
$group = Actor::fromJson(fread(fopen($group_path, 'r'), filesize($group_path)));
|
||||
DB::flush();
|
||||
|
||||
// Load Objects
|
||||
$note_path = self::fixturesPath('objects/note.jsonld', $ontology);
|
||||
$note = Note::fromJson(fread(fopen($note_path, 'r'), filesize($note_path)));
|
||||
DB::flush();
|
||||
$article_path = self::fixturesPath('objects/article.jsonld', $ontology);
|
||||
$article = Note::fromJson(fread(fopen($article_path, 'r'), filesize($article_path)));
|
||||
DB::flush();
|
||||
$reply_path = self::fixturesPath('objects/reply.jsonld', $ontology);
|
||||
$reply = Note::fromJson(fread(fopen($reply_path, 'r'), filesize($reply_path)));
|
||||
DB::flush();
|
||||
$note_with_mention_path = self::fixturesPath('objects/note_with_mention.jsonld', $ontology);
|
||||
$note_with_mention = Note::fromJson(fread(fopen($note_with_mention_path, 'r'), filesize($note_with_mention_path)));
|
||||
DB::flush();
|
||||
|
||||
// Load Activities
|
||||
$create_note_path = self::fixturesPath('activities/create_note.jsonld', $ontology);
|
||||
$create_note = Activity::fromJson(fread(fopen($create_note_path, 'r'), filesize($create_note_path)));
|
||||
DB::flush();
|
||||
$create_article_path = self::fixturesPath('activities/create_article.jsonld', $ontology);
|
||||
$create_article = Activity::fromJson(fread(fopen($create_article_path, 'r'), filesize($create_article_path)));
|
||||
DB::flush();
|
||||
$create_reply_path = self::fixturesPath('activities/create_reply.jsonld', $ontology);
|
||||
$create_reply = Activity::fromJson(fread(fopen($create_reply_path, 'r'), filesize($create_reply_path)));
|
||||
DB::flush();
|
||||
$like_note_path = self::fixturesPath('activities/like_note.jsonld', $ontology);
|
||||
$like_note = Activity::fromJson(fread(fopen($like_note_path, 'r'), filesize($like_note_path)));
|
||||
DB::flush();
|
||||
}
|
||||
}
|
82
plugins/ActivityPub/Test/Fixtures/friendica/activities/create_note.jsonld
Executable file
82
plugins/ActivityPub/Test/Fixtures/friendica/activities/create_note.jsonld
Executable file
@@ -0,0 +1,82 @@
|
||||
{
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://w3id.org/security/v1",
|
||||
{
|
||||
"vcard": "http://www.w3.org/2006/vcard/ns#",
|
||||
"dfrn": "http://purl.org/macgirvin/dfrn/1.0/",
|
||||
"diaspora": "https://diasporafoundation.org/ns/",
|
||||
"litepub": "http://litepub.social/ns#",
|
||||
"toot": "http://joinmastodon.org/ns#",
|
||||
"schema": "http://schema.org#",
|
||||
"manuallyApprovesFollowers": "as:manuallyApprovesFollowers",
|
||||
"sensitive": "as:sensitive",
|
||||
"Hashtag": "as:Hashtag",
|
||||
"directMessage": "litepub:directMessage",
|
||||
"discoverable": "toot:discoverable",
|
||||
"PropertyValue": "schema:PropertyValue",
|
||||
"value": "schema:value"
|
||||
}
|
||||
],
|
||||
"id": "https://soc.schuerz.at/objects/4edd2508-4361-edb8-c4d8-b45181083984/Create",
|
||||
"type": "Create",
|
||||
"actor": "https://soc.schuerz.at/profile/jakob",
|
||||
"published": "2022-01-23T20:21:24Z",
|
||||
"instrument": {
|
||||
"type": "Service",
|
||||
"name": "Friendica 'Siberian Iris' 2021.12-rc-1448",
|
||||
"url": "https://soc.schuerz.at"
|
||||
},
|
||||
"to": [
|
||||
"https://lemmy.schuerz.at/u/jakob",
|
||||
"https://www.w3.org/ns/activitystreams#Public",
|
||||
"https://lemmy.schuerz.at/c/test"
|
||||
],
|
||||
"cc": [
|
||||
"https://soc.schuerz.at/followers/jakob"
|
||||
],
|
||||
"object": {
|
||||
"id": "https://soc.schuerz.at/objects/4edd2508-4361-edb8-c4d8-b45181083984",
|
||||
"type": "Note",
|
||||
"summary": "",
|
||||
"inReplyTo": "https://lemmy.schuerz.at/post/25360",
|
||||
"diaspora:guid": "4edd2508-4361-edb8-c4d8-b45181083984",
|
||||
"published": "2022-01-23T20:21:24Z",
|
||||
"url": "https://soc.schuerz.at/display/4edd2508-4361-edb8-c4d8-b45181083984",
|
||||
"attributedTo": "https://soc.schuerz.at/profile/jakob",
|
||||
"sensitive": false,
|
||||
"context": "https://lemmy.schuerz.at/post/25360#context",
|
||||
"content": "<span class=\"h-card\"><a href=\"https://lemmy.schuerz.at/u/jakob\" class=\"u-url mention\">@<span>jakob</span></a></span> test",
|
||||
"contentMap": {
|
||||
"de": "<bdi>@<a href=\"https://lemmy.schuerz.at/u/jakob\" class=\"userinfo mention\" title=\"jakob\">jakob</a></bdi> test"
|
||||
},
|
||||
"source": {
|
||||
"content": "@[url=https://lemmy.schuerz.at/u/jakob]Jakob[/url] test",
|
||||
"mediaType": "text/bbcode"
|
||||
},
|
||||
"diaspora:comment": "{\"author\":\"jakob@soc.schuerz.at\",\"guid\":\"4edd2508-4361-edb8-c4d8-b45181083984\",\"created_at\":\"2022-01-23T20:21:24Z\",\"edited_at\":\"2022-01-23T20:21:24Z\",\"parent_guid\":\"ea620d1e-742c8b4d15249a9b-18b5fca3\",\"text\":\"@{Jakob; jakob@lemmy.schuerz.at} test\",\"author_signature\":\"JNCqOui5Cg8\\/Uxw+f0NtGCRjRnhPOrqE6kGJnMkZvOOKhlCdZbCqvyPlNJzEYDa3Z30mOWQKTTNo5BVI+VVZtGrVEqFOdzNog7jOLQoY1dKU9iEQ9vc8USwUCkyJyv48w1iXpfea87KPwv+03DMlftmD6kC7jdUVwhc7+jm0g4fh06tpOcCMQJOZqTTV\\/80EjxIJQ+8eEk5evSw\\/S98ohD1ahcwSomJ9hJUV1H48ucDvMod1FCLcN5h4ALHqubCu4TZIYhGhw9zoCl52GeHhrD3\\/vL6OW4ftZ7UG4rEKQ4HowuXqmNwydrQldtprRtu2UrZBjLqVusPXEs\\/xERQqZnalNXHijyd1TwwCmfTV4YjKwH4BhX\\/p4hdWMqEP4yYXlfA4apalVeAaYZLrNR58kPJjBHad\\/yqH30ziBFheqZ5odFh\\/jnKB4OCFVST3u9b1OKE0jyTrbTepPTaONwc8giQH1sM8koj1gFdulwuJuOTRUKR\\/8ishgHi5SWwbp5YG5Z3YSINkF10IcLiFZAF300AvwgOCdf7ferim4i\\/7TR1D2CBpoNUZnKCKZRymZbE0GuKEE+A6Pk3lk\\/DCsDtmMXpnxlPZ8Nq8OZS\\/olXevAu1y57MNnxBDXtojr4F54MP2fO7E2JwBr7AlwoeSEvtZSAO\\/elzrKfW0eVWOUM2OnI=\"}",
|
||||
"attachment": [],
|
||||
"tag": [
|
||||
{
|
||||
"type": "Mention",
|
||||
"href": "https://lemmy.schuerz.at/u/jakob",
|
||||
"name": "@jakob@lemmy.schuerz.at"
|
||||
}
|
||||
],
|
||||
"to": [
|
||||
"https://lemmy.schuerz.at/u/jakob",
|
||||
"https://www.w3.org/ns/activitystreams#Public",
|
||||
"https://lemmy.schuerz.at/c/test"
|
||||
],
|
||||
"cc": [
|
||||
"https://soc.schuerz.at/followers/jakob"
|
||||
]
|
||||
},
|
||||
"signature": {
|
||||
"type": "RsaSignature2017",
|
||||
"nonce": "fe42f1478453c9c5e92efdc8a1b00c7e2dd2ce89501f2437c4438b8add1c8ff7",
|
||||
"creator": "https://soc.schuerz.at/profile/jakob#main-key",
|
||||
"created": "2022-01-23T20:21:25Z",
|
||||
"signatureValue": "iWeNKyfH/d5+f6FDmZIadF4hW7XBliL8w3PQ2QkeKQG7fheqx1MB6825JX+Eaq8C0aNESesTTiDJgy3Xdcw8tgKwAVdji2DNZh7rNbSy57AzXlXOPRDnGJUbXp8gAuW2PJNZx3TTsJ5yM7tKLmHk0PpwsnKbvjFabL5O+htyfRZNVjFAsB9bVym/dBvf4jiTZiLufGDprgsaDVygUi3QrzmwsE41NZtL/MIEtbiC5pROWQvdQBEzeLfMDsnjI4CR+3tnaSlvepipuFxeSFpwl5Ae5+YM6IYRvSDsssjr8kAg1t3XnHUyeBdBdys0A6ryR5t5QuY0ygAHFs+X633JsgHDuCxxHiqNYxFuTs1xO0gmHydFy1iKlEt2rbr9pcX05hSvEFg0bI8HEC5M9GuafpY7sOyLX0jobBUH9CxdHUu0qri4ntORlvvAYsGFNHj+folFlMRBNMkcZ+MbrAxdoXBdjhsAp+tD6nje+PeZy63yJJQmPLQi9E+fHGGe0DAobGrBE/XF8X1ABH+ywyKwVu0t6lkSxu+zdr9+JXKgnf7HaFSsknapumw9aQwC7N/Q0M5KO41fF0R4VL2GtoppyB9Ck9Dg1zwMWjL2KZN3ckbWABb+frWtmKIVQACzupRWzHiHSZjRRNJalK3uugVisHF2PFGkjYoUjHDCNegKHO0="
|
||||
}
|
||||
}
|
56
plugins/ActivityPub/Test/Fixtures/friendica/objects/note.jsonld
Executable file
56
plugins/ActivityPub/Test/Fixtures/friendica/objects/note.jsonld
Executable file
@@ -0,0 +1,56 @@
|
||||
{
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://w3id.org/security/v1",
|
||||
{
|
||||
"vcard": "http://www.w3.org/2006/vcard/ns#",
|
||||
"dfrn": "http://purl.org/macgirvin/dfrn/1.0/",
|
||||
"diaspora": "https://diasporafoundation.org/ns/",
|
||||
"litepub": "http://litepub.social/ns#",
|
||||
"toot": "http://joinmastodon.org/ns#",
|
||||
"schema": "http://schema.org#",
|
||||
"manuallyApprovesFollowers": "as:manuallyApprovesFollowers",
|
||||
"sensitive": "as:sensitive",
|
||||
"Hashtag": "as:Hashtag",
|
||||
"directMessage": "litepub:directMessage",
|
||||
"discoverable": "toot:discoverable",
|
||||
"PropertyValue": "schema:PropertyValue",
|
||||
"value": "schema:value"
|
||||
}
|
||||
],
|
||||
"id": "https://soc.schuerz.at/objects/4edd2508-4361-edb8-c4d8-b45181083984",
|
||||
"type": "Note",
|
||||
"summary": "",
|
||||
"inReplyTo": "https://lemmy.schuerz.at/post/25360",
|
||||
"diaspora:guid": "4edd2508-4361-edb8-c4d8-b45181083984",
|
||||
"published": "2022-01-23T20:21:24Z",
|
||||
"url": "https://soc.schuerz.at/display/4edd2508-4361-edb8-c4d8-b45181083984",
|
||||
"attributedTo": "https://soc.schuerz.at/profile/jakob",
|
||||
"sensitive": false,
|
||||
"context": "https://lemmy.schuerz.at/post/25360#context",
|
||||
"content": "<span class=\"h-card\"><a href=\"https://lemmy.schuerz.at/u/jakob\" class=\"u-url mention\">@<span>jakob</span></a></span> test",
|
||||
"contentMap": {
|
||||
"de": "<bdi>@<a href=\"https://lemmy.schuerz.at/u/jakob\" class=\"userinfo mention\" title=\"jakob\">jakob</a></bdi> test"
|
||||
},
|
||||
"source": {
|
||||
"content": "@[url=https://lemmy.schuerz.at/u/jakob]Jakob[/url] test",
|
||||
"mediaType": "text/bbcode"
|
||||
},
|
||||
"diaspora:comment": "{\"author\":\"jakob@soc.schuerz.at\",\"guid\":\"4edd2508-4361-edb8-c4d8-b45181083984\",\"created_at\":\"2022-01-23T20:21:24Z\",\"edited_at\":\"2022-01-23T20:21:24Z\",\"parent_guid\":\"ea620d1e-742c8b4d15249a9b-18b5fca3\",\"text\":\"@{Jakob; jakob@lemmy.schuerz.at} test\",\"author_signature\":\"JNCqOui5Cg8\\/Uxw+f0NtGCRjRnhPOrqE6kGJnMkZvOOKhlCdZbCqvyPlNJzEYDa3Z30mOWQKTTNo5BVI+VVZtGrVEqFOdzNog7jOLQoY1dKU9iEQ9vc8USwUCkyJyv48w1iXpfea87KPwv+03DMlftmD6kC7jdUVwhc7+jm0g4fh06tpOcCMQJOZqTTV\\/80EjxIJQ+8eEk5evSw\\/S98ohD1ahcwSomJ9hJUV1H48ucDvMod1FCLcN5h4ALHqubCu4TZIYhGhw9zoCl52GeHhrD3\\/vL6OW4ftZ7UG4rEKQ4HowuXqmNwydrQldtprRtu2UrZBjLqVusPXEs\\/xERQqZnalNXHijyd1TwwCmfTV4YjKwH4BhX\\/p4hdWMqEP4yYXlfA4apalVeAaYZLrNR58kPJjBHad\\/yqH30ziBFheqZ5odFh\\/jnKB4OCFVST3u9b1OKE0jyTrbTepPTaONwc8giQH1sM8koj1gFdulwuJuOTRUKR\\/8ishgHi5SWwbp5YG5Z3YSINkF10IcLiFZAF300AvwgOCdf7ferim4i\\/7TR1D2CBpoNUZnKCKZRymZbE0GuKEE+A6Pk3lk\\/DCsDtmMXpnxlPZ8Nq8OZS\\/olXevAu1y57MNnxBDXtojr4F54MP2fO7E2JwBr7AlwoeSEvtZSAO\\/elzrKfW0eVWOUM2OnI=\"}",
|
||||
"attachment": [],
|
||||
"tag": [
|
||||
{
|
||||
"type": "Mention",
|
||||
"href": "https://lemmy.schuerz.at/u/jakob",
|
||||
"name": "@jakob@lemmy.schuerz.at"
|
||||
}
|
||||
],
|
||||
"to": [
|
||||
"https://lemmy.schuerz.at/u/jakob",
|
||||
"https://www.w3.org/ns/activitystreams#Public",
|
||||
"https://lemmy.schuerz.at/c/test"
|
||||
],
|
||||
"cc": [
|
||||
"https://soc.schuerz.at/followers/jakob"
|
||||
]
|
||||
}
|
94
plugins/ActivityPub/Test/Fixtures/friendica/objects/person.jsonld
Executable file
94
plugins/ActivityPub/Test/Fixtures/friendica/objects/person.jsonld
Executable file
@@ -0,0 +1,94 @@
|
||||
{
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://w3id.org/security/v1",
|
||||
{
|
||||
"vcard": "http://www.w3.org/2006/vcard/ns#",
|
||||
"dfrn": "http://purl.org/macgirvin/dfrn/1.0/",
|
||||
"diaspora": "https://diasporafoundation.org/ns/",
|
||||
"litepub": "http://litepub.social/ns#",
|
||||
"toot": "http://joinmastodon.org/ns#",
|
||||
"schema": "http://schema.org#",
|
||||
"manuallyApprovesFollowers": "as:manuallyApprovesFollowers",
|
||||
"sensitive": "as:sensitive",
|
||||
"Hashtag": "as:Hashtag",
|
||||
"directMessage": "litepub:directMessage",
|
||||
"discoverable": "toot:discoverable",
|
||||
"PropertyValue": "schema:PropertyValue",
|
||||
"value": "schema:value"
|
||||
}
|
||||
],
|
||||
"id": "https://soc.schuerz.at/profile/jakob",
|
||||
"diaspora:guid": "4edd2508-1661-30f6-ebcc-2da966353356",
|
||||
"type": "Person",
|
||||
"following": "https://soc.schuerz.at/following/jakob",
|
||||
"followers": "https://soc.schuerz.at/followers/jakob",
|
||||
"inbox": "https://soc.schuerz.at/inbox/jakob",
|
||||
"outbox": "https://soc.schuerz.at/outbox/jakob",
|
||||
"preferredUsername": "jakob",
|
||||
"name": "Jakob :friendica:",
|
||||
"vcard:hasAddress": {
|
||||
"@type": "vcard:Home",
|
||||
"vcard:country-name": "Austria",
|
||||
"vcard:region": "Niederoesterreich",
|
||||
"vcard:locality": ""
|
||||
},
|
||||
"summary": "Linux, FOSS, Öffentlicher Verkehr, Eisenbahn, Radfahren, Fußgehen, Verkehrsplanung, Städtebau, Will das Schöne wieder in die Welt bringen,Nachhaltigkeit, Modellbahn, Java Entwickler (jun), Bash,<br><br>#FediverseOnlyAccount",
|
||||
"vcard:hasInstantMessage": [
|
||||
"xmpp:jakob@schuerz.at",
|
||||
"matrix:@jakob:schuerz.at"
|
||||
],
|
||||
"url": "https://soc.schuerz.at/profile/jakob",
|
||||
"manuallyApprovesFollowers": true,
|
||||
"discoverable": true,
|
||||
"publicKey": {
|
||||
"id": "https://soc.schuerz.at/profile/jakob#main-key",
|
||||
"owner": "https://soc.schuerz.at/profile/jakob",
|
||||
"publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA1RRoj3DpUmTiRBshv+kz\njO5tgfHs99aBJjvaoW8nbPcOs+HZm9Nj4ncJh99kwd+yONwac6ObMMIisYpVU4C1\neKpnlRrRu/8vQFwhHQT4RxpkibB+l+LvG1HJoMNIuYxvVCIaQZugdJclAdMJjDTF\nbDQNwG6xlcazKd4IbMbmgfoxTxSnQSomJQew1NUbdD3vDiCdJEtjCmeWm6eTCfyZ\njT0mjrAm8ccJ7+opN5SWJ0je0Rav5dohyaVFEtv1Dlv1UlqU4hKefvv71eoROHCA\nWQ3+kYGFGY4ApnbWxwLZyke7khzxr2BjDrfwUAeEsLJT4YOxa5fKJJ59+q5Iddaq\nPNT3QqP0Qzum5w6qDOWm3cNNw7ByqoqxKckZS5U2vm0sx83UEmBqysAkAS/8M9Qr\nBKkb9DQ9jgUa7GPpL+Oknr8hV+Vpk49Jjx+A1WJ/MlNja7fi4w4rBM+v3B8nRayM\nzX8XaKbbOib21mCawJiJIOAm0EP2rNqNM1GpUWPstHKG00o3Czz3P5Hm/q6RcNJE\nKRlSIPQZnUVsoC0bFsqWzipsgb3uDHnz3Ni2OjLNLWBVYkWD7RNfB3WV/XKl2QL3\nnnhmUDahGN7UCOrcBuLfWsTa+GZDFeHot1HXa9tNcxq+QxAUg3qv7oiAH1H+hoJg\nn/Ydg1IR5sLovKi3g7DRS7MCAwEAAQ==\n-----END PUBLIC KEY-----\n"
|
||||
},
|
||||
"endpoints": {
|
||||
"sharedInbox": "https://soc.schuerz.at/inbox"
|
||||
},
|
||||
"icon": {
|
||||
"type": "Image",
|
||||
"url": "https://soc.schuerz.at/photo/profile/jakob.png?ts=1630598950",
|
||||
"mediaType": "image/png"
|
||||
},
|
||||
"attachment": [
|
||||
{
|
||||
"type": "PropertyValue",
|
||||
"name": "Mobilizon",
|
||||
"value": "@jakob@events.schuerz.at<br>@jakob@events.tulln.social"
|
||||
},
|
||||
{
|
||||
"type": "PropertyValue",
|
||||
"name": "Lemmy",
|
||||
"value": "<a href=\"https://lemmy.schuerz.at/u/jakob\" target=\"_blank\" rel=\"noopener noreferrer\">https://lemmy.schuerz.at/u/jakob</a>"
|
||||
},
|
||||
{
|
||||
"type": "PropertyValue",
|
||||
"name": "Funkwhale",
|
||||
"value": "<a href=\"https://radio.schuerz.at/@jakob/\" target=\"_blank\" rel=\"noopener noreferrer\">https://radio.schuerz.at/@jakob/</a>"
|
||||
},
|
||||
{
|
||||
"type": "PropertyValue",
|
||||
"name": "Peertube",
|
||||
"value": "<a href=\"https://kino.schuerz.at/a/jakob\" target=\"_blank\" rel=\"noopener noreferrer\">https://kino.schuerz.at/a/jakob</a>"
|
||||
},
|
||||
{
|
||||
"type": "PropertyValue",
|
||||
"name": "Pixelfed",
|
||||
"value": "<a href=\"https://japix.schuerz.at/jakob\" target=\"_blank\" rel=\"noopener noreferrer\">https://japix.schuerz.at/jakob</a>"
|
||||
},
|
||||
{
|
||||
"type": "PropertyValue",
|
||||
"name": "about:",
|
||||
"value": "This is an OpenPGP proof that connects my OpenPGP key to this Peertube account. For details check out <a href=\"https://keyoxide.org/guides/openpgp-proofs\" target=\"_blank\" rel=\"noopener noreferrer\">https://keyoxide.org/guides/openpgp-proofs</a><br><br>[Verifying my OpenPGP key: openpgp4fpr:FED82F1C73FF53FB1EE9926336615E0FD12833CF]"
|
||||
}
|
||||
],
|
||||
"generator": {
|
||||
"type": "Service",
|
||||
"name": "Friendica 'Siberian Iris' 2021.12-rc-1448",
|
||||
"url": "https://soc.schuerz.at"
|
||||
}
|
||||
}
|
53
plugins/ActivityPub/Test/Fixtures/gnusocial/activities/create_article.jsonld
Executable file
53
plugins/ActivityPub/Test/Fixtures/gnusocial/activities/create_article.jsonld
Executable file
@@ -0,0 +1,53 @@
|
||||
{
|
||||
"type": "Create",
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://w3id.org/security/v1",
|
||||
{
|
||||
"gs": "https://www.gnu.org/software/social/ns#"
|
||||
},
|
||||
{
|
||||
"litepub": "http://litepub.social/ns#"
|
||||
},
|
||||
{
|
||||
"chatMessage": "litepub:chatMessage"
|
||||
},
|
||||
{
|
||||
"inConversation": {
|
||||
"@id": "gs:inConversation",
|
||||
"@type": "@id"
|
||||
}
|
||||
}
|
||||
],
|
||||
"id": "https://instance.gnusocial.test/activity/1338",
|
||||
"published": "2022-03-17T23:30:26+00:00",
|
||||
"actor": "https://instance.gnusocial.test/actor/42",
|
||||
"to": [
|
||||
"https://www.w3.org/ns/activitystreams#Public"
|
||||
],
|
||||
"cc": [
|
||||
"https://instance.gnusocial.test/actor/21"
|
||||
],
|
||||
"object": {
|
||||
"type": "Article",
|
||||
"id": "https://instance.gnusocial.test/object/note/1338",
|
||||
"published": "2022-03-17T23:30:26+00:00",
|
||||
"attributedTo": "https://instance.gnusocial.test/actor/42",
|
||||
"name": "hello, world.",
|
||||
"content": "<p>This is an interesting article.</p>",
|
||||
"mediaType": "text/html",
|
||||
"source": {
|
||||
"content": "This is an interesting article.",
|
||||
"mediaType": "text/markdown"
|
||||
},
|
||||
"attachment": [],
|
||||
"tag": [],
|
||||
"inConversation": "https://instance.gnusocial.test/conversation/1338",
|
||||
"to": [
|
||||
"https://www.w3.org/ns/activitystreams#Public"
|
||||
],
|
||||
"cc": [
|
||||
"https://instance.gnusocial.test/actor/21"
|
||||
]
|
||||
}
|
||||
}
|
55
plugins/ActivityPub/Test/Fixtures/gnusocial/activities/create_note.jsonld
Executable file
55
plugins/ActivityPub/Test/Fixtures/gnusocial/activities/create_note.jsonld
Executable file
@@ -0,0 +1,55 @@
|
||||
{
|
||||
"type": "Create",
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://w3id.org/security/v1",
|
||||
{
|
||||
"gs": "https://www.gnu.org/software/social/ns#"
|
||||
},
|
||||
{
|
||||
"litepub": "http://litepub.social/ns#"
|
||||
},
|
||||
{
|
||||
"chatMessage": "litepub:chatMessage"
|
||||
},
|
||||
{
|
||||
"inConversation": {
|
||||
"@id": "gs:inConversation",
|
||||
"@type": "@id"
|
||||
}
|
||||
},
|
||||
{
|
||||
"@language": "en"
|
||||
}
|
||||
],
|
||||
"id": "https://instance.gnusocial.test/activity/1337",
|
||||
"published": "2022-03-01T20:58:48+00:00",
|
||||
"actor": "https://instance.gnusocial.test/actor/42",
|
||||
"object": {
|
||||
"type": "Note",
|
||||
"id": "https://instance.gnusocial.test/object/note/1337",
|
||||
"published": "2022-03-10T23:07:50+00:00",
|
||||
"attributedTo": "https://instance.gnusocial.test/actor/42",
|
||||
"content": "<p>hello, world.</p>",
|
||||
"mediaType": "text/html",
|
||||
"source": {
|
||||
"content": "hello, world.",
|
||||
"mediaType": "text/plain"
|
||||
},
|
||||
"attachment": [],
|
||||
"tag": [],
|
||||
"inConversation": "https://instance.gnusocial.test/conversation/1337",
|
||||
"to": [
|
||||
"https://www.w3.org/ns/activitystreams#Public"
|
||||
],
|
||||
"cc": [
|
||||
"https://instance.gnusocial.test/actor/42/subscribers"
|
||||
]
|
||||
},
|
||||
"to": [
|
||||
"https://www.w3.org/ns/activitystreams#Public"
|
||||
],
|
||||
"cc": [
|
||||
"https://instance.gnusocial.test/actor/42/subscribers"
|
||||
]
|
||||
}
|
53
plugins/ActivityPub/Test/Fixtures/gnusocial/activities/create_reply.jsonld
Executable file
53
plugins/ActivityPub/Test/Fixtures/gnusocial/activities/create_reply.jsonld
Executable file
@@ -0,0 +1,53 @@
|
||||
{
|
||||
"type": "Create",
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://w3id.org/security/v1",
|
||||
{
|
||||
"gs": "https://www.gnu.org/software/social/ns#"
|
||||
},
|
||||
{
|
||||
"litepub": "http://litepub.social/ns#"
|
||||
},
|
||||
{
|
||||
"chatMessage": "litepub:chatMessage"
|
||||
},
|
||||
{
|
||||
"inConversation": {
|
||||
"@id": "gs:inConversation",
|
||||
"@type": "@id"
|
||||
}
|
||||
}
|
||||
],
|
||||
"id": "https://instance.gnusocial.test/activity/1339",
|
||||
"published": "2022-03-01T20:58:48+00:00",
|
||||
"actor": "https://instance.gnusocial.test/actor/42",
|
||||
"object": {
|
||||
"type": "Note",
|
||||
"id": "https://instance.gnusocial.test/object/note/1339",
|
||||
"published": "2022-03-01T21:00:16+00:00",
|
||||
"attributedTo": "https://instance.gnusocial.test/actor/42",
|
||||
"content": "<p>yay ^^</p>",
|
||||
"mediaType": "text/html",
|
||||
"source": {
|
||||
"content": "yay ^^",
|
||||
"mediaType": "text/plain"
|
||||
},
|
||||
"attachment": [],
|
||||
"tag": [],
|
||||
"inReplyTo": "https://instance.gnusocial.test/object/note/1338",
|
||||
"inConversation": "https://instance.gnusocial.test/conversation/1338",
|
||||
"to": [
|
||||
"https://www.w3.org/ns/activitystreams#Public"
|
||||
],
|
||||
"cc": [
|
||||
"https://instance.gnusocial.test/actor/42/subscribers"
|
||||
]
|
||||
},
|
||||
"to": [
|
||||
"https://www.w3.org/ns/activitystreams#Public"
|
||||
],
|
||||
"cc": [
|
||||
"https://instance.gnusocial.test/actor/42/subscribers"
|
||||
]
|
||||
}
|
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"type": "Like",
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams"
|
||||
],
|
||||
"id": "https://another_instance.gnusocial.test/activity/41362",
|
||||
"published": "2022-03-20T17:54:15+00:00",
|
||||
"actor": "https://another_instance.gnusocial.test/actor/43",
|
||||
"to": [
|
||||
"https://www.w3.org/ns/activitystreams#Public"
|
||||
],
|
||||
"cc": [
|
||||
"https://instance.gnusocial.test/actor/42"
|
||||
],
|
||||
"object": "https://instance.gnusocial.test/object/note/1337"
|
||||
}
|
19
plugins/ActivityPub/Test/Fixtures/gnusocial/context.jsonld
Executable file
19
plugins/ActivityPub/Test/Fixtures/gnusocial/context.jsonld
Executable file
@@ -0,0 +1,19 @@
|
||||
[
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://w3id.org/security/v1",
|
||||
{
|
||||
"gs": "https://www.gnu.org/software/social/ns#"
|
||||
},
|
||||
{
|
||||
"litepub": "http://litepub.social/ns#"
|
||||
},
|
||||
{
|
||||
"chatMessage": "litepub:chatMessage"
|
||||
},
|
||||
{
|
||||
"inConversation": {
|
||||
"@id": "gs:inConversation",
|
||||
"@type": "@id"
|
||||
}
|
||||
}
|
||||
]
|
42
plugins/ActivityPub/Test/Fixtures/gnusocial/objects/another_person.jsonld
Executable file
42
plugins/ActivityPub/Test/Fixtures/gnusocial/objects/another_person.jsonld
Executable file
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"type": "Person",
|
||||
"streams": [],
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://w3id.org/security/v1",
|
||||
{
|
||||
"gs": "https://www.gnu.org/software/social/ns#"
|
||||
},
|
||||
{
|
||||
"litepub": "http://litepub.social/ns#"
|
||||
},
|
||||
{
|
||||
"chatMessage": "litepub:chatMessage"
|
||||
},
|
||||
{
|
||||
"inConversation": {
|
||||
"@id": "gs:inConversation",
|
||||
"@type": "@id"
|
||||
}
|
||||
}
|
||||
],
|
||||
"id": "https://another_instance.gnusocial.test/actor/43",
|
||||
"inbox": "https://another_instance.gnusocial.test/actor/43/inbox.json",
|
||||
"outbox": "https://another_instance.gnusocial.test/actor/43/outbox.json",
|
||||
"following": "https://another_instance.gnusocial.test/actor/43/subscriptions",
|
||||
"followers": "https://another_instance.gnusocial.test/actor/43/subscribers",
|
||||
"liked": "https://another_instance.gnusocial.test/actor/43/favourites",
|
||||
"preferredUsername": "alice",
|
||||
"publicKey": {
|
||||
"id": "https://another_instance.gnusocial.test/actor/43#public-key",
|
||||
"owner": "https://another_instance.gnusocial.test/actor/43",
|
||||
"publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArRHP8lxqj1HqFL4q7CKh\noDyBvuhoaoWo/AGdjiWu5AEODL6utaQX+bCJApH9+XNICCkWvayKupgOvLPqBxkh\nl4TPUjlb1iCt+iZeMB8ftude4epaUNUDdqK1zG3g8z8AdF3nx9/cHI+8UY7+JAh6\naZ5EBi+wNYtl4UoDfizmLeRmmGIam5UQ6x2RseYCevIm1BBCZZHLdIaoPJphyjLW\n8sRJtHL4D3m28NkGG8GizctXHbMl7+RlVJ8HyQSr5taRMF+CmZ9ZDFqF2ewc9Pmw\nOMG4o/6m50Q2ELz23O8idjGxKgG7iGdEa3c5cQZTCQ0+2N77L+iS029AV9AKyZMi\nCwIDAQAB\n-----END PUBLIC KEY-----\n"
|
||||
},
|
||||
"name": "Alice P. Hacker",
|
||||
"published": "2022-02-23T17:20:30+00:00",
|
||||
"updated": "2022-02-25T02:12:48+00:00",
|
||||
"url": "https://another_instance.gnusocial.test/@alice",
|
||||
"endpoints": {
|
||||
"sharedInbox": "https://another_instance.gnusocial.test/inbox.json"
|
||||
}
|
||||
}
|
41
plugins/ActivityPub/Test/Fixtures/gnusocial/objects/article.jsonld
Executable file
41
plugins/ActivityPub/Test/Fixtures/gnusocial/objects/article.jsonld
Executable file
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"type": "Article",
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://w3id.org/security/v1",
|
||||
{
|
||||
"gs": "https://www.gnu.org/software/social/ns#"
|
||||
},
|
||||
{
|
||||
"litepub": "http://litepub.social/ns#"
|
||||
},
|
||||
{
|
||||
"chatMessage": "litepub:chatMessage"
|
||||
},
|
||||
{
|
||||
"inConversation": {
|
||||
"@id": "gs:inConversation",
|
||||
"@type": "@id"
|
||||
}
|
||||
}
|
||||
],
|
||||
"id": "https://instance.gnusocial.test/object/note/1338",
|
||||
"published": "2022-03-17T23:30:26+00:00",
|
||||
"attributedTo": "https://instance.gnusocial.test/actor/42",
|
||||
"name": "hello, world.",
|
||||
"content": "<p>This is an interesting article.</p>",
|
||||
"mediaType": "text/html",
|
||||
"source": {
|
||||
"content": "This is an interesting article.",
|
||||
"mediaType": "text/markdown"
|
||||
},
|
||||
"attachment": [],
|
||||
"tag": [],
|
||||
"inConversation": "https://instance.gnusocial.test/conversation/1338",
|
||||
"to": [
|
||||
"https://www.w3.org/ns/activitystreams#Public"
|
||||
],
|
||||
"cc": [
|
||||
"https://instance.gnusocial.test/actor/21"
|
||||
]
|
||||
}
|
42
plugins/ActivityPub/Test/Fixtures/gnusocial/objects/group.jsonld
Executable file
42
plugins/ActivityPub/Test/Fixtures/gnusocial/objects/group.jsonld
Executable file
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"type": "Group",
|
||||
"streams": [],
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://w3id.org/security/v1",
|
||||
{
|
||||
"gs": "https://www.gnu.org/software/social/ns#"
|
||||
},
|
||||
{
|
||||
"litepub": "http://litepub.social/ns#"
|
||||
},
|
||||
{
|
||||
"chatMessage": "litepub:chatMessage"
|
||||
},
|
||||
{
|
||||
"inConversation": {
|
||||
"@id": "gs:inConversation",
|
||||
"@type": "@id"
|
||||
}
|
||||
}
|
||||
],
|
||||
"id": "https://instance.gnusocial.test/actor/21",
|
||||
"inbox": "https://instance.gnusocial.test/actor/21/inbox.json",
|
||||
"outbox": "https://instance.gnusocial.test/actor/21/outbox.json",
|
||||
"following": "https://instance.gnusocial.test/actor/21/subscriptions",
|
||||
"followers": "https://instance.gnusocial.test/actor/21/subscribers",
|
||||
"liked": "https://instance.gnusocial.test/actor/21/favourites",
|
||||
"preferredUsername": "hackers",
|
||||
"publicKey": {
|
||||
"id": "https://instance.gnusocial.test/actor/2#public-key",
|
||||
"owner": "https://instance.gnusocial.test/actor/2",
|
||||
"publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoZyKL+GyJbTV/ilVBlzz\n8OL/UwNi3KpfV5kQwXU0pPcBbw6y2JOfWnKUT1CfiHG3ntiOFnc+wQfHZk4hRSE8\n9Xe/G5Y215xW+gqx/kjt2GOENqzSzYXdEZ5Qsx6yumZD/yb6VZK9Og0HjX2mpRs9\nbactY76w4BQVntjZ17gSkMhYcyPFZTAIe7QDkeSPk5lkXfTwtaB3YcJSbQ3+s7La\npeEgukQDkrLUIP6cxayKrgUl4fhHdpx1Yk4Bzd/1XkZCjeBca94lP1p2M12amI+Z\nOLSTuLyEiCcku8aN+Ms9plwATmIDaGvKFVk0YVtBHdIJlYXV0yIscab3bqyhsLBK\njwIDAQAB\n-----END PUBLIC KEY-----\n"
|
||||
},
|
||||
"name": "Hackers!",
|
||||
"published": "2022-02-23T21:54:52+00:00",
|
||||
"updated": "2022-02-23T21:55:16+00:00",
|
||||
"url": "https://instance.gnusocial.test/!hackers",
|
||||
"endpoints": {
|
||||
"sharedInbox": "https://instance.gnusocial.test/inbox.json"
|
||||
}
|
||||
}
|
43
plugins/ActivityPub/Test/Fixtures/gnusocial/objects/note.jsonld
Executable file
43
plugins/ActivityPub/Test/Fixtures/gnusocial/objects/note.jsonld
Executable file
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"type": "Note",
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://w3id.org/security/v1",
|
||||
{
|
||||
"gs": "https://www.gnu.org/software/social/ns#"
|
||||
},
|
||||
{
|
||||
"litepub": "http://litepub.social/ns#"
|
||||
},
|
||||
{
|
||||
"chatMessage": "litepub:chatMessage"
|
||||
},
|
||||
{
|
||||
"inConversation": {
|
||||
"@id": "gs:inConversation",
|
||||
"@type": "@id"
|
||||
}
|
||||
},
|
||||
{
|
||||
"@language": "en"
|
||||
}
|
||||
],
|
||||
"id": "https://instance.gnusocial.test/object/note/1337",
|
||||
"published": "2022-03-10T23:07:50+00:00",
|
||||
"attributedTo": "https://instance.gnusocial.test/actor/42",
|
||||
"content": "<p>hello, world.</p>",
|
||||
"mediaType": "text/html",
|
||||
"source": {
|
||||
"content": "hello, world.",
|
||||
"mediaType": "text/plain"
|
||||
},
|
||||
"attachment": [],
|
||||
"tag": [],
|
||||
"inConversation": "https://instance.gnusocial.test/conversation/1337",
|
||||
"to": [
|
||||
"https://www.w3.org/ns/activitystreams#Public"
|
||||
],
|
||||
"cc": [
|
||||
"https://instance.gnusocial.test/actor/42/subscribers"
|
||||
]
|
||||
}
|
50
plugins/ActivityPub/Test/Fixtures/gnusocial/objects/note_with_mention.jsonld
Executable file
50
plugins/ActivityPub/Test/Fixtures/gnusocial/objects/note_with_mention.jsonld
Executable file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"type": "Note",
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://w3id.org/security/v1",
|
||||
{
|
||||
"gs": "https://www.gnu.org/software/social/ns#"
|
||||
},
|
||||
{
|
||||
"litepub": "http://litepub.social/ns#"
|
||||
},
|
||||
{
|
||||
"chatMessage": "litepub:chatMessage"
|
||||
},
|
||||
{
|
||||
"inConversation": {
|
||||
"@id": "gs:inConversation",
|
||||
"@type": "@id"
|
||||
}
|
||||
},
|
||||
{
|
||||
"@language": "en"
|
||||
}
|
||||
],
|
||||
"id": "https://instance.gnusocial.test/object/note/1340",
|
||||
"published": "2022-03-16T21:54:43+00:00",
|
||||
"attributedTo": "https://instance.gnusocial.test/actor/42",
|
||||
"content": "<p>This is a public root note with a mention to @<span class=\"h-card\"><a href=\"https://another_instance.gnusocial.test/actor/43\" class=\"h-card u-url p-nickname mention\">alice@another_instance.gnusocial.test</a></span>.</p>",
|
||||
"mediaType": "text/html",
|
||||
"source": {
|
||||
"content": "This is a public root note with a mention to @alice@another_instance.gnusocial.test.",
|
||||
"mediaType": "text/plain"
|
||||
},
|
||||
"attachment": [],
|
||||
"tag": [
|
||||
{
|
||||
"type": "Mention",
|
||||
"href": "https://another_instance.gnusocial.test/actor/43",
|
||||
"name": "@alice@another_instance.gnusocial.test"
|
||||
}
|
||||
],
|
||||
"inConversation": "https://instance.gnusocial.test/conversation/1340",
|
||||
"to": [
|
||||
"https://www.w3.org/ns/activitystreams#Public",
|
||||
"https://testv3.gnusocial.rocks/actor/43"
|
||||
],
|
||||
"cc": [
|
||||
"https://testv3.gnusocial.rocks/actor/43"
|
||||
]
|
||||
}
|
42
plugins/ActivityPub/Test/Fixtures/gnusocial/objects/person.jsonld
Executable file
42
plugins/ActivityPub/Test/Fixtures/gnusocial/objects/person.jsonld
Executable file
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"type": "Person",
|
||||
"streams": [],
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://w3id.org/security/v1",
|
||||
{
|
||||
"gs": "https://www.gnu.org/software/social/ns#"
|
||||
},
|
||||
{
|
||||
"litepub": "http://litepub.social/ns#"
|
||||
},
|
||||
{
|
||||
"chatMessage": "litepub:chatMessage"
|
||||
},
|
||||
{
|
||||
"inConversation": {
|
||||
"@id": "gs:inConversation",
|
||||
"@type": "@id"
|
||||
}
|
||||
}
|
||||
],
|
||||
"id": "https://instance.gnusocial.test/actor/42",
|
||||
"inbox": "https://instance.gnusocial.test/actor/42/inbox.json",
|
||||
"outbox": "https://instance.gnusocial.test/actor/42/outbox.json",
|
||||
"following": "https://instance.gnusocial.test/actor/42/subscriptions",
|
||||
"followers": "https://instance.gnusocial.test/actor/42/subscribers",
|
||||
"liked": "https://instance.gnusocial.test/actor/42/favourites",
|
||||
"preferredUsername": "diogo",
|
||||
"publicKey": {
|
||||
"id": "https://instance.gnusocial.test/actor/42#public-key",
|
||||
"owner": "https://instance.gnusocial.test/actor/42",
|
||||
"publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArBB+3ldwA2qC1hQTtIho\n9KYhvvMlPdydn8dA6OlyIQ3Jy57ADt2e144jDSY5RQ3esmzWm2QqsI8rAsZsAraO\nl2+855y7Fw35WH4GBc7PJ6MLAEvMk1YWeS/rttXaDzh2i4n/AXkMuxDjS1IBqw2w\nn0qTz2sdGcBJ+mop6AB9Qt2lseBc5IW040jSnfLEDDIaYgoc5m2yRsjGKItOh3BG\njGHDb6JB9FySToSMGIt0/tE5k06wfvAxtkxX5dfGeKtciBpC2MGT169iyMIOM8DN\nFhSl8mowtV1NJQ7nN692USrmNvSJjqe9ugPCDPPvwQ5A6A61Qrgpz5pav/o5Sz69\nzQIDAQAB\n-----END PUBLIC KEY-----\n"
|
||||
},
|
||||
"name": "Diogo Peralta Cordeiro",
|
||||
"published": "2022-02-23T17:20:30+00:00",
|
||||
"updated": "2022-02-25T02:12:48+00:00",
|
||||
"url": "https://instance.gnusocial.test/@diogo",
|
||||
"endpoints": {
|
||||
"sharedInbox": "https://instance.gnusocial.test/inbox.json"
|
||||
}
|
||||
}
|
44
plugins/ActivityPub/Test/Fixtures/gnusocial/objects/reply.jsonld
Executable file
44
plugins/ActivityPub/Test/Fixtures/gnusocial/objects/reply.jsonld
Executable file
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"type": "Note",
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://w3id.org/security/v1",
|
||||
{
|
||||
"gs": "https://www.gnu.org/software/social/ns#"
|
||||
},
|
||||
{
|
||||
"litepub": "http://litepub.social/ns#"
|
||||
},
|
||||
{
|
||||
"chatMessage": "litepub:chatMessage"
|
||||
},
|
||||
{
|
||||
"inConversation": {
|
||||
"@id": "gs:inConversation",
|
||||
"@type": "@id"
|
||||
}
|
||||
},
|
||||
{
|
||||
"@language": "en"
|
||||
}
|
||||
],
|
||||
"id": "https://instance.gnusocial.test/object/note/1339",
|
||||
"published": "2022-03-01T21:00:16+00:00",
|
||||
"attributedTo": "https://instance.gnusocial.test/actor/42",
|
||||
"content": "<p>yay ^^</p>",
|
||||
"mediaType": "text/html",
|
||||
"source": {
|
||||
"content": "yay ^^",
|
||||
"mediaType": "text/plain"
|
||||
},
|
||||
"attachment": [],
|
||||
"tag": [],
|
||||
"inReplyTo": "https://instance.gnusocial.test/object/note/1338",
|
||||
"inConversation": "https://instance.gnusocial.test/conversation/1338",
|
||||
"to": [
|
||||
"https://www.w3.org/ns/activitystreams#Public"
|
||||
],
|
||||
"cc": [
|
||||
"https://instance.gnusocial.test/actor/42/subscribers"
|
||||
]
|
||||
}
|
16
plugins/ActivityPub/Test/Fixtures/lemmy/activities/block/block_user.jsonld
Executable file
16
plugins/ActivityPub/Test/Fixtures/lemmy/activities/block/block_user.jsonld
Executable file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"actor": "http://enterprise.lemmy.ml/u/lemmy_beta",
|
||||
"to": [
|
||||
"https://www.w3.org/ns/activitystreams#Public"
|
||||
],
|
||||
"object": "http://ds9.lemmy.ml/u/lemmy_alpha",
|
||||
"cc": [
|
||||
"http://enterprise.lemmy.ml/c/main"
|
||||
],
|
||||
"target": "http://enterprise.lemmy.ml/c/main",
|
||||
"type": "Block",
|
||||
"remove_data": "true",
|
||||
"summary": "spam post",
|
||||
"expires": "2021-11-01T12:23:50.151874+00:00",
|
||||
"id": "http://enterprise.lemmy.ml/activities/block/5d42fffb-0903-4625-86d4-0b39bb344fc2"
|
||||
}
|
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"actor": "http://enterprise.lemmy.ml/u/lemmy_beta",
|
||||
"to": [
|
||||
"https://www.w3.org/ns/activitystreams#Public"
|
||||
],
|
||||
"object": {
|
||||
"actor": "http://enterprise.lemmy.ml/u/lemmy_beta",
|
||||
"to": [
|
||||
"https://www.w3.org/ns/activitystreams#Public"
|
||||
],
|
||||
"object": "http://ds9.lemmy.ml/u/lemmy_alpha",
|
||||
"cc": [
|
||||
"http://enterprise.lemmy.ml/c/main"
|
||||
],
|
||||
"target": "http://enterprise.lemmy.ml/c/main",
|
||||
"type": "Block",
|
||||
"remove_data": "true",
|
||||
"summary": "spam post",
|
||||
"expires": "2021-11-01T12:23:50.151874+00:00",
|
||||
"id": "http://enterprise.lemmy.ml/activities/block/726f43ab-bd0e-4ab3-89c8-627e976f553c"
|
||||
},
|
||||
"cc": [
|
||||
"http://enterprise.lemmy.ml/c/main"
|
||||
],
|
||||
"type": "Undo",
|
||||
"id": "http://enterprise.lemmy.ml/activities/undo/06a20ffb-3e32-42fb-8f4c-674b36d7c557"
|
||||
}
|
13
plugins/ActivityPub/Test/Fixtures/lemmy/activities/community/add_mod.jsonld
Executable file
13
plugins/ActivityPub/Test/Fixtures/lemmy/activities/community/add_mod.jsonld
Executable file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"actor": "http://enterprise.lemmy.ml/u/lemmy_beta",
|
||||
"to": [
|
||||
"https://www.w3.org/ns/activitystreams#Public"
|
||||
],
|
||||
"object": "http://ds9.lemmy.ml/u/lemmy_alpha",
|
||||
"target": "http://enterprise.lemmy.ml/c/main/moderators",
|
||||
"cc": [
|
||||
"http://enterprise.lemmy.ml/c/main"
|
||||
],
|
||||
"type": "Add",
|
||||
"id": "http://enterprise.lemmy.ml/activities/add/ec069147-77c3-447f-88c8-0ef1df10403f"
|
||||
}
|
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"actor": "http://enterprise.lemmy.ml/c/main",
|
||||
"to": [
|
||||
"https://www.w3.org/ns/activitystreams#Public"
|
||||
],
|
||||
"object": {
|
||||
"actor": "http://enterprise.lemmy.ml/u/lemmy_beta",
|
||||
"to": [
|
||||
"https://www.w3.org/ns/activitystreams#Public"
|
||||
],
|
||||
"object": {
|
||||
"type": "Page",
|
||||
"id": "http://enterprise.lemmy.ml/post/7",
|
||||
"attributedTo": "http://enterprise.lemmy.ml/u/lemmy_beta",
|
||||
"to": [
|
||||
"http://enterprise.lemmy.ml/c/main",
|
||||
"https://www.w3.org/ns/activitystreams#Public"
|
||||
],
|
||||
"name": "post 4",
|
||||
"mediaType": "text/html",
|
||||
"commentsEnabled": true,
|
||||
"sensitive": false,
|
||||
"stickied": false,
|
||||
"published": "2021-11-01T12:11:22.871846+00:00"
|
||||
},
|
||||
"cc": [
|
||||
"http://enterprise.lemmy.ml/c/main"
|
||||
],
|
||||
"type": "Create",
|
||||
"id": "http://enterprise.lemmy.ml/activities/create/2807c9ec-3ad8-4859-a9e0-28b59b6e499f"
|
||||
},
|
||||
"cc": [
|
||||
"http://enterprise.lemmy.ml/c/main/followers"
|
||||
],
|
||||
"type": "Announce",
|
||||
"id": "http://enterprise.lemmy.ml/activities/announce/8030b171-803a-4108-94b1-342688f375cf"
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user