From 836560f55f39890136861d8ee1bdfbae7978b40f Mon Sep 17 00:00:00 2001 From: Eliseu Amaro Date: Wed, 29 Dec 2021 17:54:02 +0000 Subject: [PATCH] [CARDS][Note] AppendCardNote event overhaul [PLUGINS][Favourite] Added complementary information on user action [COMPONENTS][Conversation] Fixed AppendCardNote issue where cached query would only act on Notes with depth > 1 --- components/Conversation/Conversation.php | 44 ++++++---------- .../Conversation/Entity/Conversation.php | 2 + .../{Favourite.php => NoteFavourite.php} | 19 ++++++- plugins/Favourite/Favourite.php | 28 ++++++++--- plugins/RepeatNote/RepeatNote.php | 50 ++++++------------- src/Entity/Note.php | 2 +- templates/cards/note/view.html.twig | 18 +++++-- 7 files changed, 83 insertions(+), 80 deletions(-) rename plugins/Favourite/Entity/{Favourite.php => NoteFavourite.php} (88%) diff --git a/components/Conversation/Conversation.php b/components/Conversation/Conversation.php index 6a7878359b..86c7502209 100644 --- a/components/Conversation/Conversation.php +++ b/components/Conversation/Conversation.php @@ -118,45 +118,29 @@ class Conversation extends Component */ public function onAppendCardNote(array $vars, array &$result): bool { - // if note is the original, append on end "user replied to this" - // if note is the reply itself: append on end "in response to user in conversation" + // 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?" $check_user = !\is_null(Common::user()); - $note = $vars['note']; - $complementary_info = ''; - $reply_actor = []; - $note_replies = $note->getReplies(); + // The current Note being rendered + $note = $vars['note']; - // Get actors who replied + // Will have actors array, and action string + // Actors are the subjects, action is the verb (in the final phrase) + $reply_actors = []; + $note_replies = $note->getReplies(); + + // Get actors who repeated the note foreach ($note_replies as $reply) { - $reply_actor[] = Actor::getByPK($reply->getActorId()); + $reply_actors[] = Actor::getByPK($reply->getActorId()); } - if (\count($reply_actor) < 1) { + if (\count($reply_actors) < 1) { return Event::next; } // Filter out multiple replies from the same actor - $reply_actor = array_unique($reply_actor, \SORT_REGULAR); - - // Add to complementary info - foreach ($reply_actor as $actor) { - $reply_actor_url = $actor->getUrl(); - $reply_actor_nickname = $actor->getNickname(); - - if ($check_user && $actor->getId() === (Common::actor())->getId()) { - // If the reply is yours - $you_translation = _m('You'); - $prepend = "{$you_translation}, " . ($prepend = &$complementary_info); - $complementary_info = $prepend; - } else { - // If the repeat is from someone else - $complementary_info .= "{$reply_actor_nickname}, "; - } - } - - $complementary_info = rtrim(trim($complementary_info), ','); - $complementary_info .= _m(' replied to this note.'); - $result[] = Formatting::twigRenderString($complementary_info, []); + $reply_actors = array_unique($reply_actors, SORT_REGULAR); + $result[] = ['actors' => $reply_actors, 'action' => 'replied to']; return Event::next; } diff --git a/components/Conversation/Entity/Conversation.php b/components/Conversation/Entity/Conversation.php index fce7a5ee9c..9ed2d8cb62 100644 --- a/components/Conversation/Entity/Conversation.php +++ b/components/Conversation/Entity/Conversation.php @@ -23,8 +23,10 @@ declare(strict_types = 1); namespace Component\Conversation\Entity; +use App\Core\DB\DB; use App\Core\Entity; use App\Core\Router\Router; +use App\Entity\Note; /** * Entity class for Conversations diff --git a/plugins/Favourite/Entity/Favourite.php b/plugins/Favourite/Entity/NoteFavourite.php similarity index 88% rename from plugins/Favourite/Entity/Favourite.php rename to plugins/Favourite/Entity/NoteFavourite.php index 7b2c247aa7..9a500caadb 100644 --- a/plugins/Favourite/Entity/Favourite.php +++ b/plugins/Favourite/Entity/NoteFavourite.php @@ -21,11 +21,12 @@ declare(strict_types = 1); namespace Plugin\Favourite\Entity; +use App\Core\DB\DB; use App\Core\Entity; use App\Entity\Note; use DateTimeInterface; -class Favourite extends Entity +class NoteFavourite extends Entity { // {{{ Autocode // @codeCoverageIgnoreStart @@ -81,6 +82,20 @@ class Favourite extends Entity // @codeCoverageIgnoreEnd // }}} Autocode + public static function getNoteFavouriteActors(Note $note): array + { + return DB::dql( + <<<'EOF' + select a from actor as a + inner join note_favourite as nf + with nf.note_id = :note_id + where a.id = nf.actor_id + order by nf.created DESC + EOF, + ['note_id' => $note->getId()], + ); + } + public function getNotificationTargetIds(array $ids_already_known = [], ?int $sender_id = null, bool $include_additional = true): array { if (!\array_key_exists('object', $ids_already_known)) { @@ -102,7 +117,7 @@ class Favourite extends Entity public static function schemaDef() { return [ - 'name' => 'favourite', + 'name' => 'note_favourite', 'fields' => [ 'note_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'App\Entity\Note.id', 'multiplicity' => 'one to one', 'not null' => true, 'description' => 'note that is the favorite of'], 'actor_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'App\Entity\Actor.id', 'multiplicity' => 'one to one', 'not null' => true, 'description' => 'actor who favourited this note'], // note: formerly referenced notice.id, but we can now record remote users' favorites diff --git a/plugins/Favourite/Favourite.php b/plugins/Favourite/Favourite.php index 6d88c479ea..96aa95a8e0 100644 --- a/plugins/Favourite/Favourite.php +++ b/plugins/Favourite/Favourite.php @@ -37,7 +37,7 @@ use App\Entity\Note; use App\Util\Common; use App\Util\Nickname; use DateTime; -use Plugin\Favourite\Entity\Favourite as FavouriteEntity; +use Plugin\Favourite\Entity\NoteFavourite as FavouriteEntity; use Symfony\Component\HttpFoundation\Request; class Favourite extends NoteHandlerPlugin @@ -45,7 +45,7 @@ class Favourite extends NoteHandlerPlugin public static function favourNote(int $note_id, int $actor_id, string $source = 'web'): ?Activity { $opts = ['note_id' => $note_id, 'actor_id' => $actor_id]; - $note_already_favoured = DB::find('favourite', $opts); + $note_already_favoured = DB::find('note_favourite', $opts); $activity = null; if (\is_null($note_already_favoured)) { DB::persist(FavouriteEntity::create($opts)); @@ -65,7 +65,7 @@ class Favourite extends NoteHandlerPlugin public static function unfavourNote(int $note_id, int $actor_id, string $source = 'web'): ?Activity { - $note_already_favoured = DB::find('favourite', ['note_id' => $note_id, 'actor_id' => $actor_id]); + $note_already_favoured = DB::find('note_favourite', ['note_id' => $note_id, 'actor_id' => $actor_id]); $activity = null; if (!\is_null($note_already_favoured)) { DB::remove($note_already_favoured); @@ -98,7 +98,7 @@ class Favourite extends NoteHandlerPlugin // If note is favourite, "is_favourite" is 1 $opts = ['note_id' => $note->getId(), 'actor_id' => $user->getId()]; - $is_favourite = DB::find('favourite', $opts) !== null; + $is_favourite = DB::find('note_favourite', $opts) !== null; // Generating URL for favourite action route $args = ['id' => $note->getId()]; @@ -125,10 +125,24 @@ class Favourite extends NoteHandlerPlugin public function onAppendCardNote(array $vars, array &$result) { - // if note is the original, append on end "user favoured this" - $actor = $vars['actor']; - $note = $vars['note']; + // 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?" + $check_user = !\is_null(Common::user()); + // The current Note being rendered + $note = $vars['note']; + + // Will have actors array, and action string + // Actors are the subjects, action is the verb (in the final phrase) + $favourite_actors = FavouriteEntity::getNoteFavouriteActors($note); + + if (\count($favourite_actors) < 1) { + return Event::next; + } + + // Filter out multiple replies from the same actor + $favourite_actors = array_unique($favourite_actors, SORT_REGULAR); + $result[] = ['actors' => $favourite_actors, 'action' => 'favourited']; return Event::next; } diff --git a/plugins/RepeatNote/RepeatNote.php b/plugins/RepeatNote/RepeatNote.php index aa47460fc9..bec2c85131 100644 --- a/plugins/RepeatNote/RepeatNote.php +++ b/plugins/RepeatNote/RepeatNote.php @@ -245,57 +245,35 @@ class RepeatNote extends NoteHandlerPlugin * @param array $result Rendered String containing anchors for Actors that * repeated the Note * - * @return array|bool + * @return bool */ public function onAppendCardNote(array $vars, array &$result) { - // 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 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?" $check_user = !\is_null(Common::user()); + // The current Note being rendered $note = $vars['note']; - $complementary_info = ''; - $repeat_actor = []; + // Will have actors array, and action string + // Actors are the subjects, action is the verb (in the final phrase) + $repeat_actors = []; $note_repeats = NoteRepeat::getNoteRepeats($note); - // Get actors who replied - foreach ($note_repeats as $reply) { - $repeat_actor[] = Actor::getByPK($reply->getActorId()); + // Get actors who repeated the note + foreach ($note_repeats as $repeat) { + $repeat_actors[] = Actor::getByPK($repeat->getActorId()); } - if (\count($repeat_actor) < 1) { + if (\count($repeat_actors) < 1) { return Event::next; } // Filter out multiple replies from the same actor - $repeat_actor = array_unique($repeat_actor, SORT_REGULAR); + $repeat_actors = array_unique($repeat_actors, SORT_REGULAR); + $result[] = ['actors' => $repeat_actors, 'action' => 'repeated']; - // Add to complementary info - foreach ($repeat_actor as $actor) { - $repeat_actor_url = $actor->getUrl(); - $repeat_actor_nickname = $actor->getNickname(); - - if ($check_user && $actor->getId() === (Common::actor())->getId()) { - // If the repeat is yours - try { - $you_translation = _m('You'); - } catch (ServerException $e) { - $you_translation = 'You'; - } - - $prepend = "{$you_translation}, " . ($prepend = &$complementary_info); - $complementary_info = $prepend; - } else { - // If the repeat is from someone else - $complementary_info .= "{$repeat_actor_nickname}, "; - } - } - - $complementary_info = rtrim(trim($complementary_info), ','); - $complementary_info .= ' repeated this note.'; - $result[] = Formatting::twigRenderString($complementary_info, []); - - return $result; + return Event::next; } /** diff --git a/src/Entity/Note.php b/src/Entity/Note.php index 79f255861b..7a7307a4b2 100644 --- a/src/Entity/Note.php +++ b/src/Entity/Note.php @@ -354,7 +354,7 @@ class Note extends Entity */ public function getReplies(): array { - return Cache::get('note-replies-' . $this->getId(), fn () => DB::dql('select n from note n where n.reply_to = :id', ['id' => $this->getId()])); + return DB::findBy('note', ['reply_to' => $this->getId()], order_by: ['created' => 'DESC', 'id' => 'DESC']); } /** diff --git a/templates/cards/note/view.html.twig b/templates/cards/note/view.html.twig index 2180c24335..c8ca887e77 100644 --- a/templates/cards/note/view.html.twig +++ b/templates/cards/note/view.html.twig @@ -134,11 +134,21 @@ {{ block('note_replies') }} - {% for block in handle_event('AppendCardNote', {'note': note, 'actor': note.getActor() }) %} - + + {% for complementary_info in handle_event('AppendCardNote', {'note': note }) %} + {% endfor %} + + {% endmacro macro_note %}