diff --git a/src/Domain/Movie/History/MovieHistoryApi.php b/src/Domain/Movie/History/MovieHistoryApi.php index a8a28cf5..c237c03d 100644 --- a/src/Domain/Movie/History/MovieHistoryApi.php +++ b/src/Domain/Movie/History/MovieHistoryApi.php @@ -74,7 +74,7 @@ public function fetchActors( public function fetchAveragePersonalRating(int $userId) : float { - return round($this->movieRepository->fetchPersonalRating($userId), 1); + return round($this->movieRepository->fetchAveragePersonalRating($userId), 1); } public function fetchAveragePlaysPerDay(int $userId) : float diff --git a/src/Domain/Movie/MovieApi.php b/src/Domain/Movie/MovieApi.php index 4fb9a6bc..b51e86e0 100644 --- a/src/Domain/Movie/MovieApi.php +++ b/src/Domain/Movie/MovieApi.php @@ -402,10 +402,18 @@ public function updateUserRating(int $movieId, int $userId, ?PersonalRating $rat return; } - if ($this->repository->updateUserRating($movieId, $userId, $rating) > 0) { + $currentRating = $this->repository->findPersonalMovieRating($movieId, $userId); + + if ($currentRating === null) { + $this->repository->insertUserRating($movieId, $userId, $rating); + + return; + } + + if ($currentRating->isEqual($rating) === true) { return; } - $this->repository->insertUserRating($movieId, $userId, $rating); + $this->repository->updateUserRating($movieId, $userId, $rating); } } diff --git a/src/Domain/Movie/MovieRepository.php b/src/Domain/Movie/MovieRepository.php index ff902f7a..17a9be6a 100644 --- a/src/Domain/Movie/MovieRepository.php +++ b/src/Domain/Movie/MovieRepository.php @@ -176,6 +176,16 @@ public function fetchAllOrderedByLastUpdatedAtTmdbAsc(?int $limit = null) : \Tra return $this->dbConnection->prepare($query)->executeQuery()->iterateAssociative(); } + public function fetchAveragePersonalRating(int $userId) : float + { + return (float)$this->dbConnection->fetchFirstColumn( + 'SELECT AVG(rating) + FROM movie_user_rating + WHERE user_id = ?', + [$userId], + )[0]; + } + public function fetchAverageRuntime(int $userId) : float { return (float)$this->dbConnection->executeQuery( @@ -439,16 +449,6 @@ public function fetchMoviesByProductionCompany(int $productionCompanyId, int $us ); } - public function fetchPersonalRating(int $userId) : float - { - return (float)$this->dbConnection->fetchFirstColumn( - 'SELECT AVG(rating) - FROM movie_user_rating - WHERE user_id = ?', - [$userId], - )[0]; - } - public function fetchPlaysForMovieIdAtDate(int $movieId, int $userId, Date $watchedAt) : int { $result = $this->dbConnection->fetchOne( @@ -718,6 +718,16 @@ public function findByTraktId(TraktId $traktId) : ?MovieEntity return $data === false ? null : MovieEntity::createFromArray($data); } + public function findPersonalMovieRating(int $movieId, int $userId) : ?PersonalRating + { + $data = $this->dbConnection->fetchOne( + 'SELECT * FROM `movie_user_rating` WHERE movie_id = ? AND user_id = ?', + [$movieId, $userId], + ); + + return $data === false ? null : PersonalRating::create($data); + } + public function findPlaysForMovieIdAndDate(int $movieId, int $userId, Date $watchedAt) : ?int { $result = $this->dbConnection->fetchFirstColumn( @@ -744,14 +754,9 @@ public function findUserRating(int $movieId, int $userId) : ?PersonalRating public function insertUserRating(int $movieId, int $userId, PersonalRating $rating) : void { - $this->dbConnection->insert( - 'movie_user_rating', - [ - 'movie_id' => $movieId, - 'user_id' => $userId, - 'rating' => $rating->asInt(), - 'created_at' => (string)DateTime::create(), - ], + $this->dbConnection->executeQuery( + 'INSERT INTO movie_user_rating (movie_id, user_id, rating, created_at) VALUES (?, ?, ?, ?)', + [$movieId, $userId, $rating->asInt(), (string)DateTime::create()], ); } @@ -808,18 +813,11 @@ public function updateTraktId(int $id, TraktId $traktId) : void $this->dbConnection->update('movie', ['trakt_id' => $traktId->asInt(), 'updated_at' => (string)DateTime::create()], ['id' => $id]); } - public function updateUserRating(int $movieId, int $userId, PersonalRating $personalRating) : int + public function updateUserRating(int $movieId, int $userId, PersonalRating $rating) : void { - return (int)$this->dbConnection->update( - 'movie_user_rating', - [ - 'rating' => $personalRating->asInt() - ], - [ - 'movie_id' => $movieId, - 'user_id' => $userId, - 'updated_at' => (string)DateTime::create(), - ], + $this->dbConnection->executeQuery( + 'UPDATE movie_user_rating SET rating = ?, updated_at = ? WHERE movie_id = ? AND user_id = ?', + [$rating->asInt(), (string)DateTime::create(), $movieId, $userId], ); } diff --git a/src/ValueObject/PersonalRating.php b/src/ValueObject/PersonalRating.php index 30c06bfa..4f8365f2 100644 --- a/src/ValueObject/PersonalRating.php +++ b/src/ValueObject/PersonalRating.php @@ -29,4 +29,9 @@ public function asInt() : int { return $this->rating; } + + public function isEqual(PersonalRating $personalRating) : bool + { + return $this->asInt() === $personalRating->asInt(); + } } diff --git a/tests/unit/ValueObject/PersonalRatingTest.php b/tests/unit/ValueObject/PersonalRatingTest.php index ddf130be..b332a64f 100644 --- a/tests/unit/ValueObject/PersonalRatingTest.php +++ b/tests/unit/ValueObject/PersonalRatingTest.php @@ -32,6 +32,17 @@ public function testCreateThrowsExceptionIfPersonalRatingIsLowerThanOne() : void PersonalRating::create(0); } + public function testIsEqual() : void + { + $subject = PersonalRating::create(5); + + $equalToSubject = PersonalRating::create(5); + $notEqualToSubject = PersonalRating::create(4); + + self::assertTrue($subject->isEqual($equalToSubject)); + self::assertFalse($subject->isEqual($notEqualToSubject)); + } + public function testToString() : void { $subject = PersonalRating::create(5);