[COMPONENT][Subscription] Start component

This commit is contained in:
Diogo Peralta Cordeiro 2022-01-02 20:00:17 +00:00
parent 5fa8056899
commit 6cfb69d64b
Signed by: diogo
GPG Key ID: 18D2D35001FBFAB0
7 changed files with 77 additions and 46 deletions

View File

@ -39,6 +39,7 @@ use Component\Collection\Util\ActorControllerTrait;
use Component\Collection\Util\Controller\FeedController; use Component\Collection\Util\Controller\FeedController;
use Component\Group\Entity\GroupMember; use Component\Group\Entity\GroupMember;
use Component\Group\Entity\LocalGroup; use Component\Group\Entity\LocalGroup;
use Component\Subscription\Entity\Subscription;
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;
@ -91,7 +92,7 @@ class Group extends FeedController
'group_id' => $group->getId(), 'group_id' => $group->getId(),
'nickname' => $nickname, 'nickname' => $nickname,
])); ]));
DB::persist(E\Subscription::create([ DB::persist(Subscription::create([
'subscriber' => $group->getId(), 'subscriber' => $group->getId(),
'subscribed' => $group->getId(), 'subscribed' => $group->getId(),
])); ]));
@ -115,7 +116,7 @@ class Group extends FeedController
} else { } else {
if (!\is_null($actor) if (!\is_null($actor)
&& \is_null(Cache::get( && \is_null(Cache::get(
E\Subscription::cacheKeys($actor, $group)['subscribed'], Subscription::cacheKeys($actor, $group)['subscribed'],
fn () => DB::findOneBy('subscription', [ fn () => DB::findOneBy('subscription', [
'subscriber' => $actor->getId(), 'subscriber' => $actor->getId(),
'subscribed' => $group->getId(), 'subscribed' => $group->getId(),
@ -125,14 +126,14 @@ class Group extends FeedController
$subscribe_form = Form::create([['subscribe', SubmitType::class, ['label' => _m('Subscribe to this group')]]]); $subscribe_form = Form::create([['subscribe', SubmitType::class, ['label' => _m('Subscribe to this group')]]]);
$subscribe_form->handleRequest($request); $subscribe_form->handleRequest($request);
if ($subscribe_form->isSubmitted() && $subscribe_form->isValid()) { if ($subscribe_form->isSubmitted() && $subscribe_form->isValid()) {
DB::persist(E\Subscription::create([ DB::persist(Subscription::create([
'subscriber' => $actor->getId(), 'subscriber' => $actor->getId(),
'subscribed' => $group->getId(), 'subscribed' => $group->getId(),
])); ]));
DB::flush(); DB::flush();
Cache::delete(E\Actor::cacheKeys($group->getId())['subscriber']); Cache::delete(E\Actor::cacheKeys($group->getId())['subscriber']);
Cache::delete(E\Actor::cacheKeys($actor->getId())['subscribed']); Cache::delete(E\Actor::cacheKeys($actor->getId())['subscribed']);
Cache::delete(E\Subscription::cacheKeys($actor, $group)['subscribed']); Cache::delete(Subscription::cacheKeys($actor, $group)['subscribed']);
} }
} }
} }

View File

@ -21,22 +21,24 @@ declare(strict_types = 1);
// }}} // }}}
namespace App\Controller; namespace Component\Subscription\Controller;
use App\Core\Controller\ActorController; use function App\Core\I18n\_m;
use Component\Collection\Util\ActorControllerTrait;
use Component\Collection\Util\Controller\CircleController;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
/** /**
* Collection of an actor's subscribers * Collection of an actor's subscribers
*/ */
class Subscribers extends ActorController class Subscribers extends CircleController
{ {
use ActorControllerTrait;
public function subscribersByActorId(Request $request, int $id) public function subscribersByActorId(Request $request, int $id)
{ {
return $this->handleActorById( return $this->handleActorById(
$id, $id,
fn ($actor) => [ fn ($actor) => [
'_template' => 'subscribers/view.html.twig',
'actor' => $actor, 'actor' => $actor,
], ],
); );
@ -47,8 +49,12 @@ class Subscribers extends ActorController
return $this->handleActorByNickname( return $this->handleActorByNickname(
$nickname, $nickname,
fn ($actor) => [ fn ($actor) => [
'_template' => 'subscribers/view.html.twig', '_template' => 'collection/actors.html.twig',
'actor' => $actor, 'title' => _m('Subscribers'),
'empty_message' => _m('No subscribers'),
'sort_options' => [],
'page' => $this->int('page') ?? 1,
'actors' => $actor->getSubscribers(),
], ],
); );
} }

View File

@ -21,22 +21,24 @@ declare(strict_types = 1);
// }}} // }}}
namespace App\Controller; namespace Component\Subscription\Controller;
use App\Core\Controller\ActorController; use function App\Core\I18n\_m;
use Component\Collection\Util\ActorControllerTrait;
use Component\Collection\Util\Controller\CircleController;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
/** /**
* Collection of an actor's subscriptions * Collection of an actor's subscriptions
*/ */
class Subscriptions extends ActorController class Subscriptions extends CircleController
{ {
use ActorControllerTrait;
public function subscriptionsByActorId(Request $request, int $id) public function subscriptionsByActorId(Request $request, int $id)
{ {
return $this->handleActorById( return $this->handleActorById(
$id, $id,
fn ($actor) => [ fn ($actor) => [
'_template' => 'subscriptions/view.html.twig',
'actor' => $actor, 'actor' => $actor,
], ],
); );
@ -47,8 +49,12 @@ class Subscriptions extends ActorController
return $this->handleActorByNickname( return $this->handleActorByNickname(
$nickname, $nickname,
fn ($actor) => [ fn ($actor) => [
'_template' => 'subscriptions/view.html.twig', '_template' => 'collection/actors.html.twig',
'actor' => $actor, 'title' => _m('Subscribers'),
'empty_message' => _m('No subscribers'),
'sort_options' => [],
'page' => $this->int('page') ?? 1,
'actors' => $actor->getSubscribers(),
], ],
); );
} }

View File

@ -9,10 +9,10 @@ use App\Core\VisibilityScope;
use App\Entity\Actor; use App\Entity\Actor;
use App\Entity\LocalUser; use App\Entity\LocalUser;
use App\Entity\Note; use App\Entity\Note;
use App\Entity\Subscription;
use Component\Group\Entity\GroupInbox; use Component\Group\Entity\GroupInbox;
use Component\Group\Entity\GroupMember; use Component\Group\Entity\GroupMember;
use Component\Group\Entity\LocalGroup; use Component\Group\Entity\LocalGroup;
use Component\Subscription\Entity\Subscription;
use Doctrine\Bundle\FixturesBundle\Fixture; use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Persistence\ObjectManager; use Doctrine\Persistence\ObjectManager;

View File

@ -37,6 +37,7 @@ use App\Util\Nickname;
use Component\Avatar\Avatar; use Component\Avatar\Avatar;
use Component\Language\Entity\ActorLanguage; use Component\Language\Entity\ActorLanguage;
use Component\Language\Entity\Language; use Component\Language\Entity\Language;
use Component\Subscription\Entity\Subscription;
use DateTimeInterface; use DateTimeInterface;
use Functional as F; use Functional as F;
@ -375,10 +376,7 @@ class Actor extends Entity
{ {
return Cache::get( return Cache::get(
self::cacheKeys($this->getId())[$which], self::cacheKeys($this->getId())[$which],
fn () => DB::dql( fn() => DB::count(Subscription::class, [$column => $this->getId()]) - ($this->getIsLocal() ? 1 : 0)
"select count(s) from subscription s where s.{$column} = :{$column}", // Not injecting the parameter value
[$column => $this->getId()],
)[0][1] - ($this->getIsLocal() ? 1 : 0), // Remove self subscription if local
); );
} }
@ -387,11 +385,31 @@ class Actor extends Entity
return $this->getSubCount(which: 'subscriber', column: 'subscribed_id'); return $this->getSubCount(which: 'subscriber', column: 'subscribed_id');
} }
public function getSubscribedCount() public function getSubscribedCount(): int
{ {
return $this->getSubCount(which: 'subscribed', column: 'subscriber_id'); return $this->getSubCount(which: 'subscribed', column: 'subscriber_id');
} }
public function getSubscriptions(): array
{
return DB::dql(<<<EOF
SELECT a FROM actor AS a
INNER JOIN subscription AS s
WITH a.id = s.subscribed_id
WHERE s.subscriber_id = :self AND a.id != :self
EOF, ['self' => $this->getId()]);
}
public function getSubscribers(): array
{
return DB::dql(<<<EOF
SELECT a FROM actor AS a
INNER JOIN subscription AS s
WITH a.id = s.subscriber_id
WHERE s.subscribed_id = :self AND a.id != :self
EOF, ['self' => $this->getId()]);
}
/** /**
* Resolve an ambiguous nickname reference, checking in following order: * Resolve an ambiguous nickname reference, checking in following order:
* - Actors that $sender subscribes to * - Actors that $sender subscribes to

View File

@ -34,9 +34,9 @@ declare(strict_types = 1);
namespace App\Routes; namespace App\Routes;
use App\Controller as C;
use App\Core\Router\RouteLoader; use App\Core\Router\RouteLoader;
use App\Util\Nickname; use App\Util\Nickname;
use Component\Subscription\Controller as C;
abstract class Subscribers abstract class Subscribers
{ {

View File

@ -34,9 +34,9 @@ declare(strict_types = 1);
namespace App\Routes; namespace App\Routes;
use App\Controller as C;
use App\Core\Router\RouteLoader; use App\Core\Router\RouteLoader;
use App\Util\Nickname; use App\Util\Nickname;
use Component\Subscription\Controller as C;
abstract class Subscriptions abstract class Subscriptions
{ {