[COMPONENT][Subscription] Implement subscription handlers
This commit is contained in:
parent
fe087b2217
commit
9ea230d12b
@ -2,10 +2,107 @@
|
|||||||
|
|
||||||
declare(strict_types = 1);
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
// {{{ 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 Component\Subscription;
|
namespace Component\Subscription;
|
||||||
|
|
||||||
|
use App\Core\DB\DB;
|
||||||
|
use App\Core\Event;
|
||||||
|
use function App\Core\I18n\_m;
|
||||||
use App\Core\Modules\Component;
|
use App\Core\Modules\Component;
|
||||||
|
use App\Entity\Activity;
|
||||||
|
use App\Entity\Actor;
|
||||||
|
use App\Entity\LocalUser;
|
||||||
|
use App\Util\Exception\ServerException;
|
||||||
|
|
||||||
class Subscription extends Component
|
class Subscription extends Component
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Persists a new Subscription Entity from Subscriber to Subject (Actor being subscribed) and Activity
|
||||||
|
*
|
||||||
|
* A new notification is then handled, informing all interested Actors of this action
|
||||||
|
*
|
||||||
|
* @throws ServerException
|
||||||
|
*/
|
||||||
|
public static function subscribe(int|Actor|LocalUser $subscriber, int|Actor|LocalUser $subject, string $source = 'web'): ?Activity
|
||||||
|
{
|
||||||
|
$subscriber_id = \is_int($subscriber) ? $subscriber : $subscriber->getId();
|
||||||
|
$subscribed_id = \is_int($subject) ? $subject : $subject->getId();
|
||||||
|
$opts = [
|
||||||
|
'subscriber_id' => $subscriber_id,
|
||||||
|
'subscribed_id' => $subscribed_id,
|
||||||
|
];
|
||||||
|
$subscription = DB::findOneBy(table: \Component\Subscription\Entity\Subscription::class, criteria: $opts, return_null: true);
|
||||||
|
$activity = null;
|
||||||
|
if (\is_null($subscription)) {
|
||||||
|
DB::persist(\Component\Subscription\Entity\Subscription::create($opts));
|
||||||
|
$activity = Activity::create([
|
||||||
|
'actor_id' => $subscriber_id,
|
||||||
|
'verb' => 'subscribe',
|
||||||
|
'object_type' => 'actor',
|
||||||
|
'object_id' => $subscribed_id,
|
||||||
|
'source' => $source,
|
||||||
|
]);
|
||||||
|
DB::persist($activity);
|
||||||
|
|
||||||
|
Event::handle('NewNotification', [
|
||||||
|
$actor = ($subscriber instanceof Actor ? $subscriber : Actor::getById($subscribed_id)),
|
||||||
|
$activity,
|
||||||
|
['object' => [$subscribed_id]],
|
||||||
|
_m('{nickname} subscribed to {subject}.', ['{actor}' => $actor->getId(), '{subject}' => $activity->getObjectId()]),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
return $activity;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the Subscription Entity created beforehand, by the same Actor, and on the same subject
|
||||||
|
*
|
||||||
|
* Informs all interested Actors of this action, handling out the NewNotification event
|
||||||
|
*
|
||||||
|
* @throws ServerException
|
||||||
|
*/
|
||||||
|
public static function unsubscribe(int|Actor|LocalUser $subscriber, int|Actor|LocalUser $subject, string $source = 'web'): ?Activity
|
||||||
|
{
|
||||||
|
$subscriber_id = \is_int($subscriber) ? $subscriber : $subscriber->getId();
|
||||||
|
$subscribed_id = \is_int($subject) ? $subject : $subject->getId();
|
||||||
|
$opts = [
|
||||||
|
'subscriber_id' => $subscriber_id,
|
||||||
|
'subscribed_id' => $subscribed_id,
|
||||||
|
];
|
||||||
|
$subscription = DB::findOneBy(table: \Component\Subscription\Entity\Subscription::class, criteria: $opts, return_null: true);
|
||||||
|
$activity = null;
|
||||||
|
if (!\is_null($subscription)) {
|
||||||
|
// Remove Subscription
|
||||||
|
DB::remove($subscription);
|
||||||
|
$previous_follow_activity = DB::findBy('activity', ['verb' => 'subscribe', 'object_type' => 'actor', 'object_id' => $subscribed_id], order_by: ['created' => 'DESC'])[0];
|
||||||
|
// Store Activity
|
||||||
|
$activity = Activity::create([
|
||||||
|
'actor_id' => $subscriber_id,
|
||||||
|
'verb' => 'undo',
|
||||||
|
'object_type' => 'activity',
|
||||||
|
'object_id' => $previous_follow_activity->getId(),
|
||||||
|
'source' => $source,
|
||||||
|
]);
|
||||||
|
DB::persist($activity);
|
||||||
|
}
|
||||||
|
return $activity;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -494,6 +494,13 @@ class ActivityPub extends Plugin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Try known remote
|
||||||
|
$aprofile = DB::findOneBy(ActivitypubActor::class, ['uri' => $resource], return_null: true);
|
||||||
|
if (!\is_null($aprofile)) {
|
||||||
|
return Actor::getById($aprofile->getActorId());
|
||||||
|
}
|
||||||
|
|
||||||
// Try remote
|
// Try remote
|
||||||
if ($try_online) {
|
if ($try_online) {
|
||||||
$aprofile = ActivitypubActor::getByAddr($resource);
|
$aprofile = ActivitypubActor::getByAddr($resource);
|
||||||
|
@ -32,7 +32,6 @@ declare(strict_types = 1);
|
|||||||
|
|
||||||
namespace Plugin\ActivityPub\Util\Model;
|
namespace Plugin\ActivityPub\Util\Model;
|
||||||
|
|
||||||
use _PHPStan_4a258568e\Nette\NotImplementedException;
|
|
||||||
use ActivityPhp\Type;
|
use ActivityPhp\Type;
|
||||||
use ActivityPhp\Type\AbstractObject;
|
use ActivityPhp\Type\AbstractObject;
|
||||||
use App\Core\Event;
|
use App\Core\Event;
|
||||||
@ -41,6 +40,7 @@ use App\Entity\Activity as GSActivity;
|
|||||||
use App\Util\Exception\ClientException;
|
use App\Util\Exception\ClientException;
|
||||||
use App\Util\Exception\NoSuchActorException;
|
use App\Util\Exception\NoSuchActorException;
|
||||||
use App\Util\Exception\NotFoundException;
|
use App\Util\Exception\NotFoundException;
|
||||||
|
use App\Util\Exception\NotImplementedException;
|
||||||
use DateTimeInterface;
|
use DateTimeInterface;
|
||||||
use InvalidArgumentException;
|
use InvalidArgumentException;
|
||||||
use Plugin\ActivityPub\ActivityPub;
|
use Plugin\ActivityPub\ActivityPub;
|
||||||
@ -168,7 +168,7 @@ class Activity extends Model
|
|||||||
$uri = match ($object->getObjectType()) {
|
$uri = match ($object->getObjectType()) {
|
||||||
'note' => Router::url('note_view', ['id' => $object->getObjectId()], type: Router::ABSOLUTE_URL),
|
'note' => Router::url('note_view', ['id' => $object->getObjectId()], type: Router::ABSOLUTE_URL),
|
||||||
'actor' => Router::url('actor_view_id', ['id' => $object->getObjectId()], type: Router::ABSOLUTE_URL),
|
'actor' => Router::url('actor_view_id', ['id' => $object->getObjectId()], type: Router::ABSOLUTE_URL),
|
||||||
default => throw new \App\Util\Exception\NotImplementedException(),
|
default => throw new NotImplementedException(),
|
||||||
};
|
};
|
||||||
$attr['object'] = Type::create('Tombstone', [
|
$attr['object'] = Type::create('Tombstone', [
|
||||||
'id' => $uri,
|
'id' => $uri,
|
||||||
|
@ -35,7 +35,8 @@ namespace Plugin\ActivityPub\Util\Model;
|
|||||||
use ActivityPhp\Type\AbstractObject;
|
use ActivityPhp\Type\AbstractObject;
|
||||||
use App\Core\DB\DB;
|
use App\Core\DB\DB;
|
||||||
use App\Entity\Activity as GSActivity;
|
use App\Entity\Activity as GSActivity;
|
||||||
use Component\Subscription\Entity\Subscription;
|
use App\Util\Exception\ClientException;
|
||||||
|
use Component\Subscription\Subscription;
|
||||||
use DateTime;
|
use DateTime;
|
||||||
use InvalidArgumentException;
|
use InvalidArgumentException;
|
||||||
use Plugin\ActivityPub\Entity\ActivitypubActivity;
|
use Plugin\ActivityPub\Entity\ActivitypubActivity;
|
||||||
@ -51,28 +52,17 @@ class ActivityFollow extends Activity
|
|||||||
protected static function handle_core_activity(\App\Entity\Actor $actor, AbstractObject $type_activity, mixed $type_object, ?ActivitypubActivity &$ap_act): ActivitypubActivity
|
protected static function handle_core_activity(\App\Entity\Actor $actor, AbstractObject $type_activity, mixed $type_object, ?ActivitypubActivity &$ap_act): ActivitypubActivity
|
||||||
{
|
{
|
||||||
if ($type_object instanceof AbstractObject) {
|
if ($type_object instanceof AbstractObject) {
|
||||||
$subscribed = Actor::fromJson($type_object);
|
$subscribed = Actor::fromJson($type_object)->getActorId();
|
||||||
} elseif ($type_object instanceof \App\Entity\Actor) {
|
} elseif ($type_object instanceof \App\Entity\Actor) {
|
||||||
$subscribed = $type_object;
|
$subscribed = $type_object;
|
||||||
} else {
|
} else {
|
||||||
throw new InvalidArgumentException('Follow{:Object} should be either an AbstractObject or an Actor.');
|
throw new InvalidArgumentException('Follow{:Object} should be either an AbstractObject or an Actor.');
|
||||||
}
|
}
|
||||||
// Store Subscription
|
// Execute Subscribe
|
||||||
DB::persist(Subscription::create([
|
$act = Subscription::subscribe($actor, $subscribed, 'ActivityPub');
|
||||||
'subscriber_id' => $actor->getId(),
|
if (\is_null($act)) {
|
||||||
'subscribed_id' => $subscribed->getActorId(),
|
throw new ClientException('You are already subscribed to this actor.');
|
||||||
'created' => new DateTime($type_activity->get('published') ?? 'now'),
|
}
|
||||||
]));
|
|
||||||
// Store Activity
|
|
||||||
$act = GSActivity::create([
|
|
||||||
'actor_id' => $actor->getId(),
|
|
||||||
'verb' => 'subscribe',
|
|
||||||
'object_type' => 'actor',
|
|
||||||
'object_id' => $subscribed->getActorId(),
|
|
||||||
'created' => new DateTime($type_activity->get('published') ?? 'now'),
|
|
||||||
'source' => 'ActivityPub',
|
|
||||||
]);
|
|
||||||
DB::persist($act);
|
|
||||||
// Store ActivityPub Activity
|
// Store ActivityPub Activity
|
||||||
$ap_act = ActivitypubActivity::create([
|
$ap_act = ActivitypubActivity::create([
|
||||||
'activity_id' => $act->getId(),
|
'activity_id' => $act->getId(),
|
||||||
@ -86,21 +76,11 @@ class ActivityFollow extends Activity
|
|||||||
|
|
||||||
public static function handle_undo(\App\Entity\Actor $actor, AbstractObject $type_activity, GSActivity $type_object, ?ActivitypubActivity &$ap_act): ActivitypubActivity
|
public static function handle_undo(\App\Entity\Actor $actor, AbstractObject $type_activity, GSActivity $type_object, ?ActivitypubActivity &$ap_act): ActivitypubActivity
|
||||||
{
|
{
|
||||||
// Remove Subscription
|
// Execute Unsubscribe
|
||||||
DB::removeBy(Subscription::class, [
|
$act = Subscription::unsubscribe($actor, $type_object->getObjectId(), 'ActivityPub');
|
||||||
'subscriber_id' => $type_object->getActorId(),
|
if (\is_null($act)) {
|
||||||
'subscribed_id' => $type_object->getObjectId(),
|
throw new ClientException('You are already unsubscribed of this actor.');
|
||||||
]);
|
}
|
||||||
// Store Activity
|
|
||||||
$act = GSActivity::create([
|
|
||||||
'actor_id' => $actor->getId(),
|
|
||||||
'verb' => 'undo',
|
|
||||||
'object_type' => 'activity',
|
|
||||||
'object_id' => $type_object->getId(),
|
|
||||||
'created' => new DateTime($type_activity->get('published') ?? 'now'),
|
|
||||||
'source' => 'ActivityPub',
|
|
||||||
]);
|
|
||||||
DB::persist($act);
|
|
||||||
// Store ActivityPub Activity
|
// Store ActivityPub Activity
|
||||||
$ap_act = ActivitypubActivity::create([
|
$ap_act = ActivitypubActivity::create([
|
||||||
'activity_id' => $act->getId(),
|
'activity_id' => $act->getId(),
|
||||||
|
@ -91,7 +91,7 @@ class Actor extends Model
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!isset($options['objects']['Actor'])) {
|
if (!isset($options['objects']['Actor'])) {
|
||||||
DB::persist($actor);
|
DB::wrapInTransaction(fn () => DB::persist($actor));
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActivityPub Actor
|
// ActivityPub Actor
|
||||||
@ -104,7 +104,7 @@ class Actor extends Model
|
|||||||
], $options['objects']['ActivitypubActor'] ?? null);
|
], $options['objects']['ActivitypubActor'] ?? null);
|
||||||
|
|
||||||
if (!isset($options['objects']['ActivitypubActor'])) {
|
if (!isset($options['objects']['ActivitypubActor'])) {
|
||||||
DB::persist($ap_actor);
|
DB::wrapInTransaction(fn () => DB::persist($ap_actor));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Public Key
|
// Public Key
|
||||||
@ -114,7 +114,7 @@ class Actor extends Model
|
|||||||
], $options['objects']['ActivitypubRsa'] ?? null);
|
], $options['objects']['ActivitypubRsa'] ?? null);
|
||||||
|
|
||||||
if (!isset($options['objects']['ActivitypubRsa'])) {
|
if (!isset($options['objects']['ActivitypubRsa'])) {
|
||||||
DB::persist($apRSA);
|
DB::wrapInTransaction(fn () => DB::persist($apRSA));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Avatar
|
// Avatar
|
||||||
|
@ -25,6 +25,7 @@ namespace Plugin\Favourite;
|
|||||||
|
|
||||||
use App\Core\DB\DB;
|
use App\Core\DB\DB;
|
||||||
use App\Core\Event;
|
use App\Core\Event;
|
||||||
|
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\Core\Router\Router;
|
use App\Core\Router\Router;
|
||||||
@ -38,7 +39,6 @@ use App\Util\Nickname;
|
|||||||
use DateTime;
|
use DateTime;
|
||||||
use Plugin\Favourite\Entity\NoteFavourite as FavouriteEntity;
|
use Plugin\Favourite\Entity\NoteFavourite as FavouriteEntity;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use function App\Core\I18n\_m;
|
|
||||||
|
|
||||||
class Favourite extends NoteHandlerPlugin
|
class Favourite extends NoteHandlerPlugin
|
||||||
{
|
{
|
||||||
@ -48,33 +48,28 @@ class Favourite extends NoteHandlerPlugin
|
|||||||
*
|
*
|
||||||
* A new notification is then handled, informing all interested Actors of this action
|
* A new notification is then handled, informing all interested Actors of this action
|
||||||
*
|
*
|
||||||
* @param int $note_id
|
|
||||||
* @param int $actor_id
|
|
||||||
* @param string $source
|
|
||||||
*
|
|
||||||
* @return \App\Entity\Activity|null
|
|
||||||
* @throws \App\Util\Exception\ServerException
|
* @throws \App\Util\Exception\ServerException
|
||||||
* @throws \Doctrine\ORM\ORMException
|
|
||||||
* @throws \Doctrine\ORM\OptimisticLockException
|
* @throws \Doctrine\ORM\OptimisticLockException
|
||||||
|
* @throws \Doctrine\ORM\ORMException
|
||||||
* @throws \Doctrine\ORM\TransactionRequiredException
|
* @throws \Doctrine\ORM\TransactionRequiredException
|
||||||
*/
|
*/
|
||||||
public static function favourNote(int $note_id, int $actor_id, string $source = 'web'): ?Activity
|
public static function favourNote(int $note_id, int $actor_id, string $source = 'web'): ?Activity
|
||||||
{
|
{
|
||||||
$opts = ['note_id' => $note_id, 'actor_id' => $actor_id];
|
$opts = ['note_id' => $note_id, 'actor_id' => $actor_id];
|
||||||
$note_already_favoured = DB::find('note_favourite', $opts);
|
$note_already_favoured = DB::findOneBy('note_favourite', $opts, return_null: true);
|
||||||
$activity = null;
|
$activity = null;
|
||||||
if (\is_null($note_already_favoured)) {
|
if (\is_null($note_already_favoured)) {
|
||||||
DB::persist(FavouriteEntity::create($opts));
|
DB::persist(FavouriteEntity::create($opts));
|
||||||
$activity = Activity::create([
|
$activity = Activity::create([
|
||||||
'actor_id' => $actor_id,
|
'actor_id' => $actor_id,
|
||||||
'verb' => 'favourite',
|
'verb' => 'favourite',
|
||||||
'object_type' => 'note',
|
'object_type' => 'note',
|
||||||
'object_id' => $note_id,
|
'object_id' => $note_id,
|
||||||
'source' => $source,
|
'source' => $source,
|
||||||
]);
|
]);
|
||||||
DB::persist($activity);
|
DB::persist($activity);
|
||||||
|
|
||||||
Event::handle('NewNotification', [$actor = Actor::getById($actor_id), $activity, [], _m('{nickname} favoured note {note_id}.', ['nickname' => $actor->getNickname(), 'note_id' => $activity->getObjectId()])]);
|
Event::handle('NewNotification', [$actor = Actor::getById($actor_id), $activity, [], _m('{nickname} favoured note {note_id}.', ['{nickname}' => $actor->getNickname(), '{note_id}' => $activity->getObjectId()])]);
|
||||||
}
|
}
|
||||||
return $activity;
|
return $activity;
|
||||||
}
|
}
|
||||||
@ -84,33 +79,28 @@ class Favourite extends NoteHandlerPlugin
|
|||||||
*
|
*
|
||||||
* Informs all interested Actors of this action, handling out the NewNotification event
|
* Informs all interested Actors of this action, handling out the NewNotification event
|
||||||
*
|
*
|
||||||
* @param int $note_id
|
|
||||||
* @param int $actor_id
|
|
||||||
* @param string $source
|
|
||||||
*
|
|
||||||
* @return \App\Entity\Activity|null
|
|
||||||
* @throws \App\Util\Exception\ServerException
|
* @throws \App\Util\Exception\ServerException
|
||||||
* @throws \Doctrine\ORM\ORMException
|
|
||||||
* @throws \Doctrine\ORM\OptimisticLockException
|
* @throws \Doctrine\ORM\OptimisticLockException
|
||||||
|
* @throws \Doctrine\ORM\ORMException
|
||||||
* @throws \Doctrine\ORM\TransactionRequiredException
|
* @throws \Doctrine\ORM\TransactionRequiredException
|
||||||
*/
|
*/
|
||||||
public static function unfavourNote(int $note_id, int $actor_id, string $source = 'web'): ?Activity
|
public static function unfavourNote(int $note_id, int $actor_id, string $source = 'web'): ?Activity
|
||||||
{
|
{
|
||||||
$note_already_favoured = DB::find('note_favourite', ['note_id' => $note_id, 'actor_id' => $actor_id]);
|
$note_already_favoured = DB::findOneBy('note_favourite', ['note_id' => $note_id, 'actor_id' => $actor_id], return_null: true);
|
||||||
$activity = null;
|
$activity = null;
|
||||||
if (!\is_null($note_already_favoured)) {
|
if (!\is_null($note_already_favoured)) {
|
||||||
DB::remove($note_already_favoured);
|
DB::remove($note_already_favoured);
|
||||||
$favourite_activity = DB::findBy('activity', ['verb' => 'favourite', 'object_type' => 'note', 'object_id' => $note_id], order_by: ['created' => 'DESC'])[ 0 ];
|
$favourite_activity = DB::findBy('activity', ['verb' => 'favourite', 'object_type' => 'note', 'object_id' => $note_id], order_by: ['created' => 'DESC'])[0];
|
||||||
$activity = Activity::create([
|
$activity = Activity::create([
|
||||||
'actor_id' => $actor_id,
|
'actor_id' => $actor_id,
|
||||||
'verb' => 'undo', // 'undo_favourite',
|
'verb' => 'undo', // 'undo_favourite',
|
||||||
'object_type' => 'activity', // 'note',
|
'object_type' => 'activity', // 'note',
|
||||||
'object_id' => $favourite_activity->getId(), // $note_id,
|
'object_id' => $favourite_activity->getId(), // $note_id,
|
||||||
'source' => $source,
|
'source' => $source,
|
||||||
]);
|
]);
|
||||||
DB::persist($activity);
|
DB::persist($activity);
|
||||||
|
|
||||||
Event::handle('NewNotification', [$actor = Actor::getById($actor_id), $activity, [], _m('{nickname} unfavoured note {note_id}.', ['nickname' => $actor->getNickname(), 'note_id' => $activity->getObjectId()])]);
|
Event::handle('NewNotification', [$actor = Actor::getById($actor_id), $activity, [], _m('{nickname} unfavoured note {note_id}.', ['{nickname}' => $actor->getNickname(), '{note_id}' => $activity->getObjectId()])]);
|
||||||
}
|
}
|
||||||
return $activity;
|
return $activity;
|
||||||
}
|
}
|
||||||
@ -119,14 +109,11 @@ class Favourite extends NoteHandlerPlugin
|
|||||||
* HTML rendering event that adds the favourite form as a note
|
* HTML rendering event that adds the favourite form as a note
|
||||||
* action, if a user is logged in
|
* action, if a user is logged in
|
||||||
*
|
*
|
||||||
* @param \Symfony\Component\HttpFoundation\Request $request
|
* @throws \Doctrine\ORM\OptimisticLockException
|
||||||
* @param \App\Entity\Note $note
|
* @throws \Doctrine\ORM\ORMException
|
||||||
* @param array $actions
|
* @throws \Doctrine\ORM\TransactionRequiredException
|
||||||
*
|
*
|
||||||
* @return bool Event hook
|
* @return bool Event hook
|
||||||
* @throws \Doctrine\ORM\ORMException
|
|
||||||
* @throws \Doctrine\ORM\OptimisticLockException
|
|
||||||
* @throws \Doctrine\ORM\TransactionRequiredException
|
|
||||||
*/
|
*/
|
||||||
public function onAddNoteActions(Request $request, Note $note, array &$actions): bool
|
public function onAddNoteActions(Request $request, Note $note, array &$actions): bool
|
||||||
{
|
{
|
||||||
@ -135,12 +122,12 @@ class Favourite extends NoteHandlerPlugin
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If note is favourite, "is_favourite" is 1
|
// If note is favourite, "is_favourite" is 1
|
||||||
$opts = ['note_id' => $note->getId(), 'actor_id' => $user->getId()];
|
$opts = ['note_id' => $note->getId(), 'actor_id' => $user->getId()];
|
||||||
$is_favourite = DB::find('note_favourite', $opts) !== null;
|
$is_favourite = !\is_null(DB::findOneBy('note_favourite', $opts, return_null: true));
|
||||||
|
|
||||||
// Generating URL for favourite action route
|
// Generating URL for favourite action route
|
||||||
$args = ['id' => $note->getId()];
|
$args = ['id' => $note->getId()];
|
||||||
$type = Router::ABSOLUTE_PATH;
|
$type = Router::ABSOLUTE_PATH;
|
||||||
$favourite_action_url = $is_favourite
|
$favourite_action_url = $is_favourite
|
||||||
? Router::url('favourite_remove', $args, $type)
|
? Router::url('favourite_remove', $args, $type)
|
||||||
: Router::url('favourite_add', $args, $type);
|
: Router::url('favourite_add', $args, $type);
|
||||||
@ -149,12 +136,12 @@ class Favourite extends NoteHandlerPlugin
|
|||||||
// Concatenating get parameter to redirect the user to where he came from
|
// Concatenating get parameter to redirect the user to where he came from
|
||||||
$favourite_action_url .= '?from=' . urlencode($request->getRequestUri());
|
$favourite_action_url .= '?from=' . urlencode($request->getRequestUri());
|
||||||
|
|
||||||
$extra_classes = $is_favourite ? 'note-actions-set' : 'note-actions-unset';
|
$extra_classes = $is_favourite ? 'note-actions-set' : 'note-actions-unset';
|
||||||
$favourite_action = [
|
$favourite_action = [
|
||||||
'url' => $favourite_action_url,
|
'url' => $favourite_action_url,
|
||||||
'title' => $is_favourite ? 'Remove this note from favourites' : 'Favourite this note!',
|
'title' => $is_favourite ? 'Remove this note from favourites' : 'Favourite this note!',
|
||||||
'classes' => "button-container favourite-button-container {$extra_classes}",
|
'classes' => "button-container favourite-button-container {$extra_classes}",
|
||||||
'id' => 'favourite-button-container-' . $note->getId(),
|
'id' => 'favourite-button-container-' . $note->getId(),
|
||||||
];
|
];
|
||||||
|
|
||||||
$actions[] = $favourite_action;
|
$actions[] = $favourite_action;
|
||||||
@ -168,7 +155,7 @@ class Favourite extends NoteHandlerPlugin
|
|||||||
$check_user = !\is_null(Common::user());
|
$check_user = !\is_null(Common::user());
|
||||||
|
|
||||||
// The current Note being rendered
|
// The current Note being rendered
|
||||||
$note = $vars[ 'note' ];
|
$note = $vars['note'];
|
||||||
|
|
||||||
// Will have actors array, and action string
|
// Will have actors array, and action string
|
||||||
// Actors are the subjects, action is the verb (in the final phrase)
|
// Actors are the subjects, action is the verb (in the final phrase)
|
||||||
@ -179,18 +166,13 @@ class Favourite extends NoteHandlerPlugin
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Filter out multiple replies from the same actor
|
// Filter out multiple replies from the same actor
|
||||||
$favourite_actors = array_unique($favourite_actors, SORT_REGULAR);
|
$favourite_actors = array_unique($favourite_actors, \SORT_REGULAR);
|
||||||
$result[] = ['actors' => $favourite_actors, 'action' => 'favourited'];
|
$result[] = ['actors' => $favourite_actors, 'action' => 'favourited'];
|
||||||
return Event::next;
|
return Event::next;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes every favourite entity in table related to a deleted Note
|
* Deletes every favourite entity in table related to a deleted Note
|
||||||
*
|
|
||||||
* @param \App\Entity\Note $note
|
|
||||||
* @param \App\Entity\Actor $actor
|
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
*/
|
||||||
public function onNoteDeleteRelated(Note &$note, Actor $actor): bool
|
public function onNoteDeleteRelated(Note &$note, Actor $actor): bool
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user