From 8acdafd26044e50a4d6ee451bf24ad66003c5bb3 Mon Sep 17 00:00:00 2001 From: Yassine Doghri Date: Thu, 21 Jul 2022 13:53:29 +0000 Subject: [PATCH] fix(episode-unpublish): set consistent posts_counts' increments/decrements for actors and episodes Some episodes could not be unpublished because of out of range error when removing posts. fixes #233 --- app/Config/Events.php | 32 +++++--------- app/Controllers/PostController.php | 6 ++- app/Models/PostModel.php | 1 - .../Admin/Controllers/EpisodeController.php | 2 + modules/Fediverse/Models/PostModel.php | 44 +++++++++---------- 5 files changed, 40 insertions(+), 45 deletions(-) diff --git a/app/Config/Events.php b/app/Config/Events.php index f8567024..a36233f8 100644 --- a/app/Config/Events.php +++ b/app/Config/Events.php @@ -122,23 +122,9 @@ Events::on('on_undo_follow', function ($actor, $targetActor): void { * @param Post $post */ Events::on('on_post_add', function ($post): void { - $isReply = $post->in_reply_to_id !== null; - - if ($isReply) { - $post = $post->reply_to_post; - } - - if ($post->episode_id !== null) { - if ($isReply) { - model(EpisodeModel::class, false)->builder() - ->where('id', $post->episode_id) - ->increment('comments_count'); - } else { - model(EpisodeModel::class, false)->builder() - ->where('id', $post->episode_id) - ->increment('posts_count'); - } - } + model(EpisodeModel::class, false)->builder() + ->where('id', $post->episode_id) + ->increment('posts_count'); if ($post->actor->is_podcast) { // Removing all of the podcast pages is a bit overkill, but works to avoid caching bugs @@ -154,10 +140,6 @@ Events::on('on_post_add', function ($post): void { * @param Post $post */ Events::on('on_post_remove', function ($post): void { - if ($post->in_reply_to_id !== null) { - Events::trigger('on_post_remove', $post->reply_to_post); - } - if ($episodeId = $post->episode_id) { model(EpisodeModel::class, false)->builder() ->where('id', $episodeId) @@ -237,6 +219,10 @@ Events::on('on_post_undo_reblog', function ($reblogPost): void { Events::on('on_post_reply', function ($reply): void { $post = $reply->reply_to_post; + model(EpisodeModel::class, false)->builder() + ->where('id', $post->episode_id) + ->increment('comments_count'); + if ($post->actor->is_podcast) { cache() ->deleteMatching("podcast#{$post->actor->podcast->id}*"); @@ -254,6 +240,10 @@ Events::on('on_post_reply', function ($reply): void { Events::on('on_reply_remove', function ($reply): void { $post = $reply->reply_to_post; + model(EpisodeModel::class, false)->builder() + ->where('id', $post->episode_id) + ->decrement('comments_count'); + if ($post->actor->is_podcast) { cache() ->deleteMatching("page_podcast#{$post->actor->podcast->id}*"); diff --git a/app/Controllers/PostController.php b/app/Controllers/PostController.php index 78510e23..6e6f033e 100644 --- a/app/Controllers/PostController.php +++ b/app/Controllers/PostController.php @@ -74,6 +74,10 @@ class PostController extends FediversePostController $this->registerPodcastWebpageHit($this->podcast->id); } + if ($this->post === null) { + throw PageNotFoundException::forPageNotFound(); + } + $cacheName = implode( '_', array_filter([ @@ -177,7 +181,7 @@ class PostController extends FediversePostController 'created_by' => user_id(), ]); - if ($this->post->in_reply_to_id === null && $this->post->episode_id !== null) { + if ($this->post->episode_id !== null) { $newPost->episode_id = $this->post->episode_id; } diff --git a/app/Models/PostModel.php b/app/Models/PostModel.php index f100a853..6f8df615 100644 --- a/app/Models/PostModel.php +++ b/app/Models/PostModel.php @@ -62,7 +62,6 @@ class PostModel extends FediversePostModel ->join(config('Fediverse')->tablesPrefix . 'posts as p2', 'p1.id = p2.in_reply_to_id') ->select('p2.id, p1.episode_id') ->where([ - 'p1.in_reply_to_id' => null, 'p2.in_reply_to_id IS NOT' => null, 'p2.episode_id' => null, 'p1.episode_id IS NOT' => null, diff --git a/modules/Admin/Controllers/EpisodeController.php b/modules/Admin/Controllers/EpisodeController.php index 18c961c2..86684bad 100644 --- a/modules/Admin/Controllers/EpisodeController.php +++ b/modules/Admin/Controllers/EpisodeController.php @@ -714,6 +714,8 @@ class EpisodeController extends BaseController $allPostsLinkedToEpisode = (new PostModel()) ->where([ 'episode_id' => $this->episode->id, + 'in_reply_to_id' => null, + 'reblog_of_id' => null, ]) ->findAll(); foreach ($allPostsLinkedToEpisode as $post) { diff --git a/modules/Fediverse/Models/PostModel.php b/modules/Fediverse/Models/PostModel.php index e25e6c62..94f2130c 100644 --- a/modules/Fediverse/Models/PostModel.php +++ b/modules/Fediverse/Models/PostModel.php @@ -277,10 +277,12 @@ class PostModel extends BaseUuidModel } if ($post->in_reply_to_id === null) { - // increment posts_count only if not reply + // post is not a reply model('ActorModel', false) ->where('id', $post->actor_id) ->increment('posts_count'); + + Events::trigger('on_post_add', $post); } if ($registerActivity) { @@ -314,8 +316,6 @@ class PostModel extends BaseUuidModel ]); } - Events::trigger('on_post_add', $post); - $this->clearCache($post); $this->db->transComplete(); @@ -365,26 +365,13 @@ class PostModel extends BaseUuidModel { $this->db->transStart(); - model('ActorModel', false) - ->where('id', $post->actor_id) - ->decrement('posts_count'); - - if ($post->in_reply_to_id !== null) { - // Post to remove is a reply - model('PostModel', false) - ->where('id', $this->uuid->fromString($post->in_reply_to_id) ->getBytes()) - ->decrement('replies_count'); - - Events::trigger('on_reply_remove', $post); - } - // remove all post reblogs foreach ($post->reblogs as $reblog) { // FIXME: issue when actor is not local, can't get actor information - $this->removePost($reblog); + $this->undoReblog($reblog); } - // remove all post replies + // remove all replies foreach ($post->replies as $reply) { $this->removePost($reply); } @@ -427,11 +414,24 @@ class PostModel extends BaseUuidModel ]); } + if ($post->in_reply_to_id === null && $post->reblog_of_id === null) { + model('ActorModel', false) + ->where('id', $post->actor_id) + ->decrement('posts_count'); + + Events::trigger('on_post_remove', $post); + } elseif ($post->in_reply_to_id !== null) { + // Post to remove is a reply + model('PostModel', false) + ->where('id', $this->uuid->fromString($post->in_reply_to_id) ->getBytes()) + ->decrement('replies_count'); + + Events::trigger('on_reply_remove', $post); + } + $result = model('PostModel', false) ->delete($post->id); - Events::trigger('on_post_remove', $post); - $this->clearCache($post); $this->db->transComplete(); @@ -574,11 +574,11 @@ class PostModel extends BaseUuidModel ]); } + Events::trigger('on_post_undo_reblog', $reblogPost); + $result = model('PostModel', false) ->delete($reblogPost->id); - Events::trigger('on_post_undo_reblog', $reblogPost); - $this->clearCache($reblogPost); $this->db->transComplete();