[CORE][Event] Make all events return \EventResult, enforced at container build time

This commit is contained in:
Hugo Sales 2022-04-03 21:40:32 +01:00
parent aef1fac536
commit d4b7e990ce
Signed by: someonewithpc
GPG Key ID: 7D0C7EAFC9D835A0
60 changed files with 345 additions and 239 deletions

View File

@ -34,10 +34,11 @@ use Component\Attachment\Entity as E;
use Doctrine\Common\Collections\ExpressionBuilder; use Doctrine\Common\Collections\ExpressionBuilder;
use Doctrine\ORM\Query\Expr; use Doctrine\ORM\Query\Expr;
use Doctrine\ORM\QueryBuilder; use Doctrine\ORM\QueryBuilder;
use EventResult;
class Attachment extends Component class Attachment extends Component
{ {
public function onAddRoute(Router $r): bool public function onAddRoute(Router $r): EventResult
{ {
$r->connect('note_attachment_show', '/object/note/{note_id<\d+>}/attachment/{attachment_id<\d+>}', [C\Attachment::class, 'attachmentShowWithNote']); $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']); $r->connect('note_attachment_view', '/object/note/{note_id<\d+>}/attachment/{attachment_id<\d+>}/view', [C\Attachment::class, 'attachmentViewWithNote']);
@ -51,13 +52,13 @@ class Attachment extends Component
* *
* This can be used in the future to deduplicate images by visual content * This can be used in the future to deduplicate images by visual content
*/ */
public function onHashFile(string $filename, ?string &$out_hash): bool public function onHashFile(string $filename, ?string &$out_hash): EventResult
{ {
$out_hash = hash_file(E\Attachment::FILEHASH_ALGO, $filename); $out_hash = hash_file(E\Attachment::FILEHASH_ALGO, $filename);
return Event::stop; return Event::stop;
} }
public function onNoteDeleteRelated(Note &$note, Actor $actor): bool public function onNoteDeleteRelated(Note &$note, Actor $actor): EventResult
{ {
Cache::delete("note-attachments-{$note->getId()}"); Cache::delete("note-attachments-{$note->getId()}");
foreach ($note->getAttachments() as $attachment) { foreach ($note->getAttachments() as $attachment) {
@ -68,7 +69,7 @@ class Attachment extends Component
return Event::next; return Event::next;
} }
public function onCollectionQueryAddJoins(QueryBuilder &$note_qb, QueryBuilder &$actor_qb): bool public function onCollectionQueryAddJoins(QueryBuilder &$note_qb, QueryBuilder &$actor_qb): EventResult
{ {
if (!\in_array('attachment_to_note', $note_qb->getAllAliases())) { if (!\in_array('attachment_to_note', $note_qb->getAllAliases())) {
$note_qb->leftJoin( $note_qb->leftJoin(
@ -84,7 +85,7 @@ class Attachment extends Component
/** /**
* Populate $note_expr with the criteria for looking for notes with attachments * Populate $note_expr with the criteria for looking for notes with attachments
*/ */
public function onCollectionQueryCreateExpression(ExpressionBuilder $eb, string $term, ?string $locale, ?Actor $actor, &$note_expr, &$actor_expr): bool public function onCollectionQueryCreateExpression(ExpressionBuilder $eb, string $term, ?string $locale, ?Actor $actor, &$note_expr, &$actor_expr): EventResult
{ {
$include_term = str_contains($term, ':') ? explode(':', $term)[1] : $term; $include_term = str_contains($term, ':') ? explode(':', $term)[1] : $term;
if (Formatting::startsWith($term, ['note-types:', 'notes-incude:', 'note-filter:'])) { if (Formatting::startsWith($term, ['note-types:', 'notes-incude:', 'note-filter:'])) {

View File

@ -32,15 +32,17 @@ use Component\Attachment\Entity\Attachment;
use Component\Attachment\Entity\AttachmentThumbnail; use Component\Attachment\Entity\AttachmentThumbnail;
use Component\Avatar\Controller as C; use Component\Avatar\Controller as C;
use Component\Avatar\Exception\NoAvatarException; use Component\Avatar\Exception\NoAvatarException;
use EventResult;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
class Avatar extends Component class Avatar extends Component
{ {
public function onInitializeComponent() public function onInitializeComponent(): EventResult
{ {
return EventResult::next;
} }
public function onAddRoute(Router $r): bool public function onAddRoute(Router $r): EventResult
{ {
$r->connect('avatar_actor', '/actor/{actor_id<\d+>}/avatar/{size<full|big|medium|small>?medium}', [Controller\Avatar::class, 'avatar_view']); $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']); $r->connect('avatar_default', '/avatar/default/{size<full|big|medium|small>?medium}', [Controller\Avatar::class, 'default_avatar_view']);
@ -51,7 +53,7 @@ class Avatar extends Component
/** /**
* @throws \App\Util\Exception\ClientException * @throws \App\Util\Exception\ClientException
*/ */
public function onPopulateSettingsTabs(Request $request, string $section, &$tabs): bool public function onPopulateSettingsTabs(Request $request, string $section, &$tabs): EventResult
{ {
if ($section === 'profile') { if ($section === 'profile') {
$tabs[] = [ $tabs[] = [
@ -64,7 +66,7 @@ class Avatar extends Component
return Event::next; return Event::next;
} }
public function onAvatarUpdate(int $actor_id): bool public function onAvatarUpdate(int $actor_id): EventResult
{ {
Cache::delete("avatar-{$actor_id}"); Cache::delete("avatar-{$actor_id}");
foreach (['full', 'big', 'medium', 'small'] as $size) { foreach (['full', 'big', 'medium', 'small'] as $size) {

View File

@ -39,6 +39,7 @@ use Component\Circle\Entity\ActorCircleSubscription;
use Component\Circle\Entity\ActorTag; use Component\Circle\Entity\ActorTag;
use Component\Collection\Util\MetaCollectionTrait; use Component\Collection\Util\MetaCollectionTrait;
use Component\Tag\Tag; use Component\Tag\Tag;
use EventResult;
use Functional as F; use Functional as F;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
@ -58,7 +59,7 @@ class Circle extends Component
protected const SLUG = 'circle'; protected const SLUG = 'circle';
protected const PLURAL_SLUG = 'circles'; protected const PLURAL_SLUG = 'circles';
public function onAddRoute(Router $r): bool public function onAddRoute(Router $r): EventResult
{ {
$r->connect('actor_circle_view_by_circle_id', '/circle/{circle_id<\d+>}', [CircleController\Circle::class, 'circleById']); $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 // View circle members by (tagger id or nickname) and tag
@ -93,7 +94,7 @@ class Circle extends Component
]; ];
} }
public function onPopulateSettingsTabs(Request $request, string $section, array &$tabs): bool public function onPopulateSettingsTabs(Request $request, string $section, array &$tabs): EventResult
{ {
if ($section === 'profile' && \in_array($request->get('_route'), ['person_actor_settings', 'group_actor_settings'])) { if ($section === 'profile' && \in_array($request->get('_route'), ['person_actor_settings', 'group_actor_settings'])) {
$tabs[] = [ $tabs[] = [
@ -106,7 +107,7 @@ class Circle extends Component
return Event::next; return Event::next;
} }
public function onPostingFillTargetChoices(Request $request, Actor $actor, array &$targets): bool public function onPostingFillTargetChoices(Request $request, Actor $actor, array &$targets): EventResult
{ {
$circles = $actor->getCircles(); $circles = $actor->getCircles();
foreach ($circles as $circle) { foreach ($circles as $circle) {
@ -218,7 +219,7 @@ class Circle extends Component
return $ids_only ? array_map(fn ($x) => $x->getId(), $circles) : $circles; return $ids_only ? array_map(fn ($x) => $x->getId(), $circles) : $circles;
} }
public function onCreateDefaultFeeds(int $actor_id, LocalUser $user, int &$ordering) public function onCreateDefaultFeeds(int $actor_id, LocalUser $user, int &$ordering): EventResult
{ {
DB::persist(Feed::create([ DB::persist(Feed::create([
'actor_id' => $actor_id, 'actor_id' => $actor_id,

View File

@ -14,6 +14,7 @@ use Component\Subscription\Entity\ActorSubscription;
use Doctrine\Common\Collections\ExpressionBuilder; use Doctrine\Common\Collections\ExpressionBuilder;
use Doctrine\ORM\Query\Expr; use Doctrine\ORM\Query\Expr;
use Doctrine\ORM\QueryBuilder; use Doctrine\ORM\QueryBuilder;
use EventResult;
class Collection extends Component class Collection extends Component
{ {
@ -64,7 +65,7 @@ class Collection extends Component
return ['notes' => $notes ?? null, 'actors' => $actors ?? null]; return ['notes' => $notes ?? null, 'actors' => $actors ?? null];
} }
public function onCollectionQueryAddJoins(QueryBuilder &$note_qb, QueryBuilder &$actor_qb): bool public function onCollectionQueryAddJoins(QueryBuilder &$note_qb, QueryBuilder &$actor_qb): EventResult
{ {
$note_aliases = $note_qb->getAllAliases(); $note_aliases = $note_qb->getAllAliases();
if (!\in_array('subscription', $note_aliases)) { if (!\in_array('subscription', $note_aliases)) {
@ -80,7 +81,7 @@ class Collection extends Component
* Convert $term to $note_expr and $actor_expr, search criteria. Handles searching for text * Convert $term to $note_expr and $actor_expr, search criteria. Handles searching for text
* notes, for different types of actors and for the content of text notes * notes, for different types of actors and for the content of text notes
*/ */
public function onCollectionQueryCreateExpression(ExpressionBuilder $eb, string $term, ?string $locale, ?Actor $actor, &$note_expr, &$actor_expr) public function onCollectionQueryCreateExpression(ExpressionBuilder $eb, string $term, ?string $locale, ?Actor $actor, &$note_expr, &$actor_expr): EventResult
{ {
if (str_contains($term, ':')) { if (str_contains($term, ':')) {
$term = explode(':', $term); $term = explode(':', $term);

View File

@ -39,6 +39,7 @@ use App\Entity\Actor;
use App\Util\Common; use App\Util\Common;
use App\Util\Exception\RedirectException; use App\Util\Exception\RedirectException;
use App\Util\Formatting; use App\Util\Formatting;
use EventResult;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\Extension\Core\Type\TextType;
@ -94,7 +95,7 @@ trait MetaCollectionTrait
* It's compose of two forms: one to select collections to add * It's compose of two forms: one to select collections to add
* the current item to, and another to create a new collection. * the current item to, and another to create a new collection.
*/ */
public function onAppendRightPanelBlock(Request $request, $vars, &$res): bool public function onAppendRightPanelBlock(Request $request, $vars, &$res): EventResult
{ {
$user = Common::actor(); $user = Common::actor();
if (\is_null($user)) { if (\is_null($user)) {
@ -186,7 +187,7 @@ trait MetaCollectionTrait
return Event::next; return Event::next;
} }
public function onEndShowStyles(array &$styles, string $route): bool public function onEndShowStyles(array &$styles, string $route): EventResult
{ {
$styles[] = 'components/Collection/assets/css/widget.css'; $styles[] = 'components/Collection/assets/css/widget.css';
$styles[] = 'components/Collection/assets/css/pages.css'; $styles[] = 'components/Collection/assets/css/pages.css';

View File

@ -40,12 +40,13 @@ use App\Util\Common;
use App\Util\Formatting; use App\Util\Formatting;
use Component\Conversation\Entity\Conversation as ConversationEntity; use Component\Conversation\Entity\Conversation as ConversationEntity;
use Component\Conversation\Entity\ConversationMute; use Component\Conversation\Entity\ConversationMute;
use EventResult;
use Functional as F; use Functional as F;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
class Conversation extends Component class Conversation extends Component
{ {
public function onAddRoute(Router $r): bool public function onAddRoute(Router $r): EventResult
{ {
$r->connect('conversation', '/conversation/{conversation_id<\d+>}', [Controller\Conversation::class, 'showConversation']); $r->connect('conversation', '/conversation/{conversation_id<\d+>}', [Controller\Conversation::class, 'showConversation']);
$r->connect('conversation_mute', '/conversation/{conversation_id<\d+>}/mute', [Controller\Conversation::class, 'muteConversation']); $r->connect('conversation_mute', '/conversation/{conversation_id<\d+>}/mute', [Controller\Conversation::class, 'muteConversation']);
@ -104,7 +105,7 @@ class Conversation extends Component
* *
* @return bool EventHook * @return bool EventHook
*/ */
public function onAddNoteActions(Request $request, Note $note, array &$actions): bool public function onAddNoteActions(Request $request, Note $note, array &$actions): EventResult
{ {
if (\is_null(Common::user())) { if (\is_null(Common::user())) {
return Event::next; return Event::next;
@ -144,7 +145,7 @@ class Conversation extends Component
* *
* @return bool EventHook * @return bool EventHook
*/ */
public function onAppendCardNote(array $vars, array &$result): bool public function onAppendCardNote(array $vars, array &$result): EventResult
{ {
if (str_contains($vars['request']->getPathInfo(), 'conversation')) { if (str_contains($vars['request']->getPathInfo(), 'conversation')) {
return Event::next; return Event::next;
@ -197,7 +198,7 @@ class Conversation extends Component
* *
* @return bool EventHook * @return bool EventHook
*/ */
public function onPostingGetContextActor(Request $request, Actor $actor, ?Actor &$context_actor): bool public function onPostingGetContextActor(Request $request, Actor $actor, ?Actor &$context_actor): EventResult
{ {
$to_note_id = $this->getReplyToIdFromRequest($request); $to_note_id = $this->getReplyToIdFromRequest($request);
if (!\is_null($to_note_id)) { if (!\is_null($to_note_id)) {
@ -218,7 +219,7 @@ class Conversation extends Component
* *
* @return bool EventHook * @return bool EventHook
*/ */
public function onPostingModifyData(Request $request, Actor $actor, array &$data): bool public function onPostingModifyData(Request $request, Actor $actor, array &$data): EventResult
{ {
$to_note_id = $this->getReplyToIdFromRequest($request); $to_note_id = $this->getReplyToIdFromRequest($request);
if (!\is_null($to_note_id)) { if (!\is_null($to_note_id)) {
@ -232,7 +233,7 @@ class Conversation extends Component
/** /**
* Add minimal Note card to RightPanel template * Add minimal Note card to RightPanel template
*/ */
public function onPrependPostingForm(Request $request, array &$elements): bool public function onPrependPostingForm(Request $request, array &$elements): EventResult
{ {
$elements[] = Formatting::twigRenderFile('cards/blocks/note_compact_wrapper.html.twig', ['note' => Note::getById((int) $request->query->get('reply_to_id'))]); $elements[] = Formatting::twigRenderFile('cards/blocks/note_compact_wrapper.html.twig', ['note' => Note::getById((int) $request->query->get('reply_to_id'))]);
return Event::next; return Event::next;
@ -247,7 +248,7 @@ class Conversation extends Component
* *
* @return bool EventHook * @return bool EventHook
*/ */
public function onNoteDeleteRelated(Note &$note, Actor $actor): bool public function onNoteDeleteRelated(Note &$note, Actor $actor): EventResult
{ {
// Ensure we have the most up to date replies // Ensure we have the most up to date replies
Cache::delete(Note::cacheKeys($note->getId())['replies']); Cache::delete(Note::cacheKeys($note->getId())['replies']);
@ -266,7 +267,7 @@ class Conversation extends Component
* *
* @return bool EventHook * @return bool EventHook
*/ */
public function onAddExtraNoteActions(Request $request, Note $note, array &$actions): bool public function onAddExtraNoteActions(Request $request, Note $note, array &$actions): EventResult
{ {
if (\is_null($user = Common::user())) { if (\is_null($user = Common::user())) {
return Event::next; return Event::next;
@ -302,7 +303,7 @@ class Conversation extends Component
* *
* @return bool EventHook * @return bool EventHook
*/ */
public function onNewNotificationShould(Activity $activity, Actor $actor): bool public function onNewNotificationShould(Activity $activity, Actor $actor): EventResult
{ {
if ($activity->getObjectType() === 'note' && ConversationMute::isMuted($activity, $actor)) { if ($activity->getObjectType() === 'note' && ConversationMute::isMuted($activity, $actor)) {
return Event::stop; return Event::stop;

View File

@ -27,10 +27,11 @@ use App\Core\Event;
use App\Core\Modules\Component; use App\Core\Modules\Component;
use App\Core\Router; use App\Core\Router;
use Component\Feed\Controller as C; use Component\Feed\Controller as C;
use EventResult;
class Feed extends Component class Feed extends Component
{ {
public function onAddRoute(Router $r): bool public function onAddRoute(Router $r): EventResult
{ {
$r->connect('feed_public', '/feed/public', [C\Feeds::class, 'public']); $r->connect('feed_public', '/feed/public', [C\Feeds::class, 'public']);
$r->connect('feed_home', '/feed/home', [C\Feeds::class, 'home']); $r->connect('feed_home', '/feed/home', [C\Feeds::class, 'home']);

View File

@ -54,6 +54,7 @@ use Component\FreeNetwork\Util\WebfingerResource;
use Component\FreeNetwork\Util\WebfingerResource\WebfingerResourceActor; use Component\FreeNetwork\Util\WebfingerResource\WebfingerResourceActor;
use Component\FreeNetwork\Util\WebfingerResource\WebfingerResourceNote; use Component\FreeNetwork\Util\WebfingerResource\WebfingerResourceNote;
use Doctrine\Common\Collections\ExpressionBuilder; use Doctrine\Common\Collections\ExpressionBuilder;
use EventResult;
use Exception; use Exception;
use const PREG_SET_ORDER; use const PREG_SET_ORDER;
use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\JsonResponse;
@ -79,13 +80,13 @@ class FreeNetwork extends Component
public const OAUTH_AUTHORIZE_REL = 'http://apinamespace.org/oauth/authorize'; public const OAUTH_AUTHORIZE_REL = 'http://apinamespace.org/oauth/authorize';
private static array $protocols = []; private static array $protocols = [];
public function onInitializeComponent(): bool public function onInitializeComponent(): EventResult
{ {
Event::handle('AddFreeNetworkProtocol', [&self::$protocols]); Event::handle('AddFreeNetworkProtocol', [&self::$protocols]);
return Event::next; return Event::next;
} }
public function onAddRoute(Router $m): bool public function onAddRoute(Router $m): EventResult
{ {
// Feeds // Feeds
$m->connect('feed_network', '/feed/network', [Feeds::class, 'network']); $m->connect('feed_network', '/feed/network', [Feeds::class, 'network']);
@ -111,7 +112,7 @@ class FreeNetwork extends Component
return Event::next; return Event::next;
} }
public function onCreateDefaultFeeds(int $actor_id, LocalUser $user, int &$ordering) public function onCreateDefaultFeeds(int $actor_id, LocalUser $user, int &$ordering): EventResult
{ {
DB::persist(\App\Entity\Feed::create(['actor_id' => $actor_id, 'url' => Router::url($route = 'feed_network'), 'route' => $route, 'title' => _m('Meteorites'), 'ordering' => $ordering++])); DB::persist(\App\Entity\Feed::create(['actor_id' => $actor_id, 'url' => Router::url($route = 'feed_network'), 'route' => $route, 'title' => _m('Meteorites'), 'ordering' => $ordering++]));
DB::persist(\App\Entity\Feed::create(['actor_id' => $actor_id, 'url' => Router::url($route = 'feed_clique'), 'route' => $route, 'title' => _m('Planetary System'), 'ordering' => $ordering++])); DB::persist(\App\Entity\Feed::create(['actor_id' => $actor_id, 'url' => Router::url($route = 'feed_clique'), 'route' => $route, 'title' => _m('Planetary System'), 'ordering' => $ordering++]));
@ -119,7 +120,7 @@ class FreeNetwork extends Component
return Event::next; return Event::next;
} }
public function onStartGetProfileAcctUri(Actor $profile, &$acct): bool public function onStartGetProfileAcctUri(Actor $profile, &$acct): EventResult
{ {
$wfr = new WebFingerResourceActor($profile); $wfr = new WebFingerResourceActor($profile);
try { try {
@ -147,7 +148,7 @@ class FreeNetwork extends Component
* @throws NoSuchActorException * @throws NoSuchActorException
* @throws ServerException * @throws ServerException
*/ */
public function onEndGetWebFingerResource(string $resource, ?WebfingerResource &$target = null, array $args = []): bool public function onEndGetWebFingerResource(string $resource, ?WebfingerResource &$target = null, array $args = []): EventResult
{ {
// * Either we didn't find the profile, then we want to make // * Either we didn't find the profile, then we want to make
// the $profile variable null for clarity. // the $profile variable null for clarity.
@ -223,7 +224,7 @@ class FreeNetwork extends Component
return Event::next; return Event::next;
} }
public function onStartHostMetaLinks(array &$links): bool public function onStartHostMetaLinks(array &$links): EventResult
{ {
foreach (Discovery::supportedMimeTypes() as $type) { foreach (Discovery::supportedMimeTypes() as $type) {
$links[] = new XML_XRD_Element_Link( $links[] = new XML_XRD_Element_Link(
@ -244,7 +245,7 @@ class FreeNetwork extends Component
/** /**
* Add a link header for LRDD Discovery * Add a link header for LRDD Discovery
*/ */
public function onStartShowHTML($action): bool public function onStartShowHTML($action): EventResult
{ {
if ($action instanceof ShowstreamAction) { if ($action instanceof ShowstreamAction) {
$resource = $action->getTarget()->getUri(); $resource = $action->getTarget()->getUri();
@ -257,13 +258,13 @@ class FreeNetwork extends Component
return Event::next; return Event::next;
} }
public function onStartDiscoveryMethodRegistration(Discovery $disco): bool public function onStartDiscoveryMethodRegistration(Discovery $disco): EventResult
{ {
$disco->registerMethod('\Component\FreeNetwork\Util\LrddMethod\LrddMethodWebfinger'); $disco->registerMethod('\Component\FreeNetwork\Util\LrddMethod\LrddMethodWebfinger');
return Event::next; return Event::next;
} }
public function onEndDiscoveryMethodRegistration(Discovery $disco): bool public function onEndDiscoveryMethodRegistration(Discovery $disco): EventResult
{ {
$disco->registerMethod('\Component\FreeNetwork\Util\LrddMethod\LrddMethodHostMeta'); $disco->registerMethod('\Component\FreeNetwork\Util\LrddMethod\LrddMethodHostMeta');
$disco->registerMethod('\Component\FreeNetwork\Util\LrddMethod\LrddMethodLinkHeader'); $disco->registerMethod('\Component\FreeNetwork\Util\LrddMethod\LrddMethodLinkHeader');
@ -275,7 +276,7 @@ class FreeNetwork extends Component
* @throws ClientException * @throws ClientException
* @throws ServerException * @throws ServerException
*/ */
public function onControllerResponseInFormat(string $route, array $accept_header, array $vars, ?Response &$response = null): bool public function onControllerResponseInFormat(string $route, array $accept_header, array $vars, ?Response &$response = null): EventResult
{ {
if (!\in_array($route, ['freenetwork_hostmeta', 'freenetwork_hostmeta_format', 'freenetwork_webfinger', 'freenetwork_webfinger_format', 'freenetwork_ownerxrd'])) { if (!\in_array($route, ['freenetwork_hostmeta', 'freenetwork_hostmeta_format', 'freenetwork_webfinger', 'freenetwork_webfinger_format', 'freenetwork_ownerxrd'])) {
return Event::next; return Event::next;
@ -376,7 +377,7 @@ class FreeNetwork extends Component
* @return bool hook return value * @return bool hook return value
* @example.com/mublog/user * @example.com/mublog/user
*/ */
public function onEndFindMentions(Actor $sender, string $text, array &$mentions): bool public function onEndFindMentions(Actor $sender, string $text, array &$mentions): EventResult
{ {
$matches = []; $matches = [];
@ -517,7 +518,7 @@ class FreeNetwork extends Component
* Add fediverse: query expression * Add fediverse: query expression
* // TODO: adding WebFinger would probably be nice * // TODO: adding WebFinger would probably be nice
*/ */
public function onCollectionQueryCreateExpression(ExpressionBuilder $eb, string $term, ?string $locale, ?Actor $actor, &$note_expr, &$actor_expr): bool public function onCollectionQueryCreateExpression(ExpressionBuilder $eb, string $term, ?string $locale, ?Actor $actor, &$note_expr, &$actor_expr): EventResult
{ {
if (Formatting::startsWith($term, ['fediverse:'])) { if (Formatting::startsWith($term, ['fediverse:'])) {
foreach (self::$protocols as $protocol) { foreach (self::$protocols as $protocol) {
@ -530,7 +531,7 @@ class FreeNetwork extends Component
return Event::next; return Event::next;
} }
public function onPluginVersion(array &$versions): bool public function onPluginVersion(array &$versions): EventResult
{ {
$versions[] = [ $versions[] = [
'name' => 'WebFinger', 'name' => 'WebFinger',

View File

@ -33,11 +33,12 @@ use App\Util\Nickname;
use Component\Group\Controller as C; use Component\Group\Controller as C;
use Component\Group\Entity\LocalGroup; use Component\Group\Entity\LocalGroup;
use Component\Notification\Notification; use Component\Notification\Notification;
use EventResult;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
class Group extends Component class Group extends Component
{ {
public function onAddRoute(Router $r): bool public function onAddRoute(Router $r): EventResult
{ {
$r->connect(id: 'group_actor_view_id', uri_path: '/group/{id<\d+>}', target: [C\GroupFeed::class, 'groupViewId']); $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']); $r->connect(id: 'group_actor_view_nickname', uri_path: '/!{nickname<' . Nickname::DISPLAY_FMT . '>}', target: [C\GroupFeed::class, 'groupViewNickname']);
@ -50,7 +51,7 @@ class Group extends Component
* Enqueues a notification for an Actor (such as person or group) which means * Enqueues a notification for an Actor (such as person or group) which means
* it shows up in their home feed and such. * it shows up in their home feed and such.
*/ */
public function onNewNotificationStart(Actor $sender, Activity $activity, array $targets = [], ?string $reason = null): bool public function onNewNotificationStart(Actor $sender, Activity $activity, array $targets = [], ?string $reason = null): EventResult
{ {
foreach ($targets as $target) { foreach ($targets as $target) {
if ($target->isGroup()) { if ($target->isGroup()) {
@ -70,7 +71,7 @@ class Group extends Component
/** /**
* Add an <a href=group_actor_settings> to the profile card for groups, if the current actor can access them * Add an <a href=group_actor_settings> to the profile card for groups, if the current actor can access them
*/ */
public function onAppendCardProfile(array $vars, array &$res): bool public function onAppendCardProfile(array $vars, array &$res): EventResult
{ {
$actor = Common::actor(); $actor = Common::actor();
$group = $vars['actor']; $group = $vars['actor'];
@ -108,7 +109,7 @@ class Group extends Component
return null; return null;
} }
public function onPostingFillTargetChoices(Request $request, Actor $actor, array &$targets): bool public function onPostingFillTargetChoices(Request $request, Actor $actor, array &$targets): EventResult
{ {
$group = $this->getGroupFromContext($request); $group = $this->getGroupFromContext($request);
if (!\is_null($group)) { if (!\is_null($group)) {
@ -127,7 +128,7 @@ class Group extends Component
* *
* @param null|Actor $context_actor Actor group, if current route is part of an existing Group set of routes * @param null|Actor $context_actor Actor group, if current route is part of an existing Group set of routes
*/ */
public function onPostingGetContextActor(Request $request, Actor $actor, ?Actor &$context_actor): bool public function onPostingGetContextActor(Request $request, Actor $actor, ?Actor &$context_actor): EventResult
{ {
$ctx = $this->getGroupFromContext($request); $ctx = $this->getGroupFromContext($request);
if (!\is_null($ctx)) { if (!\is_null($ctx)) {

View File

@ -33,18 +33,19 @@ use Component\Language\Entity\ActorLanguage;
use Doctrine\Common\Collections\ExpressionBuilder; use Doctrine\Common\Collections\ExpressionBuilder;
use Doctrine\ORM\Query\Expr; use Doctrine\ORM\Query\Expr;
use Doctrine\ORM\QueryBuilder; use Doctrine\ORM\QueryBuilder;
use EventResult;
use Functional as F; use Functional as F;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
class Language extends Component class Language extends Component
{ {
public function onAddRoute(Router $r): bool public function onAddRoute(Router $r): EventResult
{ {
$r->connect('settings_sort_languages', '/settings/sort_languages', [C\Language::class, 'sortLanguages']); $r->connect('settings_sort_languages', '/settings/sort_languages', [C\Language::class, 'sortLanguages']);
return Event::next; return Event::next;
} }
public function onFilterNoteList(?Actor $actor, array &$notes, Request $request): bool public function onFilterNoteList(?Actor $actor, array &$notes, Request $request): EventResult
{ {
if (\is_null($actor)) { if (\is_null($actor)) {
return Event::next; return Event::next;
@ -60,7 +61,7 @@ class Language extends Component
/** /**
* Populate $note_expr or $actor_expr with an expression to match a language * Populate $note_expr or $actor_expr with an expression to match a language
*/ */
public function onCollectionQueryCreateExpression(ExpressionBuilder $eb, string $term, ?string $locale, ?Actor $actor, &$note_expr, &$actor_expr): bool public function onCollectionQueryCreateExpression(ExpressionBuilder $eb, string $term, ?string $locale, ?Actor $actor, &$note_expr, &$actor_expr): EventResult
{ {
$search_term = str_contains($term, ':') ? explode(':', $term)[1] : $term; $search_term = str_contains($term, ':') ? explode(':', $term)[1] : $term;
@ -103,7 +104,7 @@ class Language extends Component
return Event::next; return Event::next;
} }
public function onCollectionQueryAddJoins(QueryBuilder &$note_qb, QueryBuilder &$actor_qb): bool public function onCollectionQueryAddJoins(QueryBuilder &$note_qb, QueryBuilder &$actor_qb): EventResult
{ {
$note_aliases = $note_qb->getAllAliases(); $note_aliases = $note_qb->getAllAliases();
if (!\in_array('note_language', $note_aliases)) { if (!\in_array('note_language', $note_aliases)) {

View File

@ -32,10 +32,11 @@ use App\Entity\Feed;
use App\Util\Exception\ClientException; use App\Util\Exception\ClientException;
use App\Util\Exception\NotFoundException; use App\Util\Exception\NotFoundException;
use Component\LeftPanel\Controller as C; use Component\LeftPanel\Controller as C;
use EventResult;
class LeftPanel extends Component class LeftPanel extends Component
{ {
public function onAddRoute(Router $r): bool public function onAddRoute(Router $r): EventResult
{ {
$r->connect('edit_feeds', '/edit-feeds', C\EditFeeds::class); $r->connect('edit_feeds', '/edit-feeds', C\EditFeeds::class);
return Event::next; return Event::next;
@ -46,7 +47,7 @@ class LeftPanel extends Component
* @throws \App\Util\Exception\ServerException * @throws \App\Util\Exception\ServerException
* @throws ClientException * @throws ClientException
*/ */
public function onAppendFeed(Actor $actor, string $title, string $route, array $route_params): bool public function onAppendFeed(Actor $actor, string $title, string $route, array $route_params): EventResult
{ {
$cache_key = Feed::cacheKey($actor); $cache_key = Feed::cacheKey($actor);
$feeds = Feed::getFeeds($actor); $feeds = Feed::getFeeds($actor);

View File

@ -31,6 +31,7 @@ use App\Entity\Note;
use App\Util\Common; use App\Util\Common;
use App\Util\HTML; use App\Util\HTML;
use Component\Link\Entity\NoteToLink; use Component\Link\Entity\NoteToLink;
use EventResult;
use InvalidArgumentException; use InvalidArgumentException;
class Link extends Component class Link extends Component
@ -54,7 +55,7 @@ class Link extends Component
/** /**
* Extract URLs from $content and create the appropriate Link and NoteToLink entities * Extract URLs from $content and create the appropriate Link and NoteToLink entities
*/ */
public function onProcessNoteContent(Note $note, string $content, string $content_type, array $process_note_content_extra_args = []): bool public function onProcessNoteContent(Note $note, string $content, string $content_type, array $process_note_content_extra_args = []): EventResult
{ {
$ignore = $process_note_content_extra_args['ignoreLinks'] ?? []; $ignore = $process_note_content_extra_args['ignoreLinks'] ?? [];
if (Common::config('attachments', 'process_links')) { if (Common::config('attachments', 'process_links')) {
@ -71,7 +72,7 @@ class Link extends Component
return Event::next; return Event::next;
} }
public function onRenderPlainTextNoteContent(string &$text): bool public function onRenderPlainTextNoteContent(string &$text): EventResult
{ {
$text = $this->replaceURLs($text); $text = $this->replaceURLs($text);
return Event::next; return Event::next;
@ -275,7 +276,7 @@ class Link extends Component
return HTML::html(['a' => ['attrs' => $attrs, $url]], options: ['indent' => false]); return HTML::html(['a' => ['attrs' => $attrs, $url]], options: ['indent' => false]);
} }
public function onNoteDeleteRelated(Note &$note, Actor $actor): bool public function onNoteDeleteRelated(Note &$note, Actor $actor): EventResult
{ {
DB::wrapInTransaction(fn () => NoteToLink::removeWhereNoteId($note->getId())); DB::wrapInTransaction(fn () => NoteToLink::removeWhereNoteId($note->getId()));
return Event::next; return Event::next;

View File

@ -34,12 +34,13 @@ use App\Entity\LocalUser;
use App\Util\Exception\ServerException; use App\Util\Exception\ServerException;
use Component\FreeNetwork\FreeNetwork; use Component\FreeNetwork\FreeNetwork;
use Component\Notification\Controller\Feed; use Component\Notification\Controller\Feed;
use EventResult;
use Exception; use Exception;
use Throwable; use Throwable;
class Notification extends Component class Notification extends Component
{ {
public function onAddRoute(Router $m): bool public function onAddRoute(Router $m): EventResult
{ {
$m->connect('feed_notifications', '/feed/notifications', [Feed::class, 'notifications']); $m->connect('feed_notifications', '/feed/notifications', [Feed::class, 'notifications']);
return Event::next; return Event::next;
@ -48,7 +49,7 @@ class Notification extends Component
/** /**
* @throws ServerException * @throws ServerException
*/ */
public function onCreateDefaultFeeds(int $actor_id, LocalUser $user, int &$ordering): bool public function onCreateDefaultFeeds(int $actor_id, LocalUser $user, int &$ordering): EventResult
{ {
DB::persist(\App\Entity\Feed::create([ DB::persist(\App\Entity\Feed::create([
'actor_id' => $actor_id, 'actor_id' => $actor_id,
@ -75,7 +76,7 @@ class Notification extends Component
* @param array $targets Attentions, Mentions, any other source. Should never be empty, you usually want to register an attention to every $sender->getSubscribers() * @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 * @param null|string $reason An optional reason explaining why this notification exists
*/ */
public function onNewNotification(Actor $sender, Activity $activity, array $targets, ?string $reason = null): bool public function onNewNotification(Actor $sender, Activity $activity, array $targets, ?string $reason = null): EventResult
{ {
// Ensure targets are all actor objects and unique // Ensure targets are all actor objects and unique
$effective_targets = []; $effective_targets = [];
@ -102,13 +103,13 @@ class Notification extends Component
return Event::next; return Event::next;
} }
public function onQueueNotificationLocal(Actor $sender, Activity $activity, Actor $target, ?string $reason, array &$retry_args): bool public function onQueueNotificationLocal(Actor $sender, Activity $activity, Actor $target, ?string $reason, array &$retry_args): EventResult
{ {
// TODO: use https://symfony.com/doc/current/notifier.html // TODO: use https://symfony.com/doc/current/notifier.html
return Event::stop; return Event::stop;
} }
public function onQueueNotificationRemote(Actor $sender, Activity $activity, array $targets, ?string $reason, array &$retry_args): bool public function onQueueNotificationRemote(Actor $sender, Activity $activity, array $targets, ?string $reason, array &$retry_args): EventResult
{ {
if (FreeNetwork::notify($sender, $activity, $targets, $reason)) { if (FreeNetwork::notify($sender, $activity, $targets, $reason)) {
return Event::stop; return Event::stop;

View File

@ -26,10 +26,11 @@ use App\Core\Modules\Component;
use App\Core\Router; use App\Core\Router;
use App\Util\Nickname; use App\Util\Nickname;
use Component\Person\Controller as C; use Component\Person\Controller as C;
use EventResult;
class Person extends Component class Person extends Component
{ {
public function onAddRoute(Router $r): bool public function onAddRoute(Router $r): EventResult
{ {
$r->connect(id: 'person_actor_view_id', uri_path: '/person/{id<\d+>}', target: [C\PersonFeed::class, 'personViewId']); $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]); $r->connect(id: 'person_actor_view_nickname', uri_path: '/@{nickname<' . Nickname::DISPLAY_FMT . '>}', target: [C\PersonFeed::class, 'personViewNickname'], options: ['is_system_path' => false]);

View File

@ -47,6 +47,7 @@ use Component\Attachment\Entity\AttachmentToNote;
use Component\Conversation\Conversation; use Component\Conversation\Conversation;
use Component\Language\Entity\Language; use Component\Language\Entity\Language;
use Component\Notification\Entity\Attention; use Component\Notification\Entity\Attention;
use EventResult;
use Symfony\Component\HttpFoundation\File\UploadedFile; use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
@ -54,7 +55,7 @@ class Posting extends Component
{ {
public const route = 'posting_form_action'; public const route = 'posting_form_action';
public function onAddRoute(Router $r): bool public function onAddRoute(Router $r): EventResult
{ {
$r->connect(self::route, '/form/posting', Controller\Posting::class); $r->connect(self::route, '/form/posting', Controller\Posting::class);
return Event::next; return Event::next;
@ -70,7 +71,7 @@ class Posting extends Component
* @throws RedirectException * @throws RedirectException
* @throws ServerException * @throws ServerException
*/ */
public function onAddMainRightPanelBlock(Request $request, array &$res): bool public function onAddMainRightPanelBlock(Request $request, array &$res): EventResult
{ {
if (\is_null($user = Common::user()) || preg_match('(feed|conversation|group|view)', $request->get('_route')) === 0) { if (\is_null($user = Common::user()) || preg_match('(feed|conversation|group|view)', $request->get('_route')) === 0) {
return Event::next; return Event::next;
@ -298,7 +299,7 @@ class Posting extends Component
return [$activity, $note, $effective_attentions]; return [$activity, $note, $effective_attentions];
} }
public function onRenderNoteContent(string $content, string $content_type, ?string &$rendered, Actor $author, ?string $language = null, array &$mentions = []) public function onRenderNoteContent(string $content, string $content_type, ?string &$rendered, Actor $author, ?string $language = null, array &$mentions = []): EventResult
{ {
switch ($content_type) { switch ($content_type) {
case 'text/plain': case 'text/plain':

View File

@ -27,10 +27,12 @@ use App\Core\Event;
use App\Core\Form; use App\Core\Form;
use function App\Core\I18n\_m; use function App\Core\I18n\_m;
use App\Core\Modules\Component; use App\Core\Modules\Component;
use App\Core\Router;
use App\Util\Common; use App\Util\Common;
use App\Util\Exception\ClientException; use App\Util\Exception\ClientException;
use App\Util\Exception\RedirectException; use App\Util\Exception\RedirectException;
use App\Util\Formatting; use App\Util\Formatting;
use EventResult;
use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormView; use Symfony\Component\Form\FormView;
@ -39,9 +41,10 @@ use Symfony\Component\HttpFoundation\Request;
class Search extends Component class Search extends Component
{ {
public function onAddRoute($r) public function onAddRoute(Router $r): EventResult
{ {
$r->connect('search', '/search', Controller\Search::class); $r->connect('search', '/search', Controller\Search::class);
return EventResult::next;
} }
/** /**
@ -133,7 +136,7 @@ class Search extends Component
* *
* @throws RedirectException * @throws RedirectException
*/ */
public function onPrependRightPanelBlock(Request $request, array &$elements): bool public function onPrependRightPanelBlock(Request $request, array &$elements): EventResult
{ {
$elements[] = Formatting::twigRenderFile('cards/search/view.html.twig', ['search' => self::searchForm($request)]); $elements[] = Formatting::twigRenderFile('cards/search/view.html.twig', ['search' => self::searchForm($request)]);
return Event::next; return Event::next;
@ -146,7 +149,7 @@ class Search extends Component
* *
* @return bool hook value; true means continue processing, false means stop * @return bool hook value; true means continue processing, false means stop
*/ */
public function onEndShowStyles(array &$styles, string $route): bool public function onEndShowStyles(array &$styles, string $route): EventResult
{ {
$styles[] = 'components/Search/assets/css/view.css'; $styles[] = 'components/Search/assets/css/view.css';
return Event::next; return Event::next;

View File

@ -39,11 +39,12 @@ use App\Util\Exception\ServerException;
use Component\Notification\Entity\Attention; use Component\Notification\Entity\Attention;
use Component\Subscription\Controller\Subscribers as SubscribersController; use Component\Subscription\Controller\Subscribers as SubscribersController;
use Component\Subscription\Controller\Subscriptions as SubscriptionsController; use Component\Subscription\Controller\Subscriptions as SubscriptionsController;
use EventResult;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
class Subscription extends Component class Subscription extends Component
{ {
public function onAddRoute(Router $r): bool public function onAddRoute(Router $r): EventResult
{ {
$r->connect(id: 'actor_subscribe_add', uri_path: '/actor/subscribe/{object_id<\d+>}', target: [SubscribersController::class, 'subscribersAdd']); $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']); $r->connect(id: 'actor_subscribe_remove', uri_path: '/actor/unsubscribe/{object_id<\d+>}', target: [SubscribersController::class, 'subscribersRemove']);
@ -186,7 +187,7 @@ class Subscription extends Component
* *
* @return bool EventHook * @return bool EventHook
*/ */
public function onAddProfileActions(Request $request, Actor $object, array &$actions): bool public function onAddProfileActions(Request $request, Actor $object, array &$actions): EventResult
{ {
// Action requires a user to be logged in // Action requires a user to be logged in
// We know it's a LocalUser, which has the same id as Actor // We know it's a LocalUser, which has the same id as Actor

View File

@ -42,6 +42,7 @@ use Component\Tag\Entity\NoteTag;
use Doctrine\Common\Collections\ExpressionBuilder; use Doctrine\Common\Collections\ExpressionBuilder;
use Doctrine\ORM\Query\Expr; use Doctrine\ORM\Query\Expr;
use Doctrine\ORM\QueryBuilder; use Doctrine\ORM\QueryBuilder;
use EventResult;
use Functional as F; use Functional as F;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType; use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
@ -60,7 +61,7 @@ class Tag extends Component
public const TAG_REGEX = '/(^|\\s)(#[\\pL\\pN_\\-]{1,64})/u'; // Brion Vibber 2011-02-23 v2:classes/Notice.php:367 function saveTags public const TAG_REGEX = '/(^|\\s)(#[\\pL\\pN_\\-]{1,64})/u'; // Brion Vibber 2011-02-23 v2:classes/Notice.php:367 function saveTags
public const TAG_SLUG_REGEX = '[A-Za-z0-9]{1,64}'; public const TAG_SLUG_REGEX = '[A-Za-z0-9]{1,64}';
public function onAddRoute($r): bool public function onAddRoute($r): EventResult
{ {
$r->connect('single_note_tag', '/note-tag/{tag<' . self::TAG_SLUG_REGEX . '>}', [Controller\Tag::class, 'single_note_tag']); $r->connect('single_note_tag', '/note-tag/{tag<' . self::TAG_SLUG_REGEX . '>}', [Controller\Tag::class, 'single_note_tag']);
$r->connect('multi_note_tags', '/note-tags/{tags<(' . self::TAG_SLUG_REGEX . ',)+' . self::TAG_SLUG_REGEX . '>}', [Controller\Tag::class, 'multi_note_tags']); $r->connect('multi_note_tags', '/note-tags/{tags<(' . self::TAG_SLUG_REGEX . ',)+' . self::TAG_SLUG_REGEX . '>}', [Controller\Tag::class, 'multi_note_tags']);
@ -118,7 +119,7 @@ class Tag extends Component
/** /**
* Process note by extracting any tags present * Process note by extracting any tags present
*/ */
public function onProcessNoteContent(Note $note, string $content, string $content_type, array $extra_args): bool public function onProcessNoteContent(Note $note, string $content, string $content_type, array $extra_args): EventResult
{ {
if ($extra_args['TagProcessed'] ?? false) { if ($extra_args['TagProcessed'] ?? false) {
return Event::next; return Event::next;
@ -135,7 +136,7 @@ class Tag extends Component
return Event::next; return Event::next;
} }
public function onRenderPlainTextNoteContent(string &$text, ?string $locale = null): bool public function onRenderPlainTextNoteContent(string &$text, ?string $locale = null): EventResult
{ {
$text = preg_replace_callback(self::TAG_REGEX, fn ($m) => $m[1] . self::tagLink($m[2], $locale), $text); $text = preg_replace_callback(self::TAG_REGEX, fn ($m) => $m[1] . self::tagLink($m[2], $locale), $text);
return Event::next; return Event::next;
@ -213,7 +214,7 @@ class Tag extends Component
* *
* $term /^(note|tag|people|actor)/ means we want to match only either a note or an actor * $term /^(note|tag|people|actor)/ means we want to match only either a note or an actor
*/ */
public function onCollectionQueryCreateExpression(ExpressionBuilder $eb, string $term, ?string $locale, ?Actor $actor, &$note_expr, &$actor_expr): bool public function onCollectionQueryCreateExpression(ExpressionBuilder $eb, string $term, ?string $locale, ?Actor $actor, &$note_expr, &$actor_expr): EventResult
{ {
if (!str_contains($term, ':')) { if (!str_contains($term, ':')) {
return Event::next; return Event::next;
@ -252,7 +253,7 @@ class Tag extends Component
return Event::next; return Event::next;
} }
public function onCollectionQueryAddJoins(QueryBuilder &$note_qb, QueryBuilder &$actor_qb): bool public function onCollectionQueryAddJoins(QueryBuilder &$note_qb, QueryBuilder &$actor_qb): EventResult
{ {
if (!\in_array('note_tag', $note_qb->getAllAliases())) { if (!\in_array('note_tag', $note_qb->getAllAliases())) {
$note_qb->leftJoin(NoteTag::class, 'note_tag', Expr\Join::WITH, 'note_tag.note_id = note.id'); $note_qb->leftJoin(NoteTag::class, 'note_tag', Expr\Join::WITH, 'note_tag.note_id = note.id');
@ -263,13 +264,13 @@ class Tag extends Component
return Event::next; return Event::next;
} }
public function onPostingAddFormEntries(Request $request, Actor $actor, array &$form_params): bool public function onPostingAddFormEntries(Request $request, Actor $actor, array &$form_params): EventResult
{ {
$form_params[] = ['tag_use_canonical', CheckboxType::class, ['required' => false, 'data' => true, 'label' => _m('Make note tags canonical'), 'help' => _m('Canonical tags will be treated as a version of an existing tag with the same root/stem (e.g. \'#great_tag\' will be considered as a version of \'#great\', if it already exists)')]]; $form_params[] = ['tag_use_canonical', CheckboxType::class, ['required' => false, 'data' => true, 'label' => _m('Make note tags canonical'), 'help' => _m('Canonical tags will be treated as a version of an existing tag with the same root/stem (e.g. \'#great_tag\' will be considered as a version of \'#great\', if it already exists)')]];
return Event::next; return Event::next;
} }
public function onAddExtraArgsToNoteContent(Request $request, Actor $actor, array $data, array &$extra_args): bool public function onAddExtraArgsToNoteContent(Request $request, Actor $actor, array $data, array &$extra_args): EventResult
{ {
if (!isset($data['tag_use_canonical'])) { if (!isset($data['tag_use_canonical'])) {
throw new ClientException(_m('Missing Use Canonical preference for Tags.')); throw new ClientException(_m('Missing Use Canonical preference for Tags.'));

View File

@ -103,6 +103,9 @@
"files": [ "files": [
"src/Core/I18n/I18n.php" "src/Core/I18n/I18n.php"
], ],
"classmap": [
"src/Core/Event/EventResult.php"
],
"psr-4": { "psr-4": {
"App\\": "src/", "App\\": "src/",
"Plugin\\": "plugins/", "Plugin\\": "plugins/",

View File

@ -13,7 +13,7 @@ services:
# this creates a service per class whose id is the fully-qualified class name # this creates a service per class whose id is the fully-qualified class name
App\: App\:
resource: '../src/*' resource: '../src/*'
exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php,Routes}' exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php,Routes,Core/Event/EventResult.php}'
App\Test\Fixtures\: App\Test\Fixtures\:
resource: '../tests/fixtures/*' resource: '../tests/fixtures/*'

View File

@ -50,6 +50,7 @@ use App\Util\Exception\BugFoundException;
use Component\Collection\Util\Controller\OrderedCollection; use Component\Collection\Util\Controller\OrderedCollection;
use Component\FreeNetwork\Entity\FreeNetworkActorProtocol; use Component\FreeNetwork\Entity\FreeNetworkActorProtocol;
use Component\FreeNetwork\Util\Discovery; use Component\FreeNetwork\Util\Discovery;
use EventResult;
use Exception; use Exception;
use InvalidArgumentException; use InvalidArgumentException;
use Plugin\ActivityPub\Controller\Inbox; use Plugin\ActivityPub\Controller\Inbox;
@ -122,14 +123,14 @@ class ActivityPub extends Plugin
], ],
]; ];
public function onInitializePlugin(): bool public function onInitializePlugin(): EventResult
{ {
Event::handle('ActivityStreamsTwoContext', [&self::$activity_streams_two_context]); Event::handle('ActivityStreamsTwoContext', [&self::$activity_streams_two_context]);
self::$activity_streams_two_context = array_unique(self::$activity_streams_two_context, \SORT_REGULAR); self::$activity_streams_two_context = array_unique(self::$activity_streams_two_context, \SORT_REGULAR);
return Event::next; return Event::next;
} }
public function onQueueActivitypubInbox(ActivitypubActor $ap_actor, Actor $actor, string|AbstractObject $type): bool public function onQueueActivitypubInbox(ActivitypubActor $ap_actor, Actor $actor, string|AbstractObject $type): EventResult
{ {
// TODO: Check if Actor has authority over payload // TODO: Check if Actor has authority over payload
@ -157,7 +158,7 @@ class ActivityPub extends Plugin
* *
* @param Router $r the router that was initialized * @param Router $r the router that was initialized
*/ */
public function onAddRoute(Router $r): bool public function onAddRoute(Router $r): EventResult
{ {
$r->connect( $r->connect(
'activitypub_inbox', 'activitypub_inbox',
@ -183,7 +184,7 @@ class ActivityPub extends Plugin
/** /**
* Fill Actor->getUrl() calls with correct URL coming from ActivityPub * Fill Actor->getUrl() calls with correct URL coming from ActivityPub
*/ */
public function onStartGetActorUri(Actor $actor, int $type, ?string &$url): bool public function onStartGetActorUri(Actor $actor, int $type, ?string &$url): EventResult
{ {
if ( if (
// Is remote? // Is remote?
@ -203,7 +204,7 @@ class ActivityPub extends Plugin
/** /**
* Fill Actor->canAdmin() for Actors that came from ActivityPub * Fill Actor->canAdmin() for Actors that came from ActivityPub
*/ */
public function onFreeNetworkActorCanAdmin(Actor $actor, Actor $other, bool &$canAdmin): bool public function onFreeNetworkActorCanAdmin(Actor $actor, Actor $other, bool &$canAdmin): EventResult
{ {
// Are both in AP? // Are both in AP?
if ( if (
@ -223,7 +224,7 @@ class ActivityPub extends Plugin
* *
* @throws Exception * @throws Exception
*/ */
public function onControllerResponseInFormat(string $route, array $accept_header, array $vars, ?TypeResponse &$response = null): bool public function onControllerResponseInFormat(string $route, array $accept_header, array $vars, ?TypeResponse &$response = null): EventResult
{ {
if (\count(array_intersect(self::$accept_headers, $accept_header)) === 0) { if (\count(array_intersect(self::$accept_headers, $accept_header)) === 0) {
return Event::next; return Event::next;
@ -262,7 +263,7 @@ class ActivityPub extends Plugin
/** /**
* Add ActivityStreams 2 Extensions * Add ActivityStreams 2 Extensions
*/ */
public function onActivityPubValidateActivityStreamsTwoData(string $type_name, array &$validators): bool public function onActivityPubValidateActivityStreamsTwoData(string $type_name, array &$validators): EventResult
{ {
switch ($type_name) { switch ($type_name) {
case 'Person': case 'Person':
@ -280,7 +281,7 @@ class ActivityPub extends Plugin
/** /**
* Let FreeNetwork Component know we exist and which class to use to call the freeNetworkDistribute method * Let FreeNetwork Component know we exist and which class to use to call the freeNetworkDistribute method
*/ */
public function onAddFreeNetworkProtocol(array &$protocols): bool public function onAddFreeNetworkProtocol(array &$protocols): EventResult
{ {
$protocols[] = '\Plugin\ActivityPub\ActivityPub'; $protocols[] = '\Plugin\ActivityPub\ActivityPub';
return Event::next; return Event::next;
@ -321,7 +322,7 @@ class ActivityPub extends Plugin
string $inbox, string $inbox,
array $to_actors, array $to_actors,
array &$retry_args, array &$retry_args,
): bool { ): EventResult {
try { try {
$data = Model::toType($activity); $data = Model::toType($activity);
if ($sender->isGroup()) { // When the sender is a group, if ($sender->isGroup()) { // When the sender is a group,
@ -426,7 +427,7 @@ class ActivityPub extends Plugin
/** /**
* Add activity+json mimetype to WebFinger * Add activity+json mimetype to WebFinger
*/ */
public function onEndWebFingerProfileLinks(XML_XRD $xrd, Actor $object): bool public function onEndWebFingerProfileLinks(XML_XRD $xrd, Actor $object): EventResult
{ {
if ($object->isPerson()) { if ($object->isPerson()) {
$link = new XML_XRD_Element_Link( $link = new XML_XRD_Element_Link(
@ -442,7 +443,7 @@ class ActivityPub extends Plugin
/** /**
* When FreeNetwork component asks us to help with identifying Actors from XRDs * When FreeNetwork component asks us to help with identifying Actors from XRDs
*/ */
public function onFreeNetworkFoundXrd(XML_XRD $xrd, ?Actor &$actor = null): bool public function onFreeNetworkFoundXrd(XML_XRD $xrd, ?Actor &$actor = null): EventResult
{ {
$addr = null; $addr = null;
foreach ($xrd->aliases as $alias) { foreach ($xrd->aliases as $alias) {
@ -473,7 +474,7 @@ class ActivityPub extends Plugin
/** /**
* When FreeNetwork component asks us to help with identifying Actors from URIs * When FreeNetwork component asks us to help with identifying Actors from URIs
*/ */
public function onFreeNetworkFindMentions(string $target, ?Actor &$actor = null): bool public function onFreeNetworkFindMentions(string $target, ?Actor &$actor = null): EventResult
{ {
try { try {
if (FreeNetworkActorProtocol::canIAddr('activitypub', $addr = Discovery::normalize($target))) { if (FreeNetworkActorProtocol::canIAddr('activitypub', $addr = Discovery::normalize($target))) {

View File

@ -41,6 +41,7 @@ use App\Entity\Feed;
use App\Entity\LocalUser; use App\Entity\LocalUser;
use App\Util\Nickname; use App\Util\Nickname;
use Component\Collection\Util\MetaCollectionTrait; use Component\Collection\Util\MetaCollectionTrait;
use EventResult;
use Plugin\AttachmentCollections\Controller\AttachmentCollections as AttachmentCollectionsController; use Plugin\AttachmentCollections\Controller\AttachmentCollections as AttachmentCollectionsController;
use Plugin\AttachmentCollections\Entity\AttachmentCollection; use Plugin\AttachmentCollections\Entity\AttachmentCollection;
use Plugin\AttachmentCollections\Entity\AttachmentCollectionEntry; use Plugin\AttachmentCollections\Entity\AttachmentCollectionEntry;
@ -122,7 +123,7 @@ class AttachmentCollections extends Plugin
return array_map(fn ($x) => $x['attachment_collection_id'], $res); return array_map(fn ($x) => $x['attachment_collection_id'], $res);
} }
public function onAddRoute(Router $r): bool public function onAddRoute(Router $r): EventResult
{ {
// View all collections by actor id and nickname // View all collections by actor id and nickname
$r->connect( $r->connect(
@ -149,7 +150,7 @@ class AttachmentCollections extends Plugin
return Event::next; return Event::next;
} }
public function onCreateDefaultFeeds(int $actor_id, LocalUser $user, int &$ordering) public function onCreateDefaultFeeds(int $actor_id, LocalUser $user, int &$ordering): EventResult
{ {
DB::persist(Feed::create([ DB::persist(Feed::create([
'actor_id' => $actor_id, 'actor_id' => $actor_id,

View File

@ -28,11 +28,12 @@ use App\Core\Event;
use App\Core\Modules\Plugin; use App\Core\Modules\Plugin;
use App\Util\Common; use App\Util\Common;
use App\Util\Formatting; use App\Util\Formatting;
use EventResult;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
class AttachmentShowRelated extends Plugin class AttachmentShowRelated extends Plugin
{ {
public function onAppendRightPanelBlock(Request $request, $vars, &$res): bool public function onAppendRightPanelBlock(Request $request, $vars, &$res): EventResult
{ {
if ($vars['path'] === 'note_attachment_show') { if ($vars['path'] === 'note_attachment_show') {
$related_notes = DB::dql('select n from attachment_to_note an ' $related_notes = DB::dql('select n from attachment_to_note an '
@ -54,7 +55,7 @@ class AttachmentShowRelated extends Plugin
* *
* @return bool hook value; true means continue processing, false means stop * @return bool hook value; true means continue processing, false means stop
*/ */
public function onEndShowStyles(array &$styles, string $path): bool public function onEndShowStyles(array &$styles, string $path): EventResult
{ {
if ($path === 'note_attachment_show') { if ($path === 'note_attachment_show') {
$styles[] = '/assets/default_theme/pages/feeds.css'; $styles[] = '/assets/default_theme/pages/feeds.css';

View File

@ -38,6 +38,7 @@ use function App\Core\I18n\_m;
use App\Core\Modules\Plugin; use App\Core\Modules\Plugin;
use App\Util\Exception\ServerException; use App\Util\Exception\ServerException;
use App\Util\Formatting; use App\Util\Formatting;
use EventResult;
use FFMpeg\FFProbe as ffprobe; use FFMpeg\FFProbe as ffprobe;
use SplFileInfo; use SplFileInfo;
@ -53,7 +54,7 @@ class AudioEncoder extends Plugin
return GSFile::mimetypeMajor($mimetype) === 'audio'; return GSFile::mimetypeMajor($mimetype) === 'audio';
} }
public function onFileMetaAvailable(array &$event_map, string $mimetype): bool public function onFileMetaAvailable(array &$event_map, string $mimetype): EventResult
{ {
if (!self::shouldHandle($mimetype)) { if (!self::shouldHandle($mimetype)) {
return Event::next; return Event::next;
@ -90,7 +91,7 @@ class AudioEncoder extends Plugin
/** /**
* Generates the view for attachments of type Video * Generates the view for attachments of type Video
*/ */
public function onViewAttachment(array $vars, array &$res): bool public function onViewAttachment(array $vars, array &$res): EventResult
{ {
if (!self::shouldHandle($vars['attachment']->getMimetype())) { if (!self::shouldHandle($vars['attachment']->getMimetype())) {
return Event::next; return Event::next;
@ -110,7 +111,7 @@ class AudioEncoder extends Plugin
/** /**
* @throws ServerException * @throws ServerException
*/ */
public function onPluginVersion(array &$versions): bool public function onPluginVersion(array &$versions): EventResult
{ {
$versions[] = [ $versions[] = [
'name' => 'AudioEncoder', 'name' => 'AudioEncoder',

View File

@ -23,22 +23,23 @@ declare(strict_types = 1);
namespace Plugin\Blog; namespace Plugin\Blog;
use App\Core\Event; use App\Core\Event;
use function App\Core\I18n\_m;
use App\Core\Modules\Plugin; use App\Core\Modules\Plugin;
use App\Core\Router; use App\Core\Router;
use App\Util\Common; use App\Util\Common;
use App\Util\HTML; use App\Util\HTML;
use EventResult;
use Plugin\Blog\Controller as C; use Plugin\Blog\Controller as C;
use function App\Core\I18n\_m;
class Blog extends Plugin class Blog extends Plugin
{ {
public function onAddRoute(Router $r): bool public function onAddRoute(Router $r): EventResult
{ {
$r->connect(id: 'blog_post', uri_path: '/blog/post', target: [C\Post::class, 'makePost']); $r->connect(id: 'blog_post', uri_path: '/blog/post', target: [C\Post::class, 'makePost']);
return Event::next; return Event::next;
} }
public function onAppendCardProfile(array $vars, array &$res): bool public function onAppendCardProfile(array $vars, array &$res): EventResult
{ {
$actor = Common::actor(); $actor = Common::actor();
$group = $vars['actor']; $group = $vars['actor'];

View File

@ -27,6 +27,7 @@ use App\Core\Event;
use App\Core\Modules\Plugin; use App\Core\Modules\Plugin;
use App\Core\Router; use App\Core\Router;
use App\Util\Common; use App\Util\Common;
use EventResult;
use Plugin\Cover\Controller as C; use Plugin\Cover\Controller as C;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
@ -47,14 +48,14 @@ class Cover extends Plugin
* *
* @return bool hook value; true means continue processing, false means stop * @return bool hook value; true means continue processing, false means stop
*/ */
public function onAddRoute(Router $r): bool public function onAddRoute(Router $r): EventResult
{ {
$r->connect('settings_profile_cover', 'settings/cover', [Controller\Cover::class, 'coversettings']); $r->connect('settings_profile_cover', 'settings/cover', [Controller\Cover::class, 'coversettings']);
$r->connect('cover', '/cover', [Controller\Cover::class, 'cover']); $r->connect('cover', '/cover', [Controller\Cover::class, 'cover']);
return Event::next; return Event::next;
} }
public function onPopulateSettingsTabs(Request $request, string $section, &$tabs) public function onPopulateSettingsTabs(Request $request, string $section, &$tabs): EventResult
{ {
if ($section === 'profile') { if ($section === 'profile') {
$tabs[] = [ $tabs[] = [
@ -72,7 +73,7 @@ class Cover extends Plugin
* *
* @return bool hook value; true means continue processing, false means stop. * @return bool hook value; true means continue processing, false means stop.
* *
* public function onStartTwigPopulateVars(array &$vars): bool * public function onStartTwigPopulateVars(array &$vars): \EventResult
* { * {
* if (Common::user() != null) { * if (Common::user() != null) {
* $cover = DB::find('cover', ['actor_id' => Common::user()->getId()]); * $cover = DB::find('cover', ['actor_id' => Common::user()->getId()]);
@ -92,7 +93,7 @@ class Cover extends Plugin
* *
* @return bool hook value; true means continue processing, false means stop * @return bool hook value; true means continue processing, false means stop
*/ */
public function onStartShowStyles(array &$styles): bool public function onStartShowStyles(array &$styles): EventResult
{ {
$styles[] = 'assets/css/cover.css'; $styles[] = 'assets/css/cover.css';
return Event::next; return Event::next;

View File

@ -34,6 +34,7 @@ use App\Entity\Note;
use App\Util\Common; use App\Util\Common;
use App\Util\Exception\ClientException; use App\Util\Exception\ClientException;
use DateTime; use DateTime;
use EventResult;
use Plugin\ActivityPub\Entity\ActivitypubActivity; use Plugin\ActivityPub\Entity\ActivitypubActivity;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
@ -135,7 +136,7 @@ class DeleteNote extends NoteHandlerPlugin
* *
* @return bool Event hook * @return bool Event hook
*/ */
public function onAddRoute(Router $r) public function onAddRoute(Router $r): EventResult
{ {
$r->connect(id: 'delete_note_action', uri_path: '/object/note/{note_id<\d+>}/delete', target: Controller\DeleteNote::class); $r->connect(id: 'delete_note_action', uri_path: '/object/note/{note_id<\d+>}/delete', target: Controller\DeleteNote::class);
@ -154,7 +155,7 @@ class DeleteNote extends NoteHandlerPlugin
* *
* @return bool Event hook * @return bool Event hook
*/ */
public function onAddExtraNoteActions(Request $request, Note $note, array &$actions) public function onAddExtraNoteActions(Request $request, Note $note, array &$actions): EventResult
{ {
if (\is_null($actor = Common::actor())) { if (\is_null($actor = Common::actor())) {
return Event::next; return Event::next;
@ -227,7 +228,7 @@ class DeleteNote extends NoteHandlerPlugin
* *
* @return bool Returns `Event::stop` if handled, `Event::next` otherwise * @return bool Returns `Event::stop` if handled, `Event::next` otherwise
*/ */
public function onNewActivityPubActivity(Actor $actor, AbstractObject $type_activity, AbstractObject $type_object, ?ActivitypubActivity &$ap_act): bool public function onNewActivityPubActivity(Actor $actor, AbstractObject $type_activity, AbstractObject $type_object, ?ActivitypubActivity &$ap_act): EventResult
{ {
return $this->activitypub_handler($actor, $type_activity, $type_object, $ap_act); return $this->activitypub_handler($actor, $type_activity, $type_object, $ap_act);
} }
@ -242,7 +243,7 @@ class DeleteNote extends NoteHandlerPlugin
* *
* @return bool Returns `Event::stop` if handled, `Event::next` otherwise * @return bool Returns `Event::stop` if handled, `Event::next` otherwise
*/ */
public function onNewActivityPubActivityWithObject(Actor $actor, AbstractObject $type_activity, mixed $type_object, ?ActivitypubActivity &$ap_act): bool public function onNewActivityPubActivityWithObject(Actor $actor, AbstractObject $type_activity, mixed $type_object, ?ActivitypubActivity &$ap_act): EventResult
{ {
return $this->activitypub_handler($actor, $type_activity, $type_object, $ap_act); return $this->activitypub_handler($actor, $type_activity, $type_object, $ap_act);
} }
@ -255,7 +256,7 @@ class DeleteNote extends NoteHandlerPlugin
* *
* @return bool Returns `Event::stop` if handled, `Event::next` otherwise * @return bool Returns `Event::stop` if handled, `Event::next` otherwise
*/ */
public function onGSVerbToActivityStreamsTwoActivityType(string $verb, ?string &$gs_verb_to_activity_stream_two_verb): bool public function onGSVerbToActivityStreamsTwoActivityType(string $verb, ?string &$gs_verb_to_activity_stream_two_verb): EventResult
{ {
if ($verb === 'delete') { if ($verb === 'delete') {
$gs_verb_to_activity_stream_two_verb = 'Delete'; $gs_verb_to_activity_stream_two_verb = 'Delete';

View File

@ -31,6 +31,7 @@ use App\Util\Exception\RedirectException;
use App\Util\Exception\ServerException; use App\Util\Exception\ServerException;
use App\Util\Formatting; use App\Util\Formatting;
use Component\Group\Controller as ComponentGroupController; use Component\Group\Controller as ComponentGroupController;
use EventResult;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
class Directory extends Plugin class Directory extends Plugin
@ -40,7 +41,7 @@ class Directory extends Plugin
* *
* @return bool * @return bool
*/ */
public function onAddRoute(Router $r) public function onAddRoute(Router $r): EventResult
{ {
$r->connect('directory_people', '/directory/people', [Controller\Directory::class, 'people']); $r->connect('directory_people', '/directory/people', [Controller\Directory::class, 'people']);
$r->connect('directory_groups', '/directory/groups', [Controller\Directory::class, 'groups']); $r->connect('directory_groups', '/directory/groups', [Controller\Directory::class, 'groups']);
@ -55,7 +56,7 @@ class Directory extends Plugin
* *
* @return bool hook value; true means continue processing, false means stop * @return bool hook value; true means continue processing, false means stop
*/ */
public function onAddMainNavigationItem(array $vars, array &$res): bool public function onAddMainNavigationItem(array $vars, array &$res): EventResult
{ {
$res[] = ['title' => 'People', 'path' => Router::url($path_id = 'directory_people', []), 'path_id' => $path_id]; $res[] = ['title' => 'People', 'path' => Router::url($path_id = 'directory_people', []), 'path_id' => $path_id];
$res[] = ['title' => 'Groups', 'path' => Router::url($path_id = 'directory_groups', []), 'path_id' => $path_id]; $res[] = ['title' => 'Groups', 'path' => Router::url($path_id = 'directory_groups', []), 'path_id' => $path_id];
@ -72,7 +73,7 @@ class Directory extends Plugin
* *
* @return bool EventHook * @return bool EventHook
*/ */
public function onPrependActorsCollection(Request $request, array &$elements): bool public function onPrependActorsCollection(Request $request, array &$elements): EventResult
{ {
if (\is_null($actor = Common::actor())) { if (\is_null($actor = Common::actor())) {
return Event::next; return Event::next;

View File

@ -36,10 +36,11 @@ namespace Plugin\EmailNotifications;
use App\Core\Event; use App\Core\Event;
use App\Core\Modules\Plugin; use App\Core\Modules\Plugin;
use EventResult;
class EmailNotifications extends Plugin class EmailNotifications extends Plugin
{ {
public function onAddNotificationTransport(&$form_defs): bool public function onAddNotificationTransport(&$form_defs): EventResult
{ {
$form_defs['Email'] = $form_defs['placeholder']; $form_defs['Email'] = $form_defs['placeholder'];
$form_defs['Email'][] = $form_defs['placeholder']['save']('Email', 'save_email'); $form_defs['Email'][] = $form_defs['placeholder']['save']('Email', 'save_email');

View File

@ -57,6 +57,7 @@ use App\Util\TemporaryFile;
use Component\Attachment\Entity\Attachment; use Component\Attachment\Entity\Attachment;
use Component\Link\Entity\Link; use Component\Link\Entity\Link;
use Embed\Embed as LibEmbed; use Embed\Embed as LibEmbed;
use EventResult;
use Exception; use Exception;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface; use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
@ -111,7 +112,7 @@ class Embed extends Plugin
* *
* @throws Exception * @throws Exception
*/ */
public function onAddRoute(Router $m): bool public function onAddRoute(Router $m): EventResult
{ {
$m->connect('oembed', 'main/oembed', Controller\OEmbed::class); $m->connect('oembed', 'main/oembed', Controller\OEmbed::class);
return Event::next; return Event::next;
@ -120,7 +121,7 @@ class Embed extends Plugin
/** /**
* Insert oembed and opengraph tags in all HTML head elements * Insert oembed and opengraph tags in all HTML head elements
*/ */
public function onShowHeadElements(Request $request, array &$result): bool public function onShowHeadElements(Request $request, array &$result): EventResult
{ {
$matches = []; $matches = [];
preg_match(',/?([^/]+)/?(.*),', $request->getPathInfo(), $matches); preg_match(',/?([^/]+)/?(.*),', $request->getPathInfo(), $matches);
@ -146,7 +147,7 @@ class Embed extends Plugin
/** /**
* Show this attachment enhanced with the corresponding Embed data, if available * Show this attachment enhanced with the corresponding Embed data, if available
*/ */
public function onViewLink(array $vars, array &$res): bool public function onViewLink(array $vars, array &$res): EventResult
{ {
$link = $vars['link']; $link = $vars['link'];
try { try {
@ -177,7 +178,7 @@ class Embed extends Plugin
* *
* @throws DuplicateFoundException * @throws DuplicateFoundException
*/ */
public function onNewLinkFromNote(Link $link, Note $note): bool public function onNewLinkFromNote(Link $link, Note $note): EventResult
{ {
// Only handle text mime // Only handle text mime
$mimetype = $link->getMimetype(); $mimetype = $link->getMimetype();
@ -368,7 +369,7 @@ class Embed extends Plugin
return HTTPClient::get($url)->getContent(); return HTTPClient::get($url)->getContent();
} }
public function onAttachmentGetBestTitle(Attachment $attachment, Note $note, ?string &$title) public function onAttachmentGetBestTitle(Attachment $attachment, Note $note, ?string &$title): EventResult
{ {
try { try {
$embed = DB::findOneBy('attachment_embed', ['attachment_id' => $attachment->getId()]); $embed = DB::findOneBy('attachment_embed', ['attachment_id' => $attachment->getId()]);
@ -389,7 +390,7 @@ class Embed extends Plugin
* *
* @return bool true hook value * @return bool true hook value
*/ */
public function onPluginVersion(array &$versions): bool public function onPluginVersion(array &$versions): EventResult
{ {
$versions[] = [ $versions[] = [
'name' => 'Embed', 'name' => 'Embed',

View File

@ -45,6 +45,7 @@ use App\Util\Common;
use App\Util\Nickname; use App\Util\Nickname;
use Component\Notification\Entity\Attention; use Component\Notification\Entity\Attention;
use DateTime; use DateTime;
use EventResult;
use Plugin\Favourite\Entity\NoteFavourite; use Plugin\Favourite\Entity\NoteFavourite;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
@ -125,7 +126,7 @@ class Favourite extends NoteHandlerPlugin
* *
* @return bool Event hook, Event::next (true) is returned to allow Event to be handled by other handlers * @return bool Event hook, Event::next (true) is returned to allow Event to be handled by other handlers
*/ */
public function onAddNoteActions(Request $request, Note $note, array &$actions): bool public function onAddNoteActions(Request $request, Note $note, array &$actions): EventResult
{ {
if (\is_null($user = Common::user())) { if (\is_null($user = Common::user())) {
return Event::next; return Event::next;
@ -171,7 +172,7 @@ class Favourite extends NoteHandlerPlugin
* *
* @return bool Event hook, Event::next (true) is returned to allow Event to be handled by other handlers * @return bool Event hook, Event::next (true) is returned to allow Event to be handled by other handlers
*/ */
public function onAppendCardNote(array $vars, array &$result): bool public function onAppendCardNote(array $vars, array &$result): EventResult
{ {
// If note is the original and user isn't the one who repeated, append on end "user repeated this" // If note is the original and user isn't the one who repeated, append on end "user repeated this"
// If user is the one who repeated, append on end "you repeated this, remove repeat?" // If user is the one who repeated, append on end "you repeated this, remove repeat?"
@ -197,7 +198,7 @@ class Favourite extends NoteHandlerPlugin
/** /**
* Deletes every favourite entity in table related to a deleted Note * Deletes every favourite entity in table related to a deleted Note
*/ */
public function onNoteDeleteRelated(Note &$note, Actor $actor): bool public function onNoteDeleteRelated(Note &$note, Actor $actor): EventResult
{ {
$note_favourites_list = NoteFavourite::getNoteFavourites($note); $note_favourites_list = NoteFavourite::getNoteFavourites($note);
foreach ($note_favourites_list as $favourite_entity) { foreach ($note_favourites_list as $favourite_entity) {
@ -210,7 +211,7 @@ class Favourite extends NoteHandlerPlugin
/** /**
* Maps Routes to their respective Controllers * Maps Routes to their respective Controllers
*/ */
public function onAddRoute(Router $r): bool public function onAddRoute(Router $r): EventResult
{ {
// Add/remove note to/from favourites // Add/remove note to/from favourites
$r->connect(id: 'favourite_add', uri_path: '/object/note/{id<\d+>}/favour', target: [Controller\Favourite::class, 'favouriteAddNote']); $r->connect(id: 'favourite_add', uri_path: '/object/note/{id<\d+>}/favour', target: [Controller\Favourite::class, 'favouriteAddNote']);
@ -233,7 +234,7 @@ class Favourite extends NoteHandlerPlugin
* *
* @throws \App\Util\Exception\ServerException * @throws \App\Util\Exception\ServerException
*/ */
public function onCreateDefaultFeeds(int $actor_id, LocalUser $user, int &$ordering): bool public function onCreateDefaultFeeds(int $actor_id, LocalUser $user, int &$ordering): EventResult
{ {
DB::persist(Feed::create([ DB::persist(Feed::create([
'actor_id' => $actor_id, 'actor_id' => $actor_id,
@ -329,7 +330,7 @@ class Favourite extends NoteHandlerPlugin
return Event::stop; return Event::stop;
} }
public function onActivityPubNewNotification(Actor $sender, Activity $activity, array $targets, ?string $reason = null): bool public function onActivityPubNewNotification(Actor $sender, Activity $activity, array $targets, ?string $reason = null): EventResult
{ {
switch ($activity->getVerb()) { switch ($activity->getVerb()) {
case 'favourite': case 'favourite':
@ -366,7 +367,7 @@ class Favourite extends NoteHandlerPlugin
* *
* @return bool Returns `Event::stop` if handled, `Event::next` otherwise * @return bool Returns `Event::stop` if handled, `Event::next` otherwise
*/ */
public function onNewActivityPubActivity(Actor $actor, \ActivityPhp\Type\AbstractObject $type_activity, \ActivityPhp\Type\AbstractObject $type_object, ?\Plugin\ActivityPub\Entity\ActivitypubActivity &$ap_act): bool public function onNewActivityPubActivity(Actor $actor, \ActivityPhp\Type\AbstractObject $type_activity, \ActivityPhp\Type\AbstractObject $type_object, ?\Plugin\ActivityPub\Entity\ActivitypubActivity &$ap_act): EventResult
{ {
return $this->activitypub_handler($actor, $type_activity, $type_object, $ap_act); return $this->activitypub_handler($actor, $type_activity, $type_object, $ap_act);
} }
@ -390,7 +391,7 @@ class Favourite extends NoteHandlerPlugin
* *
* @return bool Returns `Event::stop` if handled, `Event::next` otherwise * @return bool Returns `Event::stop` if handled, `Event::next` otherwise
*/ */
public function onNewActivityPubActivityWithObject(Actor $actor, \ActivityPhp\Type\AbstractObject $type_activity, mixed $type_object, ?\Plugin\ActivityPub\Entity\ActivitypubActivity &$ap_act): bool public function onNewActivityPubActivityWithObject(Actor $actor, \ActivityPhp\Type\AbstractObject $type_activity, mixed $type_object, ?\Plugin\ActivityPub\Entity\ActivitypubActivity &$ap_act): EventResult
{ {
return $this->activitypub_handler($actor, $type_activity, $type_object, $ap_act); return $this->activitypub_handler($actor, $type_activity, $type_object, $ap_act);
} }
@ -403,7 +404,7 @@ class Favourite extends NoteHandlerPlugin
* *
* @return bool Returns `Event::stop` if handled, `Event::next` otherwise * @return bool Returns `Event::stop` if handled, `Event::next` otherwise
*/ */
public function onGSVerbToActivityStreamsTwoActivityType(string $verb, ?string &$gs_verb_to_activity_stream_two_verb): bool public function onGSVerbToActivityStreamsTwoActivityType(string $verb, ?string &$gs_verb_to_activity_stream_two_verb): EventResult
{ {
if ($verb === 'favourite') { if ($verb === 'favourite') {
$gs_verb_to_activity_stream_two_verb = 'Like'; $gs_verb_to_activity_stream_two_verb = 'Like';

View File

@ -31,6 +31,7 @@ use App\Core\Modules\Plugin;
use App\Util\Common; use App\Util\Common;
use App\Util\Exception\ClientException; use App\Util\Exception\ClientException;
use App\Util\Exception\ServerException; use App\Util\Exception\ServerException;
use EventResult;
/** /**
* Check attachment file size quotas * Check attachment file size quotas
@ -57,7 +58,7 @@ class FileQuota extends Plugin
* @throws ClientException * @throws ClientException
* @throws ServerException * @throws ServerException
*/ */
public function onEnforceUserFileQuota(int $filesize, int $user_id): bool public function onEnforceUserFileQuota(int $filesize, int $user_id): EventResult
{ {
$query = <<<'END' $query = <<<'END'
select sum(at.size) as total select sum(at.size) as total
@ -104,7 +105,7 @@ class FileQuota extends Plugin
* *
* @return bool true hook value * @return bool true hook value
*/ */
public function onPluginVersion(array &$versions): bool public function onPluginVersion(array &$versions): EventResult
{ {
$versions[] = [ $versions[] = [
'name' => 'FileQuota', 'name' => 'FileQuota',

View File

@ -32,6 +32,7 @@ use App\Util\Exception\ServerException;
use App\Util\Exception\TemporaryFileException; use App\Util\Exception\TemporaryFileException;
use App\Util\Formatting; use App\Util\Formatting;
use App\Util\TemporaryFile; use App\Util\TemporaryFile;
use EventResult;
use Exception; use Exception;
use Jcupitt\Vips; use Jcupitt\Vips;
use SplFileInfo; use SplFileInfo;
@ -59,7 +60,7 @@ class ImageEncoder extends Plugin
return GSFile::mimetypeMajor($mimetype) === 'image'; return GSFile::mimetypeMajor($mimetype) === 'image';
} }
public function onFileMetaAvailable(array &$event_map, string $mimetype): bool public function onFileMetaAvailable(array &$event_map, string $mimetype): EventResult
{ {
if (!self::shouldHandle($mimetype)) { if (!self::shouldHandle($mimetype)) {
return Event::next; return Event::next;
@ -68,7 +69,7 @@ class ImageEncoder extends Plugin
return Event::next; return Event::next;
} }
public function onFileSanitizerAvailable(array &$event_map, string $mimetype): bool public function onFileSanitizerAvailable(array &$event_map, string $mimetype): EventResult
{ {
if (!self::shouldHandle($mimetype)) { if (!self::shouldHandle($mimetype)) {
return Event::next; return Event::next;
@ -77,7 +78,7 @@ class ImageEncoder extends Plugin
return Event::next; return Event::next;
} }
public function onFileResizerAvailable(array &$event_map, string $mimetype): bool public function onFileResizerAvailable(array &$event_map, string $mimetype): EventResult
{ {
if (!self::shouldHandle($mimetype)) { if (!self::shouldHandle($mimetype)) {
return Event::next; return Event::next;
@ -179,7 +180,7 @@ class ImageEncoder extends Plugin
/** /**
* Generates the view for attachments of type Image * Generates the view for attachments of type Image
*/ */
public function onViewAttachment(array $vars, array &$res): bool public function onViewAttachment(array $vars, array &$res): EventResult
{ {
if (!self::shouldHandle($vars['attachment']->getMimetype())) { if (!self::shouldHandle($vars['attachment']->getMimetype())) {
return Event::next; return Event::next;
@ -260,7 +261,7 @@ class ImageEncoder extends Plugin
* *
* @return bool true hook value * @return bool true hook value
*/ */
public function onPluginVersion(array &$versions): bool public function onPluginVersion(array &$versions): EventResult
{ {
$versions[] = [ $versions[] = [
'name' => 'ImageEncoder', 'name' => 'ImageEncoder',

View File

@ -33,17 +33,18 @@ namespace Plugin\LatexNotes;
use App\Core\Event; use App\Core\Event;
use App\Core\Modules\Plugin; use App\Core\Modules\Plugin;
use EventResult;
use PhpLatex_Parser; use PhpLatex_Parser;
use PhpLatex_Renderer_Html; use PhpLatex_Renderer_Html;
class LatexNotes extends Plugin class LatexNotes extends Plugin
{ {
public function onPostingAvailableContentTypes(array &$types): bool public function onPostingAvailableContentTypes(array &$types): EventResult
{ {
$types['LaTeX'] = 'application/x-latex'; $types['LaTeX'] = 'application/x-latex';
return Event::next; return Event::next;
} }
public function onRenderNoteContent($content, $content_type, &$rendered): bool public function onRenderNoteContent($content, $content_type, &$rendered): EventResult
{ {
if ($content_type !== 'application/x-latex') { if ($content_type !== 'application/x-latex') {
return Event::next; return Event::next;

View File

@ -33,16 +33,17 @@ namespace Plugin\MarkdownNotes;
use App\Core\Event; use App\Core\Event;
use App\Core\Modules\Plugin; use App\Core\Modules\Plugin;
use EventResult;
use Parsedown; use Parsedown;
class MarkdownNotes extends Plugin class MarkdownNotes extends Plugin
{ {
public function onPostingAvailableContentTypes(array &$types): bool public function onPostingAvailableContentTypes(array &$types): EventResult
{ {
$types['Markdown'] = 'text/markdown'; $types['Markdown'] = 'text/markdown';
return Event::next; return Event::next;
} }
public function onRenderNoteContent($content, $content_type, &$rendered): bool public function onRenderNoteContent($content, $content_type, &$rendered): EventResult
{ {
if ($content_type !== 'text/markdown') { if ($content_type !== 'text/markdown') {
return Event::next; return Event::next;

View File

@ -40,6 +40,7 @@ use App\Util\Exception\BugFoundException;
use App\Util\Exception\ClientException; use App\Util\Exception\ClientException;
use App\Util\Formatting; use App\Util\Formatting;
use App\Util\Functional as GSF; use App\Util\Functional as GSF;
use EventResult;
use Functional as F; use Functional as F;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
@ -94,7 +95,7 @@ class NoteTypeFeedFilter extends Plugin
* *
* Includes if any positive type matches, but removes if any negated matches * Includes if any positive type matches, but removes if any negated matches
*/ */
public function onFilterNoteList(?Actor $actor, array &$notes, Request $request): bool public function onFilterNoteList(?Actor $actor, array &$notes, Request $request): EventResult
{ {
$types = $this->normalizeTypesList(\is_null($request->get('note-types')) ? [] : explode(',', $request->get('note-types'))); $types = $this->normalizeTypesList(\is_null($request->get('note-types')) ? [] : explode(',', $request->get('note-types')));
$notes = F\select( $notes = F\select(
@ -108,7 +109,7 @@ class NoteTypeFeedFilter extends Plugin
$include = false; $include = false;
foreach ($types as $type) { foreach ($types as $type) {
$is_negate = $type[0] === '!'; $is_negate = $type[0] === '!';
$type = Formatting::removePrefix($type, '!'); $type = Formatting::removePrefix($type, '!');
switch ($type) { switch ($type) {
case 'text': case 'text':
$ret = !\is_null($note->getContent()); $ret = !\is_null($note->getContent());
@ -139,7 +140,7 @@ class NoteTypeFeedFilter extends Plugin
/** /**
* Draw the media feed navigation. * Draw the media feed navigation.
*/ */
public function onAddFeedActions(Request $request, bool $is_not_empty, &$res): bool public function onAddFeedActions(Request $request, bool $is_not_empty, &$res): EventResult
{ {
$qs = []; $qs = [];
$query_string = $request->getQueryString(); $query_string = $request->getQueryString();
@ -184,7 +185,7 @@ class NoteTypeFeedFilter extends Plugin
* *
* @return bool hook value; true means continue processing, false means stop * @return bool hook value; true means continue processing, false means stop
*/ */
public function onEndShowStyles(array &$styles, string $route): bool public function onEndShowStyles(array &$styles, string $route): EventResult
{ {
$styles[] = 'plugins/NoteTypeFeedFilter/assets/css/noteTypeFeedFilter.css'; $styles[] = 'plugins/NoteTypeFeedFilter/assets/css/noteTypeFeedFilter.css';
return Event::next; return Event::next;

View File

@ -38,6 +38,7 @@ use App\Core\Modules\Plugin;
use App\Core\Router; use App\Core\Router;
use App\Util\Common; use App\Util\Common;
use DateInterval; use DateInterval;
use EventResult;
use Exception; use Exception;
use League\OAuth2\Server\AuthorizationServer; use League\OAuth2\Server\AuthorizationServer;
use League\OAuth2\Server\CryptKey; use League\OAuth2\Server\CryptKey;
@ -67,7 +68,7 @@ class OAuth2 extends Plugin
/** /**
* @throws Exception * @throws Exception
*/ */
public function onInitializePlugin() public function onInitializePlugin(): EventResult
{ {
self::$authorization_server = new AuthorizationServer( self::$authorization_server = new AuthorizationServer(
new Repository\Client, new Repository\Client,
@ -86,6 +87,7 @@ class OAuth2 extends Plugin
), ),
new DateInterval('PT1H'), new DateInterval('PT1H'),
); );
return Event::next;
} }
/** /**
@ -94,7 +96,7 @@ class OAuth2 extends Plugin
* *
* @param Router $r the router that was initialized * @param Router $r the router that was initialized
*/ */
public function onAddRoute(Router $r): bool public function onAddRoute(Router $r): EventResult
{ {
$r->connect('oauth2_mastodon_api_apps', '/api/v1/apps', C\Client::class, ['http-methods' => ['POST']]); $r->connect('oauth2_mastodon_api_apps', '/api/v1/apps', C\Client::class, ['http-methods' => ['POST']]);
$r->connect('oauth2_client', '/oauth/client', C\Client::class, ['http-methods' => ['POST']]); $r->connect('oauth2_client', '/oauth/client', C\Client::class, ['http-methods' => ['POST']]);
@ -103,7 +105,7 @@ class OAuth2 extends Plugin
return Event::next; return Event::next;
} }
public function onEndHostMetaLinks(array &$links): bool public function onEndHostMetaLinks(array &$links): EventResult
{ {
$links[] = new XML_XRD_Element_Link(self::OAUTH_REQUEST_TOKEN_REL, Router::url('oauth2_client', type: Router::ABSOLUTE_URL)); $links[] = new XML_XRD_Element_Link(self::OAUTH_REQUEST_TOKEN_REL, Router::url('oauth2_client', type: Router::ABSOLUTE_URL));
$links[] = new XML_XRD_Element_Link(self::OAUTH_AUTHORIZE_REL, Router::url('oauth2_authorize', type: Router::ABSOLUTE_URL)); $links[] = new XML_XRD_Element_Link(self::OAUTH_AUTHORIZE_REL, Router::url('oauth2_authorize', type: Router::ABSOLUTE_URL));

View File

@ -32,6 +32,7 @@ use App\Util\Common;
use App\Util\Exception\NotFoundException; use App\Util\Exception\NotFoundException;
use App\Util\Exception\RedirectException; use App\Util\Exception\RedirectException;
use App\Util\Exception\ServerException; use App\Util\Exception\ServerException;
use EventResult;
use Plugin\Oomox\Controller as C; use Plugin\Oomox\Controller as C;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
@ -50,7 +51,7 @@ class Oomox extends Plugin
/** /**
* Maps Routes to their respective Controllers * Maps Routes to their respective Controllers
*/ */
public function onAddRoute(Router $r): bool public function onAddRoute(Router $r): EventResult
{ {
$r->connect('oomox_settings', 'settings/oomox', [Controller\Oomox::class, 'oomoxSettings']); $r->connect('oomox_settings', 'settings/oomox', [Controller\Oomox::class, 'oomoxSettings']);
$r->connect('oomox_css', 'plugins/oomox/colours', [Controller\Oomox::class, 'oomoxCSS']); $r->connect('oomox_css', 'plugins/oomox/colours', [Controller\Oomox::class, 'oomoxCSS']);
@ -65,7 +66,7 @@ class Oomox extends Plugin
* @throws RedirectException * @throws RedirectException
* @throws ServerException * @throws ServerException
*/ */
public function onPopulateSettingsTabs(Request $request, string $section, array &$tabs): bool public function onPopulateSettingsTabs(Request $request, string $section, array &$tabs): EventResult
{ {
if ($section === 'colours') { if ($section === 'colours') {
$tabs[] = [ $tabs[] = [
@ -108,7 +109,7 @@ class Oomox extends Plugin
/** /**
* Adds to array $styles the generated CSS according to user settings, if any are present. * Adds to array $styles the generated CSS according to user settings, if any are present.
*/ */
public function onEndShowStyles(array &$styles, string $route): bool public function onEndShowStyles(array &$styles, string $route): EventResult
{ {
$user = Common::user(); $user = Common::user();
if ($user && Cache::get(self::cacheKey($user), static fn () => self::getEntity($user))) { if ($user && Cache::get(self::cacheKey($user), static fn () => self::getEntity($user))) {

View File

@ -35,6 +35,7 @@ namespace Plugin\Pinboard;
use App\Core\Event; use App\Core\Event;
use App\Core\Modules\Plugin; use App\Core\Modules\Plugin;
use App\Core\Router; use App\Core\Router;
use EventResult;
use Plugin\Pinboard\Controller as C; use Plugin\Pinboard\Controller as C;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
@ -42,7 +43,7 @@ class Pinboard extends Plugin
{ {
public const controller_route = 'pinboard_settings'; public const controller_route = 'pinboard_settings';
public function onAddRoute(Router $r): bool public function onAddRoute(Router $r): EventResult
{ {
$r->connect(self::controller_route, '/pinboard/settings', C\Settings::class, options: ['method' => 'post']); $r->connect(self::controller_route, '/pinboard/settings', C\Settings::class, options: ['method' => 'post']);
@ -68,7 +69,7 @@ class Pinboard extends Plugin
return Event::next; return Event::next;
} }
public function onPopulateSettingsTabs(Request $request, string $section, array &$tabs): bool public function onPopulateSettingsTabs(Request $request, string $section, array &$tabs): EventResult
{ {
if ($section === 'api') { if ($section === 'api') {
$tabs[] = [ $tabs[] = [

View File

@ -46,14 +46,15 @@ use Doctrine\Common\Collections\ExpressionBuilder;
use Doctrine\ORM\Query\Expr; use Doctrine\ORM\Query\Expr;
use Doctrine\ORM\QueryBuilder; use Doctrine\ORM\QueryBuilder;
use EventResult;
use Plugin\PinnedNotes\Controller as C; use Plugin\PinnedNotes\Controller as C;
use Plugin\PinnedNotes\Entity as E;
use Plugin\PinnedNotes\Entity as E;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
class PinnedNotes extends Plugin class PinnedNotes extends Plugin
{ {
public function onAddRoute(Router $r): bool public function onAddRoute(Router $r): EventResult
{ {
// Pin and unpin notes // Pin and unpin notes
$r->connect(id: 'toggle_note_pin', uri_path: '/object/note/{id<\d+>}/pin', target: [C\PinnedNotes::class, 'togglePin']); $r->connect(id: 'toggle_note_pin', uri_path: '/object/note/{id<\d+>}/pin', target: [C\PinnedNotes::class, 'togglePin']);
@ -73,7 +74,7 @@ class PinnedNotes extends Plugin
return Event::next; return Event::next;
} }
public function onBeforeFeed(Request $request, &$res): bool public function onBeforeFeed(Request $request, &$res): EventResult
{ {
$path = $request->attributes->get('_route'); $path = $request->attributes->get('_route');
if ($path === 'actor_view_nickname') { if ($path === 'actor_view_nickname') {
@ -92,7 +93,7 @@ class PinnedNotes extends Plugin
return Event::next; return Event::next;
} }
public function onCollectionQueryAddJoins(QueryBuilder &$note_qb, QueryBuilder &$actor_qb): bool public function onCollectionQueryAddJoins(QueryBuilder &$note_qb, QueryBuilder &$actor_qb): EventResult
{ {
if (!\in_array('pinned_notes', $note_qb->getAllAliases())) { if (!\in_array('pinned_notes', $note_qb->getAllAliases())) {
$note_qb->leftJoin(E\PinnedNotes::class, 'pinned_notes', Expr\Join::WITH, 'note.id = pinned_notes.note_id'); $note_qb->leftJoin(E\PinnedNotes::class, 'pinned_notes', Expr\Join::WITH, 'note.id = pinned_notes.note_id');
@ -100,7 +101,7 @@ class PinnedNotes extends Plugin
return Event::next; return Event::next;
} }
public function onCollectionQueryCreateExpression(ExpressionBuilder $eb, string $term, ?string $language, ?Actor $actor, &$note_expr, &$actor_expr): bool public function onCollectionQueryCreateExpression(ExpressionBuilder $eb, string $term, ?string $language, ?Actor $actor, &$note_expr, &$actor_expr): EventResult
{ {
if ($term === 'pinned:true') { if ($term === 'pinned:true') {
$note_expr = $eb->neq('pinned_notes', null); $note_expr = $eb->neq('pinned_notes', null);
@ -114,7 +115,7 @@ class PinnedNotes extends Plugin
return Event::next; return Event::next;
} }
public function onAddNoteActions(Request $request, Note $note, array &$actions): bool public function onAddNoteActions(Request $request, Note $note, array &$actions): EventResult
{ {
$user = Common::user(); $user = Common::user();
if ($user->getId() !== $note->getActorId()) { if ($user->getId() !== $note->getActorId()) {
@ -139,7 +140,7 @@ class PinnedNotes extends Plugin
return Event::next; return Event::next;
} }
public function onEndShowStyles(array &$styles, string $route): bool public function onEndShowStyles(array &$styles, string $route): EventResult
{ {
$styles[] = 'plugins/PinnedNotes/assets/css/pinned-notes.css'; $styles[] = 'plugins/PinnedNotes/assets/css/pinned-notes.css';
return Event::next; return Event::next;
@ -147,7 +148,7 @@ class PinnedNotes extends Plugin
// Activity Pub handling stuff // Activity Pub handling stuff
public function onActivityStreamsTwoContext(array &$activity_streams_two_context): bool public function onActivityStreamsTwoContext(array &$activity_streams_two_context): EventResult
{ {
$activity_streams_two_context[] = ['toot' => 'http://joinmastodon.org/ns#']; $activity_streams_two_context[] = ['toot' => 'http://joinmastodon.org/ns#'];
$activity_streams_two_context[] = [ $activity_streams_two_context[] = [
@ -159,7 +160,7 @@ class PinnedNotes extends Plugin
return Event::next; return Event::next;
} }
public function onActivityPubAddActivityStreamsTwoData(string $type_name, &$type): bool public function onActivityPubAddActivityStreamsTwoData(string $type_name, &$type): EventResult
{ {
if ($type_name === 'Person') { if ($type_name === 'Person') {
$actor = \Plugin\ActivityPub\Util\Explorer::getOneFromUri($type->get('id')); $actor = \Plugin\ActivityPub\Util\Explorer::getOneFromUri($type->get('id'));

View File

@ -34,6 +34,7 @@ use App\Util\Exception\InvalidFormException;
use App\Util\Exception\NotFoundException; use App\Util\Exception\NotFoundException;
use App\Util\Exception\RedirectException; use App\Util\Exception\RedirectException;
use App\Util\Exception\ServerException; use App\Util\Exception\ServerException;
use EventResult;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType; use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\Extension\Core\Type\SubmitType;
@ -57,7 +58,7 @@ class Poll extends NoteHandlerPlugin
* *
* @return bool hook value; true means continue processing, false means stop * @return bool hook value; true means continue processing, false means stop
*/ */
public function onAddRoute(Router $r): bool public function onAddRoute(Router $r): EventResult
{ {
$r->connect('newpoll', 'main/poll/new/{num<\\d+>?3}', [Controller\NewPoll::class, 'newpoll']); $r->connect('newpoll', 'main/poll/new/{num<\\d+>?3}', [Controller\NewPoll::class, 'newpoll']);
@ -69,7 +70,7 @@ class Poll extends NoteHandlerPlugin
* *
* @return bool hook value; true means continue processing, false means stop. * @return bool hook value; true means continue processing, false means stop.
* *
* public function onStartTwigPopulateVars(array &$vars): bool * public function onStartTwigPopulateVars(array &$vars): \EventResult
* { * {
* $vars['tabs'][] = ['title' => 'Poll', * $vars['tabs'][] = ['title' => 'Poll',
* 'href' => 'newpoll', * 'href' => 'newpoll',
@ -84,7 +85,7 @@ class Poll extends NoteHandlerPlugin
* *
* @return bool hook value; true means continue processing, false means stop * @return bool hook value; true means continue processing, false means stop
*/ */
public function onStartShowStyles(array &$styles): bool public function onStartShowStyles(array &$styles): EventResult
{ {
$styles[] = 'poll/poll.css'; $styles[] = 'poll/poll.css';
return Event::next; return Event::next;
@ -102,7 +103,7 @@ class Poll extends NoteHandlerPlugin
* *
* @return bool hook value; true means continue processing, false means stop * @return bool hook value; true means continue processing, false means stop
*/ */
public function onShowNoteContent(Request $request, Note $note, array &$otherContent): bool public function onShowNoteContent(Request $request, Note $note, array &$otherContent): EventResult
{ {
$responses = null; $responses = null;
$formView = null; $formView = null;

View File

@ -30,6 +30,7 @@ use App\Core\Router;
use App\Util\Exception\RedirectException; use App\Util\Exception\RedirectException;
use App\Util\Exception\ServerException; use App\Util\Exception\ServerException;
use App\Util\Formatting; use App\Util\Formatting;
use EventResult;
use Plugin\ProfileColor\Controller as C; use Plugin\ProfileColor\Controller as C;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
@ -51,7 +52,7 @@ class ProfileColor extends Plugin
* *
* @return bool hook value; true means continue processing, false means stop * @return bool hook value; true means continue processing, false means stop
*/ */
public function onAddRoute(Router $r): bool public function onAddRoute(Router $r): EventResult
{ {
$r->connect('settings_profile_color', 'settings/color', [Controller\ProfileColor::class, 'profileColorSettings']); $r->connect('settings_profile_color', 'settings/color', [Controller\ProfileColor::class, 'profileColorSettings']);
return Event::next; return Event::next;
@ -61,7 +62,7 @@ class ProfileColor extends Plugin
* @throws RedirectException * @throws RedirectException
* @throws ServerException * @throws ServerException
*/ */
public function onPopulateSettingsTabs(Request $request, string $section, array &$tabs): bool public function onPopulateSettingsTabs(Request $request, string $section, array &$tabs): EventResult
{ {
if ($section === 'colours') { if ($section === 'colours') {
$tabs[] = [ $tabs[] = [
@ -77,7 +78,7 @@ class ProfileColor extends Plugin
/** /**
* Renders profileColorView, which changes the background color of that profile. * Renders profileColorView, which changes the background color of that profile.
*/ */
public function onAppendCardProfile(array $vars, array &$res): bool public function onAppendCardProfile(array $vars, array &$res): EventResult
{ {
$actor = $vars['actor']; $actor = $vars['actor'];
if ($actor !== null) { if ($actor !== null) {

View File

@ -27,6 +27,7 @@ use App\Core\Event;
use App\Core\Modules\Plugin; use App\Core\Modules\Plugin;
use Component\Circle\Entity\ActorTag; use Component\Circle\Entity\ActorTag;
use Component\Tag\Entity\NoteTag; use Component\Tag\Entity\NoteTag;
use EventResult;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
class RelatedTags extends Plugin class RelatedTags extends Plugin
@ -34,7 +35,7 @@ class RelatedTags extends Plugin
/** /**
* Add a pinnned block containing tags related to the current page, be it note tags or actor tags * Add a pinnned block containing tags related to the current page, be it note tags or actor tags
*/ */
public function onAddPinnedFeedContent(Request $request, array &$pinned) public function onAddPinnedFeedContent(Request $request, array &$pinned): EventResult
{ {
// Lets not use language, probably wouldn't make it more helpful // Lets not use language, probably wouldn't make it more helpful
//$locale = $request->attributes->get('locale'); //$locale = $request->attributes->get('locale');

View File

@ -45,6 +45,7 @@ use Component\Language\Entity\Language;
use Component\Notification\Entity\Attention; use Component\Notification\Entity\Attention;
use Component\Posting\Posting; use Component\Posting\Posting;
use DateTime; use DateTime;
use EventResult;
use Plugin\RepeatNote\Entity\NoteRepeat as RepeatEntity; use Plugin\RepeatNote\Entity\NoteRepeat as RepeatEntity;
use const SORT_REGULAR; use const SORT_REGULAR;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
@ -211,7 +212,7 @@ class RepeatNote extends NoteHandlerPlugin
* *
* @return bool Event hook, Event::next (true) is returned to allow Event to be handled by other handlers * @return bool Event hook, Event::next (true) is returned to allow Event to be handled by other handlers
*/ */
public function onFilterNoteList(?Actor $actor, array &$notes, Request $request): bool public function onFilterNoteList(?Actor $actor, array &$notes, Request $request): EventResult
{ {
// Replaces repeat with original note on Actor feed // Replaces repeat with original note on Actor feed
// it's pretty cool // it's pretty cool
@ -236,7 +237,7 @@ class RepeatNote extends NoteHandlerPlugin
* *
* @return bool Event hook, Event::next (true) is returned to allow Event to be handled by other handlers * @return bool Event hook, Event::next (true) is returned to allow Event to be handled by other handlers
*/ */
public function onAddNoteActions(Request $request, Note $note, array &$actions): bool public function onAddNoteActions(Request $request, Note $note, array &$actions): EventResult
{ {
// Only logged users can repeat notes // Only logged users can repeat notes
if (\is_null($user = Common::user())) { if (\is_null($user = Common::user())) {
@ -280,7 +281,7 @@ class RepeatNote extends NoteHandlerPlugin
* *
* @return bool Event hook, Event::next (true) is returned to allow Event to be handled by other handlers * @return bool Event hook, Event::next (true) is returned to allow Event to be handled by other handlers
*/ */
public function onAppendCardNote(array $vars, array &$result) public function onAppendCardNote(array $vars, array &$result): EventResult
{ {
// If note is the original and user isn't the one who repeated, append on end "user repeated this" // If note is the original and user isn't the one who repeated, append on end "user repeated this"
// If user is the one who repeated, append on end "you repeated this, remove repeat?" // If user is the one who repeated, append on end "you repeated this, remove repeat?"
@ -318,7 +319,7 @@ class RepeatNote extends NoteHandlerPlugin
* *
* @return bool Event hook, Event::next (true) is returned to allow Event to be handled by other handlers * @return bool Event hook, Event::next (true) is returned to allow Event to be handled by other handlers
*/ */
public function onNoteDeleteRelated(Note &$note, Actor $actor): bool public function onNoteDeleteRelated(Note &$note, Actor $actor): EventResult
{ {
$note_repeats_list = RepeatEntity::getNoteRepeats($note); $note_repeats_list = RepeatEntity::getNoteRepeats($note);
foreach ($note_repeats_list as $note_repeat) { foreach ($note_repeats_list as $note_repeat) {
@ -340,7 +341,7 @@ class RepeatNote extends NoteHandlerPlugin
* *
* @return bool Event hook, Event::next (true) is returned to allow Event to be handled by other handlers * @return bool Event hook, Event::next (true) is returned to allow Event to be handled by other handlers
*/ */
public function onAddRoute(Router $r): bool public function onAddRoute(Router $r): EventResult
{ {
// Add/remove note to/from repeats // Add/remove note to/from repeats
$r->connect(id: 'repeat_add', uri_path: '/object/note/{note_id<\d+>}/repeat', target: [Controller\Repeat::class, 'repeatAddNote']); $r->connect(id: 'repeat_add', uri_path: '/object/note/{note_id<\d+>}/repeat', target: [Controller\Repeat::class, 'repeatAddNote']);
@ -427,7 +428,7 @@ class RepeatNote extends NoteHandlerPlugin
return Event::stop; return Event::stop;
} }
public function onActivityPubNewNotification(Actor $sender, Activity $activity, array $targets, ?string $reason = null): bool public function onActivityPubNewNotification(Actor $sender, Activity $activity, array $targets, ?string $reason = null): EventResult
{ {
switch ($activity->getVerb()) { switch ($activity->getVerb()) {
case 'repeat': case 'repeat':
@ -465,7 +466,7 @@ class RepeatNote extends NoteHandlerPlugin
* *
* @return bool Returns `Event::stop` if handled, `Event::next` otherwise * @return bool Returns `Event::stop` if handled, `Event::next` otherwise
*/ */
public function onNewActivityPubActivity(Actor $actor, \ActivityPhp\Type\AbstractObject $type_activity, \ActivityPhp\Type\AbstractObject $type_object, ?\Plugin\ActivityPub\Entity\ActivitypubActivity &$ap_act): bool public function onNewActivityPubActivity(Actor $actor, \ActivityPhp\Type\AbstractObject $type_activity, \ActivityPhp\Type\AbstractObject $type_object, ?\Plugin\ActivityPub\Entity\ActivitypubActivity &$ap_act): EventResult
{ {
return $this->activitypub_handler($actor, $type_activity, $type_object, $ap_act); return $this->activitypub_handler($actor, $type_activity, $type_object, $ap_act);
} }
@ -490,7 +491,7 @@ class RepeatNote extends NoteHandlerPlugin
* *
* @return bool Returns `Event::stop` if handled, `Event::next` otherwise * @return bool Returns `Event::stop` if handled, `Event::next` otherwise
*/ */
public function onNewActivityPubActivityWithObject(Actor $actor, \ActivityPhp\Type\AbstractObject $type_activity, mixed $type_object, ?\Plugin\ActivityPub\Entity\ActivitypubActivity &$ap_act): bool public function onNewActivityPubActivityWithObject(Actor $actor, \ActivityPhp\Type\AbstractObject $type_activity, mixed $type_object, ?\Plugin\ActivityPub\Entity\ActivitypubActivity &$ap_act): EventResult
{ {
return $this->activitypub_handler($actor, $type_activity, $type_object, $ap_act); return $this->activitypub_handler($actor, $type_activity, $type_object, $ap_act);
} }
@ -503,7 +504,7 @@ class RepeatNote extends NoteHandlerPlugin
* *
* @return bool Returns `Event::stop` if handled, `Event::next` otherwise * @return bool Returns `Event::stop` if handled, `Event::next` otherwise
*/ */
public function onGSVerbToActivityStreamsTwoActivityType(string $verb, ?string &$gs_verb_to_activity_stream_two_verb): bool public function onGSVerbToActivityStreamsTwoActivityType(string $verb, ?string &$gs_verb_to_activity_stream_two_verb): EventResult
{ {
if ($verb === 'repeat') { if ($verb === 'repeat') {
$gs_verb_to_activity_stream_two_verb = 'Announce'; $gs_verb_to_activity_stream_two_verb = 'Announce';

View File

@ -25,12 +25,13 @@ namespace Plugin\StemWord;
use App\Core\Event; use App\Core\Event;
use App\Core\Modules\Plugin; use App\Core\Modules\Plugin;
use EventResult;
use Wamania\Snowball\NotFoundException; use Wamania\Snowball\NotFoundException;
use Wamania\Snowball\StemmerFactory; use Wamania\Snowball\StemmerFactory;
class StemWord extends Plugin class StemWord extends Plugin
{ {
public function onStemWord(string $language, string $word, ?string &$out) public function onStemWord(string $language, string $word, ?string &$out): EventResult
{ {
$language = explode('_', $language)[0]; $language = explode('_', $language)[0];
try { try {

View File

@ -37,6 +37,7 @@ use Component\Attachment\Entity\AttachmentThumbnail;
use Component\Attachment\Entity\AttachmentToLink; use Component\Attachment\Entity\AttachmentToLink;
use Component\Attachment\Entity\AttachmentToNote; use Component\Attachment\Entity\AttachmentToNote;
use Component\Link\Entity\Link; use Component\Link\Entity\Link;
use EventResult;
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface; use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface; use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface; use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
@ -95,7 +96,7 @@ class StoreRemoteMedia extends Plugin
* @throws ServerException * @throws ServerException
* @throws TemporaryFileException * @throws TemporaryFileException
*/ */
public function onNewLinkFromNote(Link $link, Note $note): bool public function onNewLinkFromNote(Link $link, Note $note): EventResult
{ {
// Embed is the plugin to handle these // Embed is the plugin to handle these
if ($link->getMimetypeMajor() === 'text') { if ($link->getMimetypeMajor() === 'text') {
@ -236,7 +237,7 @@ class StoreRemoteMedia extends Plugin
* *
* @return bool true hook value * @return bool true hook value
*/ */
public function onPluginVersion(array &$versions): bool public function onPluginVersion(array &$versions): EventResult
{ {
$versions[] = [ $versions[] = [
'name' => 'StoreRemoteMedia', 'name' => 'StoreRemoteMedia',

View File

@ -34,6 +34,7 @@ use App\Entity\LocalUser;
use App\Entity\Note; use App\Entity\Note;
use Component\Tag\Entity\NoteTag; use Component\Tag\Entity\NoteTag;
use Component\Tag\Entity\NoteTagBlock; use Component\Tag\Entity\NoteTagBlock;
use EventResult;
use Functional as F; use Functional as F;
use Plugin\TagBasedFiltering\Controller as C; use Plugin\TagBasedFiltering\Controller as C;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
@ -51,14 +52,14 @@ class TagBasedFiltering extends Plugin
return ['note' => "blocked-note-tags-{$actor_id}", 'actor' => "blocked-actor-tags-{$actor_id}"]; return ['note' => "blocked-note-tags-{$actor_id}", 'actor' => "blocked-actor-tags-{$actor_id}"];
} }
public function onAddRoute(Router $r) public function onAddRoute(Router $r): EventResult
{ {
$r->connect(id: self::NOTE_TAG_FILTER_ROUTE, uri_path: '/filter/edit-blocked-note-tags/{note_id<\d+>}', target: [Controller\AddBlocked::class, 'addBlockedNoteTags']); $r->connect(id: self::NOTE_TAG_FILTER_ROUTE, uri_path: '/filter/edit-blocked-note-tags/{note_id<\d+>}', target: [Controller\AddBlocked::class, 'addBlockedNoteTags']);
$r->connect(id: self::ACTOR_TAG_FILTER_ROUTE, uri_path: '/filter/edit-blocked-actor-tags/{actor_id<\d+>}', target: [Controller\AddBlocked::class, 'addBlockedActorTags']); $r->connect(id: self::ACTOR_TAG_FILTER_ROUTE, uri_path: '/filter/edit-blocked-actor-tags/{actor_id<\d+>}', target: [Controller\AddBlocked::class, 'addBlockedActorTags']);
return Event::next; return Event::next;
} }
public function onAddExtraNoteActions(Request $request, Note $note, array &$actions) public function onAddExtraNoteActions(Request $request, Note $note, array &$actions): EventResult
{ {
$actions[] = [ $actions[] = [
'title' => _m('Block note tags'), 'title' => _m('Block note tags'),
@ -71,12 +72,13 @@ class TagBasedFiltering extends Plugin
'classes' => '', 'classes' => '',
'url' => Router::url(self::ACTOR_TAG_FILTER_ROUTE, ['actor_id' => $note->getActor()->getId()]), 'url' => Router::url(self::ACTOR_TAG_FILTER_ROUTE, ['actor_id' => $note->getActor()->getId()]),
]; ];
return Event::next;
} }
/** /**
* Filter out tags from notes or actors, per the user request * Filter out tags from notes or actors, per the user request
*/ */
public function onFilterNoteList(?Actor $actor, array &$notes, Request $request) public function onFilterNoteList(?Actor $actor, array &$notes, Request $request): EventResult
{ {
if (\is_null($actor)) { if (\is_null($actor)) {
return Event::next; return Event::next;
@ -102,7 +104,7 @@ class TagBasedFiltering extends Plugin
return Event::next; return Event::next;
} }
public function onPopulateSettingsTabs(Request $request, string $section, array &$tabs): bool public function onPopulateSettingsTabs(Request $request, string $section, array &$tabs): EventResult
{ {
if ($section === 'muting') { if ($section === 'muting') {
$tabs[] = [ $tabs[] = [

View File

@ -26,6 +26,7 @@ use App\Core\Modules\Plugin;
use App\Entity\Note; use App\Entity\Note;
use App\Util\Common; use App\Util\Common;
use App\Util\Formatting; use App\Util\Formatting;
use EventResult;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
class TreeNotes extends Plugin class TreeNotes extends Plugin
@ -34,7 +35,7 @@ class TreeNotes extends Plugin
* Formatting notes without taking a direct reply out of context * Formatting notes without taking a direct reply out of context
* Show whole conversation in conversation related routes. * Show whole conversation in conversation related routes.
*/ */
public function onFormatNoteList(array $notes_in, array &$notes_out, Request $request) public function onFormatNoteList(array $notes_in, array &$notes_out, Request $request): EventResult
{ {
if (str_starts_with($request->get('_route'), 'conversation')) { if (str_starts_with($request->get('_route'), 'conversation')) {
$parents = $this->conversationFormat($notes_in); $parents = $this->conversationFormat($notes_in);
@ -42,6 +43,7 @@ class TreeNotes extends Plugin
} else { } else {
$notes_out = $this->feedFormatTree($notes_in); $notes_out = $this->feedFormatTree($notes_in);
} }
return Event::stop;
} }
/** /**
@ -122,7 +124,7 @@ class TreeNotes extends Plugin
]; ];
} }
public function onAppendNoteBlock(Request $request, array $conversation, array &$res): bool public function onAppendNoteBlock(Request $request, array $conversation, array &$res): EventResult
{ {
if (\array_key_exists('replies', $conversation)) { if (\array_key_exists('replies', $conversation)) {
$res[] = Formatting::twigRenderFile( $res[] = Formatting::twigRenderFile(

View File

@ -36,6 +36,7 @@ use App\Core\DB;
use App\Core\Event; use App\Core\Event;
use App\Core\Modules\Plugin; use App\Core\Modules\Plugin;
use App\Entity\Actor; use App\Entity\Actor;
use EventResult;
use Plugin\ActivityPub\Entity\ActivitypubActor; use Plugin\ActivityPub\Entity\ActivitypubActor;
use Plugin\UnboundGroup\Controller\GroupSettings; use Plugin\UnboundGroup\Controller\GroupSettings;
use Plugin\UnboundGroup\Entity\activitypubGroupUnbound; use Plugin\UnboundGroup\Entity\activitypubGroupUnbound;
@ -49,7 +50,7 @@ use Symfony\Component\HttpFoundation\Request;
*/ */
class UnboundGroup extends Plugin class UnboundGroup extends Plugin
{ {
public function onPopulateSettingsTabs(Request $request, string $section, array &$tabs): bool public function onPopulateSettingsTabs(Request $request, string $section, array &$tabs): EventResult
{ {
if ($section === 'profile' && $request->get('_route') === 'group_actor_settings') { if ($section === 'profile' && $request->get('_route') === 'group_actor_settings') {
$tabs[] = [ $tabs[] = [
@ -68,7 +69,7 @@ class UnboundGroup extends Plugin
return Event::next; return Event::next;
} }
public function onActivityStreamsTwoContext(array &$activity_streams_two_context): bool public function onActivityStreamsTwoContext(array &$activity_streams_two_context): EventResult
{ {
$activity_streams_two_context[] = [ $activity_streams_two_context[] = [
'unbound' => [ 'unbound' => [
@ -79,7 +80,7 @@ class UnboundGroup extends Plugin
return Event::next; return Event::next;
} }
public function onActivityPubAddActivityStreamsTwoData(string $type_name, &$type): bool public function onActivityPubAddActivityStreamsTwoData(string $type_name, &$type): EventResult
{ {
if ($type_name === 'Group' || $type_name === 'Organization') { if ($type_name === 'Group' || $type_name === 'Organization') {
$actor = \Plugin\ActivityPub\Util\Explorer::getOneFromUri($type->getId()); $actor = \Plugin\ActivityPub\Util\Explorer::getOneFromUri($type->getId());
@ -92,7 +93,7 @@ class UnboundGroup extends Plugin
return Event::next; return Event::next;
} }
public function onActivityPubCreateOrUpdateActor(\ActivityPhp\Type\AbstractObject $object, Actor $actor, ActivitypubActor $ap_actor): bool public function onActivityPubCreateOrUpdateActor(\ActivityPhp\Type\AbstractObject $object, Actor $actor, ActivitypubActor $ap_actor): EventResult
{ {
if ($object->has('unbound')) { if ($object->has('unbound')) {
$obj = DB::findOneBy(activitypubGroupUnbound::class, ['actor_id' => $actor->getId()], return_null: true); $obj = DB::findOneBy(activitypubGroupUnbound::class, ['actor_id' => $actor->getId()], return_null: true);

View File

@ -42,6 +42,7 @@ use App\Util\Exception\ServerException;
use App\Util\Exception\TemporaryFileException; use App\Util\Exception\TemporaryFileException;
use App\Util\Formatting; use App\Util\Formatting;
use App\Util\TemporaryFile; use App\Util\TemporaryFile;
use EventResult;
use Exception; use Exception;
use FFMpeg\FFMpeg as ffmpeg; use FFMpeg\FFMpeg as ffmpeg;
use FFMpeg\FFProbe as ffprobe; use FFMpeg\FFProbe as ffprobe;
@ -59,7 +60,7 @@ class VideoEncoder extends Plugin
return GSFile::mimetypeMajor($mimetype) === 'video' || $mimetype === 'image/gif'; return GSFile::mimetypeMajor($mimetype) === 'video' || $mimetype === 'image/gif';
} }
public function onFileMetaAvailable(array &$event_map, string $mimetype): bool public function onFileMetaAvailable(array &$event_map, string $mimetype): EventResult
{ {
if (!self::shouldHandle($mimetype)) { if (!self::shouldHandle($mimetype)) {
return Event::next; return Event::next;
@ -69,7 +70,7 @@ class VideoEncoder extends Plugin
return Event::next; return Event::next;
} }
public function onFileSanitizerAvailable(array &$event_map, string $mimetype): bool public function onFileSanitizerAvailable(array &$event_map, string $mimetype): EventResult
{ {
if ($mimetype !== 'image/gif') { if ($mimetype !== 'image/gif') {
return Event::next; return Event::next;
@ -79,7 +80,7 @@ class VideoEncoder extends Plugin
return Event::next; return Event::next;
} }
public function onFileResizerAvailable(array &$event_map, string $mimetype): bool public function onFileResizerAvailable(array &$event_map, string $mimetype): EventResult
{ {
if ($mimetype !== 'image/gif') { if ($mimetype !== 'image/gif') {
return Event::next; return Event::next;
@ -139,7 +140,7 @@ class VideoEncoder extends Plugin
/** /**
* Generates the view for attachments of type Video * Generates the view for attachments of type Video
*/ */
public function onViewAttachment(array $vars, array &$res): bool public function onViewAttachment(array $vars, array &$res): EventResult
{ {
if ($vars['attachment']->getMimetypeMajor() !== 'video') { if ($vars['attachment']->getMimetypeMajor() !== 'video') {
return Event::next; return Event::next;
@ -289,7 +290,7 @@ class VideoEncoder extends Plugin
/** /**
* @throws ServerException * @throws ServerException
*/ */
public function onPluginVersion(array &$versions): bool public function onPluginVersion(array &$versions): EventResult
{ {
$versions[] = ['name' => 'FFmpeg', $versions[] = ['name' => 'FFmpeg',
'version' => self::version(), 'version' => self::version(),

View File

@ -33,6 +33,7 @@ use App\Entity\Actor;
use App\Entity\LocalUser; use App\Entity\LocalUser;
use App\Util\Common; use App\Util\Common;
use App\Util\Exception\ServerException; use App\Util\Exception\ServerException;
use EventResult;
use Exception; use Exception;
use Functional as F; use Functional as F;
use Plugin\WebHooks\Controller as C; use Plugin\WebHooks\Controller as C;
@ -43,12 +44,13 @@ class WebHooks extends Plugin
{ {
public const controller_route = 'webhook'; public const controller_route = 'webhook';
public function onAddRoute(Router $r) public function onAddRoute(Router $r): EventResult
{ {
$r->connect(self::controller_route, '/webhook-settings', C\WebHooks::class, options: ['method' => 'post']); $r->connect(self::controller_route, '/webhook-settings', C\WebHooks::class, options: ['method' => 'post']);
return EventResult::next;
} }
public function onPopulateSettingsTabs(Request $request, string $section, array &$tabs): bool public function onPopulateSettingsTabs(Request $request, string $section, array &$tabs): EventResult
{ {
if ($section === 'api') { if ($section === 'api') {
$tabs[] = [ $tabs[] = [
@ -69,7 +71,7 @@ class WebHooks extends Plugin
} }
} }
public function onNewNotificationEnd(Actor $sender, Activity $activity, array $effective_targets, ?string $reason) public function onNewNotificationEnd(Actor $sender, Activity $activity, array $effective_targets, ?string $reason): EventResult
{ {
foreach ($effective_targets as $actor) { foreach ($effective_targets as $actor) {
$this->maybeEnqueue($actor, 'notifications', [$sender, $activity, $effective_targets, $reason]); $this->maybeEnqueue($actor, 'notifications', [$sender, $activity, $effective_targets, $reason]);
@ -77,7 +79,7 @@ class WebHooks extends Plugin
return Event::next; return Event::next;
} }
public function onNewSubscriptionEnd(LocalUser|Actor $subscriber, Activity $activity, Actor $hook_target, ?string $reason) public function onNewSubscriptionEnd(LocalUser|Actor $subscriber, Activity $activity, Actor $hook_target, ?string $reason): EventResult
{ {
$this->maybeEnqueue($hook_target, 'subscriptions', [$subscriber, $activity, $hook_target, $reason]); $this->maybeEnqueue($hook_target, 'subscriptions', [$subscriber, $activity, $hook_target, $reason]);
return Event::next; return Event::next;
@ -86,7 +88,7 @@ class WebHooks extends Plugin
/** /**
* @param array<Actor $sender, Activity $activity, array $effective_targets, ?string $reason> $args * @param array<Actor $sender, Activity $activity, array $effective_targets, ?string $reason> $args
*/ */
public function onQueueWebhook(string $type, string $hook_target, Actor $actor, array $args) public function onQueueWebhook(string $type, string $hook_target, Actor $actor, array $args): EventResult
{ {
switch ($type) { switch ($type) {
case 'notifications': case 'notifications':

View File

@ -43,6 +43,7 @@ use App\Entity\LocalUser;
use App\Util\Common; use App\Util\Common;
use App\Util\Exception\RedirectException; use App\Util\Exception\RedirectException;
use App\Util\Formatting; use App\Util\Formatting;
use EventResult;
use Plugin\ActivityPub\Entity\ActivitypubActor; use Plugin\ActivityPub\Entity\ActivitypubActor;
use Plugin\WebMonetization\Entity\Wallet; use Plugin\WebMonetization\Entity\Wallet;
use Plugin\WebMonetization\Entity\WebMonetization as Monetization; use Plugin\WebMonetization\Entity\WebMonetization as Monetization;
@ -52,7 +53,7 @@ use Symfony\Component\HttpFoundation\Request;
class WebMonetization extends Plugin class WebMonetization extends Plugin
{ {
public function onAppendRightPanelBlock(Request $request, $vars, &$res): bool public function onAppendRightPanelBlock(Request $request, $vars, &$res): EventResult
{ {
$user = Common::actor(); $user = Common::actor();
if (\is_null($user)) { if (\is_null($user)) {
@ -209,7 +210,7 @@ class WebMonetization extends Plugin
]; ];
} }
public function onAppendToHead(Request $request, &$res): bool public function onAppendToHead(Request $request, &$res): EventResult
{ {
$user = Common::user(); $user = Common::user();
if (\is_null($user)) { if (\is_null($user)) {
@ -241,7 +242,7 @@ class WebMonetization extends Plugin
return Event::next; return Event::next;
} }
public function onActivityStreamsTwoContext(array &$activity_streams_two_context): bool public function onActivityStreamsTwoContext(array &$activity_streams_two_context): EventResult
{ {
$activity_streams_two_context[] = [ $activity_streams_two_context[] = [
'webmonetizationWallet' => [ 'webmonetizationWallet' => [
@ -252,7 +253,7 @@ class WebMonetization extends Plugin
return Event::next; return Event::next;
} }
public function onActivityPubAddActivityStreamsTwoData(string $type_name, &$type): bool public function onActivityPubAddActivityStreamsTwoData(string $type_name, &$type): EventResult
{ {
if ($type_name === 'Person') { if ($type_name === 'Person') {
$actor = \Plugin\ActivityPub\Util\Explorer::getOneFromUri($type->getId()); $actor = \Plugin\ActivityPub\Util\Explorer::getOneFromUri($type->getId());
@ -265,7 +266,7 @@ class WebMonetization extends Plugin
return Event::next; return Event::next;
} }
public function onActivityPubCreateOrUpdateActor(\ActivityPhp\Type\AbstractObject $object, Actor $actor, ActivitypubActor $ap_actor): bool public function onActivityPubCreateOrUpdateActor(\ActivityPhp\Type\AbstractObject $object, Actor $actor, ActivitypubActor $ap_actor): EventResult
{ {
if ($object->has('webmonetizationWallet')) { if ($object->has('webmonetizationWallet')) {
$attr = ['actor_id' => $actor->getId(), 'address' => $object->get('webmonetizationWallet')]; $attr = ['actor_id' => $actor->getId(), 'address' => $object->get('webmonetizationWallet')];

View File

@ -36,10 +36,11 @@ namespace Plugin\XMPPNotifications;
use App\Core\Event; use App\Core\Event;
use App\Core\Modules\Plugin; use App\Core\Modules\Plugin;
use EventResult;
class XMPPNotifications extends Plugin class XMPPNotifications extends Plugin
{ {
public function onAddNotificationTransport(&$form_defs): bool public function onAddNotificationTransport(&$form_defs): EventResult
{ {
$form_defs['XMPP'] = $form_defs['placeholder']; $form_defs['XMPP'] = $form_defs['placeholder'];
$form_defs['XMPP'][] = $form_defs['placeholder']['save']('XMPP', 'save_xmpp'); $form_defs['XMPP'][] = $form_defs['placeholder']['save']('XMPP', 'save_xmpp');

View File

@ -33,20 +33,22 @@ declare(strict_types = 1);
namespace App\Core; namespace App\Core;
use App\Core\Event\GSEvent;
use App\Util\Exception\BugFoundException;
use EventResult;
use ReflectionFunction; use ReflectionFunction;
use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\GenericEvent;
abstract class Event abstract class Event
{ {
/** /**
* Constants to be returned from event handlers, for increased clarity * Constants to be returned from event handlers
* *
* bool stop - Stop other handlers from processing the event * EventResult::stop - Stop other handlers from processing the event
* bool next - Allow the other handlers to process the event * EventResult::next - Allow the other handlers to process the event
*/ */
public const stop = false; public const stop = EventResult::stop;
public const next = true; public const next = EventResult::next;
private static EventDispatcherInterface $dispatcher; private static EventDispatcherInterface $dispatcher;
@ -83,20 +85,18 @@ abstract class Event
): void { ): void {
self::$dispatcher->addListener( self::$dispatcher->addListener(
$ns . $name, $ns . $name,
function ($event, $event_name, $dispatcher) use ($handler, $name) { function ($event, $event_name, $dispatcher) use ($handler) {
// Old style of events (preferred) $result = $handler(...$event->getArguments());
if ($event instanceof GenericEvent) { if (\is_null($result) || !isset($result)) {
if ($handler(...$event->getArguments()) === self::stop) { dd($handler, $event_name);
$event->stopPropagation(); throw new BugFoundException("Events must return an \\EventResult, which a handler for {$event_name} does not");
}
return $event;
} }
// @codeCoverageIgnoreStart
// Symfony style of events
Log::warning("Event::addHandler for {$name} doesn't Conform to GNU social guidelines. Use of this style of event is discouraged.");
$handler($event, $event_name, $dispatcher);
// @codeCoverageIgnoreEnd $event->setResult($result);
if ($result === EventResult::stop) {
$event->stopPropagation();
}
return $event;
}, },
$priority, $priority,
); );
@ -119,9 +119,9 @@ abstract class Event
* @return bool flag saying whether to continue processing, based * @return bool flag saying whether to continue processing, based
* on results of handlers * on results of handlers
*/ */
public static function handle(string $name, array $args = [], string $ns = 'GNUsocial.'): bool public static function handle(string $name, array $args = [], string $ns = 'GNUsocial.'): EventResult
{ {
return !(self::$dispatcher->dispatch(new GenericEvent($name, $args), $ns . $name)->isPropagationStopped()); return self::$dispatcher->dispatch(new GSEvent($name, $args), $ns . $name)->getResult();
} }
/** /**

View File

@ -0,0 +1,13 @@
<?php
declare(strict_types = 1);
/**
* An event must return a value from this enum, which is in the global namespace as \EventResult
*/
enum EventResult
{
case stop;
case next;
case unhandled;
}

View File

@ -0,0 +1,23 @@
<?php
declare(strict_types = 1);
namespace App\Core\Event;
use EventResult;
use Symfony\Component\EventDispatcher\GenericEvent;
class GSEvent extends GenericEvent
{
protected mixed $result;
public function setResult(mixed $result): void
{
$this->result = $result;
}
public function getResult(): mixed
{
return $this->result ?? EventResult::next;
}
}

View File

@ -36,6 +36,7 @@ declare(strict_types = 1);
namespace App\Core; namespace App\Core;
use App\Kernel; use App\Kernel;
use App\Util\Exception\BugFoundException;
use App\Util\Formatting; use App\Util\Formatting;
use AppendIterator; use AppendIterator;
use Exception; use Exception;
@ -43,6 +44,7 @@ use FilesystemIterator;
use Functional as F; use Functional as F;
use RecursiveDirectoryIterator; use RecursiveDirectoryIterator;
use RecursiveIteratorIterator; use RecursiveIteratorIterator;
use ReflectionMethod;
use Symfony\Component\Config\Loader\LoaderInterface; use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\Config\Resource\GlobResource; use Symfony\Component\Config\Resource\GlobResource;
use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\ContainerBuilder;
@ -85,10 +87,15 @@ class ModuleManager
get_class_methods($obj), get_class_methods($obj),
F\ary(F\partial_right('App\Util\Formatting::startsWith', 'on'), 1), F\ary(F\partial_right('App\Util\Formatting::startsWith', 'on'), 1),
), ),
function (string $m) use ($obj) { function (string $method) use ($obj) {
$ev = mb_substr($m, 2); if (((string) (new ReflectionMethod($obj, $method))->getReturnType()) !== 'EventResult') {
$this->events[$ev] ??= []; $class = $obj::class;
$this->events[$ev][] = [$obj, $m]; dd("Return type of {$class}::{$method} is not the required EventResult");
throw new BugFoundException("Return type of {$class}::{$method} is not the required EventResult");
}
$event_name = mb_substr($method, 2);
$this->events[$event_name] ??= [];
$this->events[$event_name][] = [$obj, $method];
}, },
); );
} }

View File

@ -22,6 +22,7 @@ declare(strict_types = 1);
namespace App\Core\Modules; namespace App\Core\Modules;
use App\Util\Common; use App\Util\Common;
use EventResult;
/** /**
* Base class for all GNU social modules (plugins and components) * Base class for all GNU social modules (plugins and components)
@ -64,22 +65,23 @@ abstract class Module
// ------- Module initialize and cleanup ---------- // ------- Module initialize and cleanup ----------
private function defer(string $cycle) private function defer(string $cycle): EventResult
{ {
$type = ucfirst(static::MODULE_TYPE); $type = ucfirst(static::MODULE_TYPE);
if (method_exists($this, $method = "on{$cycle}{$type}")) { if (method_exists($this, $method = "on{$cycle}{$type}")) {
$this->{$method}(); $this->{$method}();
} }
return EventResult::next;
} }
// Can't use __call or it won't be found by our event function finder // Can't use __call or it won't be found by our event function finder
public function onInitializeModule() public function onInitializeModule(): EventResult
{ {
$this->defer('Initialize'); return $this->defer('Initialize');
} }
public function onCleanupModule() public function onCleanupModule(): EventResult
{ {
$this->defer('Cleanup'); return $this->defer('Cleanup');
} }
} }

View File

@ -6,6 +6,7 @@ namespace App\Core\Modules;
use App\Core\Event; use App\Core\Event;
use function App\Core\I18n\_m; use function App\Core\I18n\_m;
use EventResult;
/** /**
* TODO Plugins aren't tested yet * TODO Plugins aren't tested yet
@ -21,7 +22,7 @@ abstract class Plugin extends Module
return GNUSOCIAL_BASE_VERSION; return GNUSOCIAL_BASE_VERSION;
} }
public function onPluginVersion(array &$versions): bool public function onPluginVersion(array &$versions): EventResult
{ {
$name = $this->name(); $name = $this->name();

View File

@ -33,7 +33,6 @@ declare(strict_types = 1);
namespace App\Core; namespace App\Core;
use App\Entity\LocalUser; use App\Entity\LocalUser;
use App\Util\Common;
use App\Util\Formatting; use App\Util\Formatting;
use BadMethodCallException; use BadMethodCallException;
use Functional as F; use Functional as F;
@ -97,12 +96,12 @@ class Security implements EventSubscriberInterface //implements AuthenticatorInt
// can be used to essentially override any class when such a // can be used to essentially override any class when such a
// file is opened and thus provide code execution to an // file is opened and thus provide code execution to an
// attacker. Not a complete solution, since `file://`, // attacker. Not a complete solution, since `file://`,
// `php://` and `glob://` get used _somewhere_, so we can't // `php://` and `glob://`, 'compress.zlib' (symfony profiler) get used _somewhere_, so we can't
// disable them // disable them
F\each( F\each(
['http', 'https', 'ftp', 'ftps', 'compress.zlib', 'data', 'phar'], // Making this configurable might be a nice feature, but it's tricky because this happens before general initialization ['http', 'https', 'ftp', 'ftps', 'data', 'phar'], // Making this configurable might be a nice feature, but it's tricky because this happens before general initialization
fn (string $protocol) => \stream_wrapper_unregister($protocol) fn (string $protocol) => stream_wrapper_unregister($protocol),
);; );
} }
public static function __callStatic(string $name, array $args) public static function __callStatic(string $name, array $args)