Skip to content
Snippets Groups Projects
LikeModel.php 4.39 KiB
Newer Older
  • Learn to ignore specific revisions
  • <?php
    
    declare(strict_types=1);
    
    /**
     * @copyright  2021 Podlibre
     * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
     * @link       https://castopod.org/
     */
    
    namespace App\Models;
    
    use App\Entities\EpisodeComment;
    use App\Entities\Like;
    use Michalsn\Uuid\UuidModel;
    
    use Modules\Fediverse\Activities\LikeActivity;
    use Modules\Fediverse\Activities\UndoActivity;
    use Modules\Fediverse\Entities\Actor;
    
    
    class LikeModel extends UuidModel
    {
        /**
         * @var string
         */
        protected $table = 'likes';
    
        /**
         * @var string[]
         */
        protected $uuidFields = ['comment_id'];
    
        /**
         * @var string[]
         */
        protected $allowedFields = ['actor_id', 'comment_id'];
    
        /**
         * @var string
         */
        protected $returnType = Like::class;
    
        /**
         * @var bool
         */
        protected $useTimestamps = true;
    
        protected $updatedField;
    
        public function addLike(Actor $actor, EpisodeComment $comment, bool $registerActivity = true): void
        {
            $this->db->transStart();
    
            $this->insert([
                'actor_id' => $actor->id,
                'comment_id' => $comment->id,
            ]);
    
            (new EpisodeCommentModel())
                ->where('id', service('uuid')->fromString($comment->id)->getBytes())
                ->increment('likes_count');
    
            if ($registerActivity) {
                $likeActivity = new LikeActivity();
                $likeActivity->set('actor', $actor->uri)
                    ->set('object', $comment->uri);
    
                $activityId = model('ActivityModel')
                    ->newActivity(
                        'Like',
                        $actor->id,
                        null,
                        null,
                        $likeActivity->toJSON(),
                        $comment->created_at,
                        'queued',
                    );
    
                $likeActivity->set('id', url_to('activity', $actor->username, $activityId));
    
                model('ActivityModel')
                    ->update($activityId, [
                        'payload' => $likeActivity->toJSON(),
                    ]);
            }
    
            $this->db->transComplete();
        }
    
        public function removeLike(Actor $actor, EpisodeComment $comment, bool $registerActivity = true): void
        {
            $this->db->transStart();
    
            (new EpisodeCommentModel())
                ->where('id', service('uuid') ->fromString($comment->id) ->getBytes())
                ->decrement('likes_count');
    
            $this->where([
                'actor_id' => $actor->id,
                'comment_id' => service('uuid')
                    ->fromString($comment->id)
                    ->getBytes(),
            ])
                ->delete();
    
            if ($registerActivity) {
                $undoActivity = new UndoActivity();
                // FIXME: get like activity associated with the deleted like
                $activity = model('ActivityModel')
                    ->where([
                        'type' => 'Like',
                        'actor_id' => $actor->id,
                    ])
                    ->first();
    
                $likeActivity = new LikeActivity();
                $likeActivity
                    ->set('id', url_to('activity', $actor->username, $activity->id))
                    ->set('actor', $actor->uri)
                    ->set('object', $comment->uri);
    
                $undoActivity
                    ->set('actor', $actor->uri)
                    ->set('object', $likeActivity);
    
                $activityId = model('ActivityModel')
                    ->newActivity(
                        'Undo',
                        $actor->id,
                        null,
                        null,
                        $undoActivity->toJSON(),
                        $comment->created_at,
                        'queued',
                    );
    
                $undoActivity->set('id', url_to('activity', $actor->username, $activityId));
    
                model('ActivityModel')
                    ->update($activityId, [
                        'payload' => $undoActivity->toJSON(),
                    ]);
            }
    
            $this->db->transComplete();
        }
    
        /**
         * Adds or removes likes from database
         */
        public function toggleLike(Actor $actor, EpisodeComment $comment): void
        {
            if (
                $this->where([
                    'actor_id' => $actor->id,
                    'comment_id' => service('uuid')
                        ->fromString($comment->id)
                        ->getBytes(),
                ])->first()
            ) {
                $this->removeLike($actor, $comment);
            } else {
                $this->addLike($actor, $comment);
            }
        }
    }