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
This commit is contained in:
Yassine Doghri 2022-07-21 13:53:29 +00:00
parent 9cc2996261
commit 8acdafd260
5 changed files with 40 additions and 45 deletions

View File

@ -122,23 +122,9 @@ Events::on('on_undo_follow', function ($actor, $targetActor): void {
* @param Post $post * @param Post $post
*/ */
Events::on('on_post_add', function ($post): void { Events::on('on_post_add', function ($post): void {
$isReply = $post->in_reply_to_id !== null; model(EpisodeModel::class, false)->builder()
->where('id', $post->episode_id)
if ($isReply) { ->increment('posts_count');
$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');
}
}
if ($post->actor->is_podcast) { if ($post->actor->is_podcast) {
// Removing all of the podcast pages is a bit overkill, but works to avoid caching bugs // 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 * @param Post $post
*/ */
Events::on('on_post_remove', function ($post): void { 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) { if ($episodeId = $post->episode_id) {
model(EpisodeModel::class, false)->builder() model(EpisodeModel::class, false)->builder()
->where('id', $episodeId) ->where('id', $episodeId)
@ -237,6 +219,10 @@ Events::on('on_post_undo_reblog', function ($reblogPost): void {
Events::on('on_post_reply', function ($reply): void { Events::on('on_post_reply', function ($reply): void {
$post = $reply->reply_to_post; $post = $reply->reply_to_post;
model(EpisodeModel::class, false)->builder()
->where('id', $post->episode_id)
->increment('comments_count');
if ($post->actor->is_podcast) { if ($post->actor->is_podcast) {
cache() cache()
->deleteMatching("podcast#{$post->actor->podcast->id}*"); ->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 { Events::on('on_reply_remove', function ($reply): void {
$post = $reply->reply_to_post; $post = $reply->reply_to_post;
model(EpisodeModel::class, false)->builder()
->where('id', $post->episode_id)
->decrement('comments_count');
if ($post->actor->is_podcast) { if ($post->actor->is_podcast) {
cache() cache()
->deleteMatching("page_podcast#{$post->actor->podcast->id}*"); ->deleteMatching("page_podcast#{$post->actor->podcast->id}*");

View File

@ -74,6 +74,10 @@ class PostController extends FediversePostController
$this->registerPodcastWebpageHit($this->podcast->id); $this->registerPodcastWebpageHit($this->podcast->id);
} }
if ($this->post === null) {
throw PageNotFoundException::forPageNotFound();
}
$cacheName = implode( $cacheName = implode(
'_', '_',
array_filter([ array_filter([
@ -177,7 +181,7 @@ class PostController extends FediversePostController
'created_by' => user_id(), '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; $newPost->episode_id = $this->post->episode_id;
} }

View File

@ -62,7 +62,6 @@ class PostModel extends FediversePostModel
->join(config('Fediverse')->tablesPrefix . 'posts as p2', 'p1.id = p2.in_reply_to_id') ->join(config('Fediverse')->tablesPrefix . 'posts as p2', 'p1.id = p2.in_reply_to_id')
->select('p2.id, p1.episode_id') ->select('p2.id, p1.episode_id')
->where([ ->where([
'p1.in_reply_to_id' => null,
'p2.in_reply_to_id IS NOT' => null, 'p2.in_reply_to_id IS NOT' => null,
'p2.episode_id' => null, 'p2.episode_id' => null,
'p1.episode_id IS NOT' => null, 'p1.episode_id IS NOT' => null,

View File

@ -714,6 +714,8 @@ class EpisodeController extends BaseController
$allPostsLinkedToEpisode = (new PostModel()) $allPostsLinkedToEpisode = (new PostModel())
->where([ ->where([
'episode_id' => $this->episode->id, 'episode_id' => $this->episode->id,
'in_reply_to_id' => null,
'reblog_of_id' => null,
]) ])
->findAll(); ->findAll();
foreach ($allPostsLinkedToEpisode as $post) { foreach ($allPostsLinkedToEpisode as $post) {

View File

@ -277,10 +277,12 @@ class PostModel extends BaseUuidModel
} }
if ($post->in_reply_to_id === null) { if ($post->in_reply_to_id === null) {
// increment posts_count only if not reply // post is not a reply
model('ActorModel', false) model('ActorModel', false)
->where('id', $post->actor_id) ->where('id', $post->actor_id)
->increment('posts_count'); ->increment('posts_count');
Events::trigger('on_post_add', $post);
} }
if ($registerActivity) { if ($registerActivity) {
@ -314,8 +316,6 @@ class PostModel extends BaseUuidModel
]); ]);
} }
Events::trigger('on_post_add', $post);
$this->clearCache($post); $this->clearCache($post);
$this->db->transComplete(); $this->db->transComplete();
@ -365,26 +365,13 @@ class PostModel extends BaseUuidModel
{ {
$this->db->transStart(); $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 // remove all post reblogs
foreach ($post->reblogs as $reblog) { foreach ($post->reblogs as $reblog) {
// FIXME: issue when actor is not local, can't get actor information // 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) { foreach ($post->replies as $reply) {
$this->removePost($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) $result = model('PostModel', false)
->delete($post->id); ->delete($post->id);
Events::trigger('on_post_remove', $post);
$this->clearCache($post); $this->clearCache($post);
$this->db->transComplete(); $this->db->transComplete();
@ -574,11 +574,11 @@ class PostModel extends BaseUuidModel
]); ]);
} }
Events::trigger('on_post_undo_reblog', $reblogPost);
$result = model('PostModel', false) $result = model('PostModel', false)
->delete($reblogPost->id); ->delete($reblogPost->id);
Events::trigger('on_post_undo_reblog', $reblogPost);
$this->clearCache($reblogPost); $this->clearCache($reblogPost);
$this->db->transComplete(); $this->db->transComplete();