Commit 78acd7f5 authored by Yassine Doghri's avatar Yassine Doghri
Browse files

feat(episode-unpublish): remove episode comments upon unpublish

parent 8acdafd2
Loading
Loading
Loading
Loading
Loading
+14 −6
Original line number Diff line number Diff line
@@ -219,11 +219,15 @@ Events::on('on_post_undo_reblog', function ($reblogPost): void {
Events::on('on_post_reply', function ($reply): void {
    $post = $reply->reply_to_post;

    if ($post->in_reply_to_id === null) {
        model(EpisodeModel::class, false)->builder()
            ->where('id', $post->episode_id)
            ->increment('comments_count');
    }

    if ($post->actor->is_podcast) {
        cache()
            ->deleteMatching("podcast-{$post->actor->podcast->handle}*");
        cache()
            ->deleteMatching("podcast#{$post->actor->podcast->id}*");
        cache()
@@ -240,11 +244,15 @@ Events::on('on_post_reply', function ($reply): void {
Events::on('on_reply_remove', function ($reply): void {
    $post = $reply->reply_to_post;

    if ($post->in_reply_to_id === null) {
        model(EpisodeModel::class, false)->builder()
            ->where('id', $post->episode_id)
            ->decrement('comments_count');
    }

    if ($post->actor->is_podcast) {
        cache()
            ->deleteMatching("podcast-{$post->actor->podcast->handle}*");
        cache()
            ->deleteMatching("page_podcast#{$post->actor->podcast->id}*");
        cache()
+1 −0
Original line number Diff line number Diff line
@@ -72,6 +72,7 @@ use RuntimeException;
 * @property bool $is_published_on_hubs
 * @property int $posts_count
 * @property int $comments_count
 * @property EpisodeComment[]|null $comments
 * @property int $created_by
 * @property int $updated_by
 * @property string $publication_status;
+75 −7
Original line number Diff line number Diff line
@@ -14,9 +14,12 @@ use App\Entities\EpisodeComment;
use App\Libraries\CommentObject;
use CodeIgniter\Database\BaseBuilder;
use CodeIgniter\Database\BaseResult;
use CodeIgniter\I18n\Time;
use Michalsn\Uuid\UuidModel;
use Modules\Fediverse\Activities\CreateActivity;
use Modules\Fediverse\Activities\DeleteActivity;
use Modules\Fediverse\Models\ActivityModel;
use Modules\Fediverse\Objects\TombstoneObject;

class EpisodeCommentModel extends UuidModel
{
@@ -70,10 +73,9 @@ class EpisodeCommentModel extends UuidModel
        return $found;
    }

    public function addComment(EpisodeComment $comment, bool $registerActivity = false): string | false
    public function addComment(EpisodeComment $comment, bool $registerActivity = true): string | false
    {
        $this->db->transStart();
        // increment Episode's comments_count

        if (! ($newCommentId = $this->insert($comment, true))) {
            $this->db->transRollback();
@@ -128,15 +130,67 @@ class EpisodeCommentModel extends UuidModel

        $this->db->transComplete();

        // delete podcast and episode pages cache
        cache()
            ->deleteMatching('page_podcast#' . $comment->episode->podcast_id . '*');
        cache()
            ->deleteMatching('page_episode#' . $comment->episode_id . '*');
        $this->clearCache($comment);

        return $newCommentId;
    }

    public function removeComment(EpisodeComment $comment, bool $registerActivity = true): BaseResult | bool
    {
        $this->db->transStart();

        // remove all replies
        foreach ($comment->replies as $reply) {
            $this->removeComment($reply);
        }

        if ($registerActivity) {
            $deleteActivity = new DeleteActivity();
            $tombstoneObject = new TombstoneObject();
            $tombstoneObject->set('id', $comment->uri);
            $deleteActivity
                ->set('actor', $comment->actor->uri)
                ->set('object', $tombstoneObject);

            $activityId = model(ActivityModel::class, false)
                ->newActivity(
                    'Delete',
                    $comment->actor_id,
                    null,
                    null,
                    $deleteActivity->toJSON(),
                    Time::now(),
                    'queued',
                );

            $deleteActivity->set('id', url_to('activity', esc($comment->actor->username), $activityId));

            model(ActivityModel::class, false)
                ->update($activityId, [
                    'payload' => $deleteActivity->toJSON(),
                ]);
        }

        $result = model(self::class, false)
            ->delete($comment->id);

        if ($comment->in_reply_to_id === null) {
            model(EpisodeModel::class, false)->builder()
                ->where('id', $comment->episode_id)
                ->decrement('comments_count');
        } else {
            (new self())->builder()
                ->where('id', service('uuid')->fromString($comment->in_reply_to_id)->getBytes())
                ->decrement('replies_count');
        }

        $this->clearCache($comment);

        $this->db->transComplete();

        return $result;
    }

    /**
     * Retrieves all published posts for a given episode ordered by publication date
     *
@@ -250,4 +304,18 @@ class EpisodeCommentModel extends UuidModel

        return $data;
    }

    protected function clearCache(EpisodeComment $comment): void
    {
        cache()
            ->deleteMatching("comment#{$comment->id}*");

        // delete podcast and episode pages cache
        cache()
            ->deleteMatching("podcast-{$comment->episode->podcast->handle}*");
        cache()
            ->deleteMatching('page_podcast#' . $comment->episode->podcast_id . '*');
        cache()
            ->deleteMatching('page_episode#' . $comment->episode_id . '*');
    }
}
+12 −15
Original line number Diff line number Diff line
@@ -337,33 +337,30 @@ class EpisodeModel extends Model

    public function resetCommentsCount(): int | false
    {
        $episodeCommentsCount = $this->builder()
            ->select('episodes.id, COUNT(*) as `comments_count`')
            ->join('episode_comments', 'episodes.id = episode_comments.episode_id')
        $episodeCommentsCount = (new EpisodeCommentModel())->builder()
            ->select('episode_id, COUNT(*) as `comments_count`')
            ->where('in_reply_to_id', null)
            ->groupBy('episodes.id')
            ->groupBy('episode_id')
            ->getCompiledSelect();

        $episodePostsRepliesCount = $this->builder()
            ->select('episodes.id, COUNT(*) as `comments_count`')
            ->join(
                config('Fediverse')
                    ->tablesPrefix . 'posts',
                'episodes.id = ' . config('Fediverse')->tablesPrefix . 'posts.episode_id'
            )
            ->where('in_reply_to_id IS NOT', null)
            ->groupBy('episodes.id')
        $postsTable = config('Fediverse')
            ->tablesPrefix . 'posts';
        $episodePostsRepliesCount = (new PostModel())->builder()
            ->select($postsTable . '.episode_id as episode_id, COUNT(*) as `comments_count`')
            ->join($postsTable . ' as fp', $postsTable . '.id = fp.in_reply_to_id')
            ->where($postsTable . '.in_reply_to_id', null)
            ->groupBy($postsTable . '.episode_id')
            ->getCompiledSelect();

        /** @var BaseResult $query */
        $query = $this->db->query(
            'SELECT `id`, SUM(`comments_count`) as `comments_count` FROM (' . $episodeCommentsCount . ' UNION ALL ' . $episodePostsRepliesCount . ') x GROUP BY `id`'
            'SELECT `episode_id` as `id`, SUM(`comments_count`) as `comments_count` FROM (' . $episodeCommentsCount . ' UNION ALL ' . $episodePostsRepliesCount . ') x GROUP BY `episode_id`'
        );

        $countsPerEpisodeId = $query->getResultArray();

        if ($countsPerEpisodeId !== []) {
            return $this->updateBatch($countsPerEpisodeId, 'id');
            return (new self())->updateBatch($countsPerEpisodeId, 'id');
        }

        return 0;
+10 −0
Original line number Diff line number Diff line
@@ -722,6 +722,16 @@ class EpisodeController extends BaseController
            (new PostModel())->removePost($post);
        }

        $allCommentsLinkedToEpisode = (new EpisodeCommentModel())
            ->where([
                'episode_id' => $this->episode->id,
                'in_reply_to_id' => null,
            ])
            ->findAll();
        foreach ($allCommentsLinkedToEpisode as $comment) {
            (new EpisodeCommentModel())->removeComment($comment);
        }

        // set episode published_at to null to unpublish
        $this->episode->published_at = null;

Loading