[CORE][ActivityStreamsTwo][ActivityPub] Set all routes
Allow global routes to act for every actor Fix Favoured stream query
This commit is contained in:
parent
738168461c
commit
d6f31d102a
|
@ -38,7 +38,7 @@ class Avatar extends Component
|
||||||
|
|
||||||
public function onAddRoute($r): bool
|
public function onAddRoute($r): bool
|
||||||
{
|
{
|
||||||
$r->connect('avatar', '/{gsactor_id<\d+>}/avatar/{size<full|big|medium|small>?full}', [Controller\Avatar::class, 'avatar_view']);
|
$r->connect('avatar', '/actor/{gsactor_id<\d+>}/avatar/{size<full|big|medium|small>?full}', [Controller\Avatar::class, 'avatar_view']);
|
||||||
$r->connect('settings_avatar', '/settings/avatar', [Controller\Avatar::class, 'settings_avatar']);
|
$r->connect('settings_avatar', '/settings/avatar', [Controller\Avatar::class, 'settings_avatar']);
|
||||||
return Event::next;
|
return Event::next;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@ class Left extends Component
|
||||||
$user = Common::user();
|
$user = Common::user();
|
||||||
if ($user != null) {
|
if ($user != null) {
|
||||||
$actor = $user->getActor();
|
$actor = $user->getActor();
|
||||||
|
$vars['user_id'] = $user->getId();
|
||||||
$vars['user_nickname'] = $user->getNickname();
|
$vars['user_nickname'] = $user->getNickname();
|
||||||
$vars['user_tags'] = $actor->getSelfTags();
|
$vars['user_tags'] = $actor->getSelfTags();
|
||||||
$vars['user_followers'] = $actor->getFollowersCount();
|
$vars['user_followers'] = $actor->getFollowersCount();
|
||||||
|
|
|
@ -26,9 +26,21 @@ class ActivityPub extends Plugin
|
||||||
*/
|
*/
|
||||||
public function onAddRoute(RouteLoader $r): bool
|
public function onAddRoute(RouteLoader $r): bool
|
||||||
{
|
{
|
||||||
|
$r->connect(
|
||||||
|
'activitypub_actor_inbox',
|
||||||
|
'/actor/{gsactor_id<\d+>}/inbox.json',
|
||||||
|
[Inbox::class, 'handle'],
|
||||||
|
options: ['accept' => ActivityStreamsTwo::$accept_headers]
|
||||||
|
);
|
||||||
|
$r->connect(
|
||||||
|
'activitypub_actor_outbox',
|
||||||
|
'/actor/{gsactor_id<\d+>}/outbox.json',
|
||||||
|
[Inbox::class, 'handle'],
|
||||||
|
options: ['accept' => ActivityStreamsTwo::$accept_headers]
|
||||||
|
);
|
||||||
$r->connect(
|
$r->connect(
|
||||||
'activitypub_inbox',
|
'activitypub_inbox',
|
||||||
'{gsactor_id<\d+>}/inbox',
|
'/inbox.json',
|
||||||
[Inbox::class, 'handle'],
|
[Inbox::class, 'handle'],
|
||||||
options: ['accept' => ActivityStreamsTwo::$accept_headers]
|
options: ['accept' => ActivityStreamsTwo::$accept_headers]
|
||||||
);
|
);
|
||||||
|
@ -48,12 +60,12 @@ class ActivityPub extends Plugin
|
||||||
public static function validateAcceptHeader(array|string|null $accept, bool $strict): bool
|
public static function validateAcceptHeader(array|string|null $accept, bool $strict): bool
|
||||||
{
|
{
|
||||||
if (is_string($accept)
|
if (is_string($accept)
|
||||||
&& in_array($accept, self::$accept_headers)
|
&& in_array($accept, ActivityStreamsTwo::$accept_headers)
|
||||||
) {
|
) {
|
||||||
return true;
|
return true;
|
||||||
} elseif (is_array($accept)
|
} elseif (is_array($accept)
|
||||||
&& count(
|
&& count(
|
||||||
array_intersect($accept, self::$accept_headers)
|
array_intersect($accept, ActivityStreamsTwo::$accept_headers)
|
||||||
) > 0
|
) > 0
|
||||||
) {
|
) {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -4,7 +4,6 @@ namespace Plugin\ActivityStreamsTwo;
|
||||||
|
|
||||||
use App\Core\Event;
|
use App\Core\Event;
|
||||||
use App\Core\Modules\Plugin;
|
use App\Core\Modules\Plugin;
|
||||||
use App\Core\Router\RouteLoader;
|
|
||||||
use Exception;
|
use Exception;
|
||||||
use Plugin\ActivityStreamsTwo\Util\Response\ActorResponse;
|
use Plugin\ActivityStreamsTwo\Util\Response\ActorResponse;
|
||||||
use Plugin\ActivityStreamsTwo\Util\Response\NoteResponse;
|
use Plugin\ActivityStreamsTwo\Util\Response\NoteResponse;
|
||||||
|
@ -41,33 +40,24 @@ class ActivityStreamsTwo extends Plugin
|
||||||
return Event::next;
|
return Event::next;
|
||||||
}
|
}
|
||||||
switch ($route) {
|
switch ($route) {
|
||||||
|
case 'actor_view_id':
|
||||||
|
case 'actor_view_nickname':
|
||||||
|
$response = ActorResponse::handle($vars['gsactor']);
|
||||||
|
return Event::stop;
|
||||||
case 'note_view':
|
case 'note_view':
|
||||||
$response = NoteResponse::handle($vars['note']);
|
$response = NoteResponse::handle($vars['note']);
|
||||||
return Event::stop;
|
return Event::stop;
|
||||||
case 'gsactor_view_id':
|
case 'actor_favourites':
|
||||||
case 'gsactor_view_nickname':
|
$response = LikeResponse::handle($vars['gsactor']);
|
||||||
$response = ActorResponse::handle($vars['gsactor']);
|
return Event::stop;
|
||||||
|
case 'actor_subscriptions':
|
||||||
|
$response = FollowingResponse::handle($vars['gsactor']);
|
||||||
|
return Event::stop;
|
||||||
|
case 'actor_subscribers':
|
||||||
|
$response = FollowersResponse::handle($vars['gsactor']);
|
||||||
return Event::stop;
|
return Event::stop;
|
||||||
default:
|
default:
|
||||||
return Event::next;
|
return Event::next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* This code executes when GNU social creates the page routing, and we hook
|
|
||||||
* on this event to add our action handler for Embed.
|
|
||||||
*
|
|
||||||
* @param RouteLoader $r the router that was initialized.
|
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function onAddRoute(RouteLoader $r): bool
|
|
||||||
{
|
|
||||||
/*$r->connect('note_view_as2',
|
|
||||||
'/note/{id<\d+>}',
|
|
||||||
[NoteResponse::class, 'handle'],
|
|
||||||
options: ['accept' => self::$accept_headers]
|
|
||||||
);*/
|
|
||||||
return Event::next;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ class GSActorToType
|
||||||
*/
|
*/
|
||||||
public static function translate(GSActor $gsactor)
|
public static function translate(GSActor $gsactor)
|
||||||
{
|
{
|
||||||
$uri = Router::url('gsactor_view_id', ['id' => $gsactor->getId()], Router::ABSOLUTE_URL);
|
$uri = Router::url('actor_view_id', ['id' => $gsactor->getId()], Router::ABSOLUTE_URL);
|
||||||
$attr = [
|
$attr = [
|
||||||
'@context' => 'https://www.w3.org/ns/activitystreams',
|
'@context' => 'https://www.w3.org/ns/activitystreams',
|
||||||
'id' => $uri,
|
'id' => $uri,
|
||||||
|
@ -42,7 +42,7 @@ class GSActorToType
|
||||||
'summary' => $gsactor->getBio(),
|
'summary' => $gsactor->getBio(),
|
||||||
//'tag' =>
|
//'tag' =>
|
||||||
'updated' => $gsactor->getModified()->format(DateTimeInterface::RFC3339),
|
'updated' => $gsactor->getModified()->format(DateTimeInterface::RFC3339),
|
||||||
'url' => Router::url('gsactor_view_nickname', ['nickname' => $gsactor->getNickname()], Router::ABSOLUTE_URL),
|
'url' => Router::url('actor_view_nickname', ['nickname' => $gsactor->getNickname()], Router::ABSOLUTE_URL),
|
||||||
];
|
];
|
||||||
return Type::create(type: 'Person', attributes: $attr);
|
return Type::create(type: 'Person', attributes: $attr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,17 +23,19 @@ namespace Plugin\Favourite\Controller;
|
||||||
|
|
||||||
use App\Core\DB\DB;
|
use App\Core\DB\DB;
|
||||||
use App\Core\Event;
|
use App\Core\Event;
|
||||||
use App\Util\Common;
|
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
|
||||||
class Favourite
|
class Favourite
|
||||||
{
|
{
|
||||||
public function favourites(Request $request)
|
public function favouritesByActorId(Request $request, int $id)
|
||||||
{
|
{
|
||||||
$actor_id = Common::ensureLoggedIn()->getId();
|
$notes = DB::dql(
|
||||||
$notes = DB::dql('select f from Plugin\Favourite\Entity\Favourite f ' .
|
'select n from App\Entity\Note n, Plugin\Favourite\Entity\Favourite f ' .
|
||||||
'where f.gsactor_id = :id ' .
|
'where n.id = f.note_id ' .
|
||||||
'order by f.created DESC', ['id' => $actor_id]);
|
'and f.gsactor_id = :id ' .
|
||||||
|
'order by f.created DESC',
|
||||||
|
['id' => $id]
|
||||||
|
);
|
||||||
|
|
||||||
$notes_out = null;
|
$notes_out = null;
|
||||||
Event::handle('FormatNoteList', [$notes, &$notes_out]);
|
Event::handle('FormatNoteList', [$notes, &$notes_out]);
|
||||||
|
@ -43,6 +45,11 @@ class Favourite
|
||||||
'notes' => $notes_out,
|
'notes' => $notes_out,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
public function favouritesByActorNickname(Request $request, string $nickname)
|
||||||
|
{
|
||||||
|
$user = DB::findOneBy('local_user', ['nickname' => $nickname]);
|
||||||
|
return self::favouritesByActorId($request, $user->getId());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reverse favourites stream
|
* Reverse favourites stream
|
||||||
|
@ -53,15 +60,15 @@ class Favourite
|
||||||
*
|
*
|
||||||
* @return array template
|
* @return array template
|
||||||
*/
|
*/
|
||||||
public function reverseFavourites(Request $request)
|
public function reverseFavouritesByActorId(Request $request, int $id)
|
||||||
{
|
{
|
||||||
$actor_id = Common::ensureLoggedIn()->getId();
|
|
||||||
$notes = DB::dql('select n from App\Entity\Note n, Plugin\Favourite\Entity\Favourite f ' .
|
$notes = DB::dql('select n from App\Entity\Note n, Plugin\Favourite\Entity\Favourite f ' .
|
||||||
'where n.id = f.note_id ' .
|
'where n.id = f.note_id ' .
|
||||||
'and f.gsactor_id != :id ' .
|
'and f.gsactor_id != :id ' .
|
||||||
'and n.gsactor_id = :id ' .
|
'and n.gsactor_id = :id ' .
|
||||||
'order by f.created DESC' ,
|
'order by f.created DESC' ,
|
||||||
['id' => $actor_id]);
|
['id' => $id]
|
||||||
|
);
|
||||||
|
|
||||||
$notes_out = null;
|
$notes_out = null;
|
||||||
Event::handle('FormatNoteList', [$notes, &$notes_out]);
|
Event::handle('FormatNoteList', [$notes, &$notes_out]);
|
||||||
|
@ -71,4 +78,9 @@ class Favourite
|
||||||
'notes' => $notes,
|
'notes' => $notes,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
public function reverseFavouritesByActorNickname(Request $request, string $nickname)
|
||||||
|
{
|
||||||
|
$user = DB::findOneBy('local_user', ['nickname' => $nickname]);
|
||||||
|
return self::reverseFavouritesByActorId($request, $user->getId());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ namespace Plugin\Favourite;
|
||||||
use App\Core\DB\DB;
|
use App\Core\DB\DB;
|
||||||
use App\Core\Event;
|
use App\Core\Event;
|
||||||
use App\Core\Form;
|
use App\Core\Form;
|
||||||
|
use function App\Core\I18n\_m;
|
||||||
use App\Core\Modules\NoteHandlerPlugin;
|
use App\Core\Modules\NoteHandlerPlugin;
|
||||||
use App\Core\Router\RouteLoader;
|
use App\Core\Router\RouteLoader;
|
||||||
use App\Entity\Note;
|
use App\Entity\Note;
|
||||||
|
@ -36,7 +37,6 @@ use App\Util\Nickname;
|
||||||
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;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use function App\Core\I18n\_m;
|
|
||||||
|
|
||||||
class Favourite extends NoteHandlerPlugin
|
class Favourite extends NoteHandlerPlugin
|
||||||
{
|
{
|
||||||
|
@ -60,7 +60,7 @@ class Favourite extends NoteHandlerPlugin
|
||||||
return Event::next;
|
return Event::next;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if note is favourited, "is_set" is 1
|
// if note is favoured, "is_set" is 1
|
||||||
$opts = ['note_id' => $note->getId(), 'gsactor_id' => $user->getId()];
|
$opts = ['note_id' => $note->getId(), 'gsactor_id' => $user->getId()];
|
||||||
$is_set = DB::find('favourite', $opts) !== null;
|
$is_set = DB::find('favourite', $opts) !== null;
|
||||||
$form_fav = Form::create([
|
$form_fav = Form::create([
|
||||||
|
@ -83,7 +83,7 @@ class Favourite extends NoteHandlerPlugin
|
||||||
/**
|
/**
|
||||||
* Called from form handler
|
* Called from form handler
|
||||||
*
|
*
|
||||||
* @param Note $note to be favourited
|
* @param Note $note to be favoured
|
||||||
* @param Form $data input
|
* @param Form $data input
|
||||||
*
|
*
|
||||||
* @throws RedirectException Always thrown in order to prevent accidental form re-submit from browser
|
* @throws RedirectException Always thrown in order to prevent accidental form re-submit from browser
|
||||||
|
@ -117,16 +117,18 @@ class Favourite extends NoteHandlerPlugin
|
||||||
public function onInsertLeftPanelLink(string $user_nickname, &$res): bool
|
public function onInsertLeftPanelLink(string $user_nickname, &$res): bool
|
||||||
{
|
{
|
||||||
$res[] = Formatting::twigRenderString(<<<END
|
$res[] = Formatting::twigRenderString(<<<END
|
||||||
<a href="{{ path("favourites", {'nickname' : user_nickname}) }}" class='hover-effect {{ active("favourites") }}'>Favourites</a>
|
<a href="{{ path("actor_favourites_nickname", {'nickname' : user_nickname}) }}" class='hover-effect {{ active("favourites") }}'>Favourites</a>
|
||||||
<a href="{{ path("reverse_favourites", {'nickname' : user_nickname}) }}" class='hover-effect {{ active("reverse_favourites") }}'>Reverse Favs</a>
|
<a href="{{ path("actor_reverse_favourites_nickname", {'nickname' : user_nickname}) }}" class='hover-effect {{ active("reverse_favourites") }}'>Reverse Favs</a>
|
||||||
END, ['user_nickname' => $user_nickname]);
|
END, ['user_nickname' => $user_nickname]);
|
||||||
return Event::next;
|
return Event::next;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onAddRoute(RouteLoader $r): bool
|
public function onAddRoute(RouteLoader $r): bool
|
||||||
{
|
{
|
||||||
$r->connect('favourites', '/favourites/{nickname<' . Nickname::DISPLAY_FMT . '>}', [Controller\Favourite::class, 'favourites']);
|
$r->connect(id: 'actor_favourites_id', uri_path: '/actor/{id<\d+>}/favourites', target: [Controller\Favourite::class, 'favouritesByActorId']);
|
||||||
$r->connect('reverse_favourites', '/reverse_favourites/{nickname<' . Nickname::DISPLAY_FMT . '>}', [Controller\Favourite::class, 'reverseFavourites']);
|
$r->connect(id: 'actor_reverse_favourites_id', uri_path: '/actor/{id<\d+>}/reverse_favourites', target: [Controller\Favourite::class, 'reverseFavouritesByActorId']);
|
||||||
|
$r->connect('actor_favourites_nickname', '/@{nickname<' . Nickname::DISPLAY_FMT . '>}/favourites', [Controller\Favourite::class, 'favouritesByActorNickname']);
|
||||||
|
$r->connect('actor_reverse_favourites_nickname', '/@{nickname<' . Nickname::DISPLAY_FMT . '>}/reverse_favourites', [Controller\Favourite::class, 'reverseFavouritesByActorNickname']);
|
||||||
return Event::next;
|
return Event::next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,7 @@ class GSActor extends Controller
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The page where the note and it's info is shown
|
* The page where the actor's info is shown
|
||||||
*/
|
*/
|
||||||
public function GSActorShowId(Request $request, int $id)
|
public function GSActorShowId(Request $request, int $id)
|
||||||
{
|
{
|
||||||
|
|
69
src/Controller/Subscribers.php
Normal file
69
src/Controller/Subscribers.php
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
// {{{ License
|
||||||
|
|
||||||
|
// This file is part of GNU social - https://www.gnu.org/software/social
|
||||||
|
//
|
||||||
|
// GNU social is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// GNU social is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
|
||||||
|
namespace App\Controller;
|
||||||
|
|
||||||
|
use App\Core\Controller;
|
||||||
|
use App\Core\DB\DB;
|
||||||
|
use function App\Core\I18n\_m;
|
||||||
|
use App\Util\Exception\ClientException;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
|
||||||
|
class Subscribers extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Generic function that handles getting a representation for an actor from id
|
||||||
|
*/
|
||||||
|
private function GSActorById(int $id, callable $handle)
|
||||||
|
{
|
||||||
|
$gsactor = DB::findOneBy('gsactor', ['id' => $id]);
|
||||||
|
if (empty($gsactor)) {
|
||||||
|
throw new ClientException(_m('No such actor.'), 404);
|
||||||
|
} else {
|
||||||
|
return $handle($gsactor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Generic function that handles getting a representation for an actor from nickname
|
||||||
|
*/
|
||||||
|
private function GSActorByNickname(string $nickname, callable $handle)
|
||||||
|
{
|
||||||
|
$user = DB::findOneBy('local_user', ['nickname' => $nickname]);
|
||||||
|
$gsactor = DB::findOneBy('gsactor', ['id' => $user->getId()]);
|
||||||
|
if (empty($gsactor)) {
|
||||||
|
throw new ClientException(_m('No such actor.'), 404);
|
||||||
|
} else {
|
||||||
|
return $handle($gsactor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Collection of an actor's subscribers
|
||||||
|
*/
|
||||||
|
public function GSActorShowId(Request $request, int $id)
|
||||||
|
{
|
||||||
|
return $this->GSActorById($id, fn ($gsactor) => ['_template' => 'subscribers/view.html.twig', 'gsactor' => $gsactor]);
|
||||||
|
}
|
||||||
|
public function GSActorShowNickname(Request $request, string $nickname)
|
||||||
|
{
|
||||||
|
return $this->GSActorByNickname($nickname, fn ($gsactor) => ['_template' => 'subscribers/view.html.twig', 'gsactor' => $gsactor]);
|
||||||
|
}
|
||||||
|
}
|
69
src/Controller/Subscriptions.php
Normal file
69
src/Controller/Subscriptions.php
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
// {{{ License
|
||||||
|
|
||||||
|
// This file is part of GNU social - https://www.gnu.org/software/social
|
||||||
|
//
|
||||||
|
// GNU social is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// GNU social is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
|
||||||
|
namespace App\Controller;
|
||||||
|
|
||||||
|
use App\Core\Controller;
|
||||||
|
use App\Core\DB\DB;
|
||||||
|
use function App\Core\I18n\_m;
|
||||||
|
use App\Util\Exception\ClientException;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
|
||||||
|
class Subscriptions extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Generic function that handles getting a representation for an actor from id
|
||||||
|
*/
|
||||||
|
private function GSActorById(int $id, callable $handle)
|
||||||
|
{
|
||||||
|
$gsactor = DB::findOneBy('gsactor', ['id' => $id]);
|
||||||
|
if (empty($gsactor)) {
|
||||||
|
throw new ClientException(_m('No such actor.'), 404);
|
||||||
|
} else {
|
||||||
|
return $handle($gsactor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Generic function that handles getting a representation for an actor from nickname
|
||||||
|
*/
|
||||||
|
private function GSActorByNickname(string $nickname, callable $handle)
|
||||||
|
{
|
||||||
|
$user = DB::findOneBy('local_user', ['nickname' => $nickname]);
|
||||||
|
$gsactor = DB::findOneBy('gsactor', ['id' => $user->getId()]);
|
||||||
|
if (empty($gsactor)) {
|
||||||
|
throw new ClientException(_m('No such actor.'), 404);
|
||||||
|
} else {
|
||||||
|
return $handle($gsactor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Collection of an actor's subscriptions
|
||||||
|
*/
|
||||||
|
public function GSActorShowId(Request $request, int $id)
|
||||||
|
{
|
||||||
|
return $this->GSActorById($id, fn ($gsactor) => ['_template' => 'subscriptions/view.html.twig', 'gsactor' => $gsactor]);
|
||||||
|
}
|
||||||
|
public function GSActorShowNickname(Request $request, string $nickname)
|
||||||
|
{
|
||||||
|
return $this->GSActorByNickname($nickname, fn ($gsactor) => ['_template' => 'subscriptions/view.html.twig', 'gsactor' => $gsactor]);
|
||||||
|
}
|
||||||
|
}
|
|
@ -68,7 +68,6 @@ class RouteLoader extends Loader
|
||||||
}
|
}
|
||||||
|
|
||||||
ksort($to_load);
|
ksort($to_load);
|
||||||
|
|
||||||
foreach ($to_load as $ns) {
|
foreach ($to_load as $ns) {
|
||||||
$ns::load($this);
|
$ns::load($this);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,14 +20,14 @@
|
||||||
// }}}
|
// }}}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Define social's attachment routes
|
* Define social's Actor routes
|
||||||
*
|
*
|
||||||
* @package GNUsocial
|
* @package GNUsocial
|
||||||
* @category Router
|
* @category Router
|
||||||
*
|
*
|
||||||
* @author Diogo Cordeiro <mail@diogo.site>
|
* @author Diogo Cordeiro <mail@diogo.site>
|
||||||
* @author Hugo Sales <hugo@hsal.es>
|
* @author Hugo Sales <hugo@hsal.es>
|
||||||
* @copyright 2020-2021 Free Software Foundation, Inc http://www.fsf.org
|
* @copyright 2021 Free Software Foundation, Inc http://www.fsf.org
|
||||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -40,9 +40,10 @@ use App\Util\Nickname;
|
||||||
abstract class GSActor
|
abstract class GSActor
|
||||||
{
|
{
|
||||||
const LOAD_ORDER = 30;
|
const LOAD_ORDER = 30;
|
||||||
|
|
||||||
public static function load(RouteLoader $r): void
|
public static function load(RouteLoader $r): void
|
||||||
{
|
{
|
||||||
$r->connect(id: 'gsactor_view_id', uri_path: '/actor/{id<\d+>}', target: [C\GSActor::class, 'GSActorShowId']);
|
$r->connect(id: 'actor_view_id', uri_path: '/actor/{id<\d+>}', target: [C\GSActor::class, 'GSActorShowId']);
|
||||||
$r->connect(id: 'gsactor_view_nickname', uri_path: '/{nickname<' . Nickname::DISPLAY_FMT . '>}', target: [C\GSActor::class, 'GSActorShowNickname'], options: ['is_system_path' => false]);
|
$r->connect(id: 'actor_view_nickname', uri_path: '/@{nickname<' . Nickname::DISPLAY_FMT . '>}', target: [C\GSActor::class, 'GSActorShowNickname'], options: ['is_system_path' => false]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,8 @@
|
||||||
* @category Router
|
* @category Router
|
||||||
*
|
*
|
||||||
* @author Hugo Sales <hugo@hsal.es>
|
* @author Hugo Sales <hugo@hsal.es>
|
||||||
* @author Eliseu Amaro <eliseu@fc.up.pt>
|
* @author Eliseu Amaro <mail@eliseuama.ro>
|
||||||
|
* @author Diogo Cordeiro <mail@diogo.site>
|
||||||
* @copyright 2020-2021 Free Software Foundation, Inc http://www.fsf.org
|
* @copyright 2020-2021 Free Software Foundation, Inc http://www.fsf.org
|
||||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||||
*/
|
*/
|
||||||
|
@ -54,8 +55,8 @@ abstract class Main
|
||||||
$r->connect('root', '/', RedirectController::class, ['defaults' => ['route' => 'main_all']]);
|
$r->connect('root', '/', RedirectController::class, ['defaults' => ['route' => 'main_all']]);
|
||||||
$r->connect('main_public', '/main/public', [C\Network::class, 'public']);
|
$r->connect('main_public', '/main/public', [C\Network::class, 'public']);
|
||||||
$r->connect('main_all', '/main/all', [C\Network::class, 'network']);
|
$r->connect('main_all', '/main/all', [C\Network::class, 'network']);
|
||||||
$r->connect('home_all', '/{nickname<' . Nickname::DISPLAY_FMT . '>}/all', [C\Network::class, 'home']);
|
$r->connect('home_all', '/@{nickname<' . Nickname::DISPLAY_FMT . '>}/all', [C\Network::class, 'home']);
|
||||||
$r->connect('replies', '/{nickname<' . Nickname::DISPLAY_FMT . '>}/replies', [C\Network::class, 'replies']);
|
$r->connect('replies', '/@{nickname<' . Nickname::DISPLAY_FMT . '>}/replies', [C\Network::class, 'replies']);
|
||||||
|
|
||||||
$r->connect('panel', '/panel', [C\AdminPanel::class, 'site']);
|
$r->connect('panel', '/panel', [C\AdminPanel::class, 'site']);
|
||||||
$r->connect('panel_site', '/panel/site', [C\AdminPanel::class, 'site']);
|
$r->connect('panel_site', '/panel/site', [C\AdminPanel::class, 'site']);
|
||||||
|
|
|
@ -20,14 +20,14 @@
|
||||||
// }}}
|
// }}}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Define social's attachment routes
|
* Define social's Note routes
|
||||||
*
|
*
|
||||||
* @package GNUsocial
|
* @package GNUsocial
|
||||||
* @category Router
|
* @category Router
|
||||||
*
|
*
|
||||||
* @author Diogo Cordeiro <mail@diogo.site>
|
* @author Diogo Cordeiro <mail@diogo.site>
|
||||||
* @author Hugo Sales <hugo@hsal.es>
|
* @author Hugo Sales <hugo@hsal.es>
|
||||||
* @copyright 2020-2021 Free Software Foundation, Inc http://www.fsf.org
|
* @copyright 2021 Free Software Foundation, Inc http://www.fsf.org
|
||||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -41,6 +41,6 @@ abstract class Note
|
||||||
const LOAD_ORDER = 40;
|
const LOAD_ORDER = 40;
|
||||||
public static function load(RouteLoader $r): void
|
public static function load(RouteLoader $r): void
|
||||||
{
|
{
|
||||||
$r->connect('note_view', '/note/{id<\d+>}', [C\Note::class, 'NoteShow']);
|
$r->connect('note_view', '/object/note/{id<\d+>}', [C\Note::class, 'NoteShow']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
47
src/Routes/Subscribers.php
Normal file
47
src/Routes/Subscribers.php
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
// {{{ License
|
||||||
|
|
||||||
|
// This file is part of GNU social - https://www.gnu.org/software/social
|
||||||
|
//
|
||||||
|
// GNU social is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// GNU social is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define social's GSActor's subscribers routes
|
||||||
|
*
|
||||||
|
* @package GNUsocial
|
||||||
|
* @category Router
|
||||||
|
*
|
||||||
|
* @author Diogo Cordeiro <mail@diogo.site>
|
||||||
|
* @copyright 2021 Free Software Foundation, Inc http://www.fsf.org
|
||||||
|
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Routes;
|
||||||
|
|
||||||
|
use App\Controller as C;
|
||||||
|
use App\Core\Router\RouteLoader;
|
||||||
|
use App\Util\Nickname;
|
||||||
|
|
||||||
|
abstract class Subscribers
|
||||||
|
{
|
||||||
|
const LOAD_ORDER = 31;
|
||||||
|
public static function load(RouteLoader $r): void
|
||||||
|
{
|
||||||
|
$r->connect(id: 'actor_subscribers_id', uri_path: '/actor/{id<\d+>}/subscribers', target: [C\Subscribers::class, 'SubscribersByActorId']);
|
||||||
|
$r->connect(id: 'actor_subscribers_nickname', uri_path: '/@{nickname<' . Nickname::DISPLAY_FMT . '>}/subscribers', target: [C\Subscribers::class, 'SubscribersByActorNickname']);
|
||||||
|
}
|
||||||
|
}
|
47
src/Routes/Subscriptions.php
Normal file
47
src/Routes/Subscriptions.php
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
// {{{ License
|
||||||
|
|
||||||
|
// This file is part of GNU social - https://www.gnu.org/software/social
|
||||||
|
//
|
||||||
|
// GNU social is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// GNU social is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define social's GSActor's subscriptions routes
|
||||||
|
*
|
||||||
|
* @package GNUsocial
|
||||||
|
* @category Router
|
||||||
|
*
|
||||||
|
* @author Diogo Cordeiro <mail@diogo.site>
|
||||||
|
* @copyright 2021 Free Software Foundation, Inc http://www.fsf.org
|
||||||
|
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Routes;
|
||||||
|
|
||||||
|
use App\Controller as C;
|
||||||
|
use App\Core\Router\RouteLoader;
|
||||||
|
use App\Util\Nickname;
|
||||||
|
|
||||||
|
abstract class Subscriptions
|
||||||
|
{
|
||||||
|
const LOAD_ORDER = 32;
|
||||||
|
public static function load(RouteLoader $r): void
|
||||||
|
{
|
||||||
|
$r->connect(id: 'actor_subscriptions_id', uri_path: '/actor/{id<\d+>}/subscriptions', target: [C\Subscriptions::class, 'SubscriptionsByActorId']);
|
||||||
|
$r->connect(id: 'actor_subscriptions_nickname', uri_path: '/@{nickname<' . Nickname::DISPLAY_FMT . '>}/subscriptions', target: [C\Subscriptions::class, 'SubscriptionsByActorNickname']);
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,7 +6,7 @@
|
||||||
<aside class="panel-content accessibility-target">
|
<aside class="panel-content accessibility-target">
|
||||||
{% if app.user %}
|
{% if app.user %}
|
||||||
<section class='section-widget section-widget-padded' title="{{ 'Your profile information.' | trans }}">
|
<section class='section-widget section-widget-padded' title="{{ 'Your profile information.' | trans }}">
|
||||||
<a id="user" href="{{ path('settings') }}">
|
<a id="user" href="{{ path('actor_view_nickname', {'nickname' : user_nickname}) }}">
|
||||||
<img src='{{ user_avatar }}' class="icon icon-avatar" alt="{{ 'Your account\'s avatar.' | trans }}">
|
<img src='{{ user_avatar }}' class="icon icon-avatar" alt="{{ 'Your account\'s avatar.' | trans }}">
|
||||||
<div class="user-info">
|
<div class="user-info">
|
||||||
<strong id="user-nickname" title="{{ 'Your account\' nickname.' | trans }}">{{ user_nickname }}</strong>
|
<strong id="user-nickname" title="{{ 'Your account\' nickname.' | trans }}">{{ user_nickname }}</strong>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user