From 4de92a359137e086a43fc8da388872307396a4db Mon Sep 17 00:00:00 2001 From: Timothy J Warren Date: Wed, 10 Jul 2019 10:20:37 -0400 Subject: [PATCH] No more genre-related database errors, and other collection improvements --- app/appConf/routes.php | 7 ++ app/views/collection/edit.php | 2 +- src/Controller/AnimeCollection.php | 51 ++++++++--- src/Model/Anime.php | 6 +- src/Model/AnimeCollection.php | 135 ++++++++++++++++++++++------- src/Model/Collection.php | 4 +- 6 files changed, 159 insertions(+), 46 deletions(-) diff --git a/app/appConf/routes.php b/app/appConf/routes.php index 20f14a0d..ba17aa55 100644 --- a/app/appConf/routes.php +++ b/app/appConf/routes.php @@ -110,6 +110,7 @@ $routes = [ ], 'anime.collection.view' => [ 'path' => '/anime-collection/view{/view}', + 'action' => 'view', 'tokens' => [ 'view' => ALPHA_SLUG_PATTERN, ], @@ -119,6 +120,12 @@ $routes = [ 'action' => 'delete', 'verb' => 'post', ], + 'anime.collection.redirect' => [ + 'path' => '/anime-collection', + ], + 'anime.collection.redirect2' => [ + 'path' => '/anime-collection/', + ], // --------------------------------------------------------------------- // Manga Collection Routes // --------------------------------------------------------------------- diff --git a/app/views/collection/edit.php b/app/views/collection/edit.php index c397eadc..1a56900b 100644 --- a/app/views/collection/edit.php +++ b/app/views/collection/edit.php @@ -26,7 +26,7 @@ diff --git a/src/Controller/AnimeCollection.php b/src/Controller/AnimeCollection.php index 3e0e382f..1aa86676 100644 --- a/src/Controller/AnimeCollection.php +++ b/src/Controller/AnimeCollection.php @@ -61,6 +61,11 @@ final class AnimeCollection extends BaseController { ]); } + public function index(): void + { + $this->redirect('/anime-collection/view', 303); + } + /** * Search for anime * @@ -83,7 +88,7 @@ final class AnimeCollection extends BaseController { * @throws \InvalidArgumentException * @return void */ - public function index($view): void + public function view($view): void { $viewMap = [ '' => 'cover', @@ -145,13 +150,21 @@ final class AnimeCollection extends BaseController { $data = $this->request->getParsedBody(); if (array_key_exists('hummingbird_id', $data)) { - // @TODO verify data was updated correctly $this->animeCollectionModel->update($data); - $this->setFlashMessage('Successfully updated collection item.', 'success'); + + // Verify the item was actually updated + if ($this->animeCollectionModel->wasUpdated($data)) + { + $this->setFlashMessage('Successfully updated collection item.', 'success'); + } + else + { + $this->setFlashMessage('Failed to update collection item.', 'error'); + } } else { - $this->setFlashMessage('Failed to update collection item', 'error'); + $this->setFlashMessage('No item id to update. Update failed.', 'error'); } $this->sessionRedirect(); @@ -175,21 +188,26 @@ final class AnimeCollection extends BaseController { // Check for existing entry if ($this->animeCollectionModel->get($data['id']) !== FALSE) { - $this->setFlashMessage('Anime already exists, can not create duplicate', 'info'); + // Redirect to the edit screen, because that's probably what you want! + $this->setFlashMessage('Anime already exists, update instead.', 'info'); + $this->redirect("/anime-collection/edit/{$data['id']}", 303); + return; } - else + + $this->animeCollectionModel->add($data); + + // Verify the item was added + if ($this->animeCollectionModel->wasAdded($data)) { - // @TODO actually verify that collection item was added - $this->animeCollectionModel->add($data); $this->setFlashMessage('Successfully added collection item', 'success'); + $this->sessionRedirect(); } } else { $this->setFlashMessage('Failed to add collection item.', 'error'); + $this->redirect('/anime-collection/add', 303); } - - $this->sessionRedirect(); } /** @@ -204,12 +222,21 @@ final class AnimeCollection extends BaseController { $data = $this->request->getParsedBody(); if ( ! array_key_exists('hummingbird_id', $data)) { + $this->setFlashMessage("Can't delete item that doesn't exist", 'error'); $this->redirect('/anime-collection/view', 303); } - // @TODO verify that item was actually deleted $this->animeCollectionModel->delete($data); - $this->setFlashMessage('Successfully removed anime from collection.', 'success'); + + // Verify that item was actually deleted + if ($this->animeCollectionModel->wasDeleted($data)) + { + $this->setFlashMessage('Successfully removed anime from collection.', 'success'); + } + else + { + $this->setFlashMessage('Failed to delete item from collection.', 'error'); + } $this->redirect('/anime-collection/view', 303); } diff --git a/src/Model/Anime.php b/src/Model/Anime.php index dfad39b7..c33d3766 100644 --- a/src/Model/Anime.php +++ b/src/Model/Anime.php @@ -166,7 +166,7 @@ class Anime extends API { $requester = new ParallelAPIRequest(); $requester->addRequest($this->kitsuModel->createListItem($data), 'kitsu'); - if (array_key_exists('mal_id', $data) && $this->anilistEnabled) + if ($data['mal_id'] !== null && $this->anilistEnabled) { $requester->addRequest($this->anilistModel->createListItem($data, 'ANIME'), 'anilist'); } @@ -189,7 +189,7 @@ class Anime extends API { $array = $data->toArray(); - if (array_key_exists('mal_id', $array) && $this->anilistEnabled) + if ($array['mal_id'] !== null && $this->anilistEnabled) { $requester->addRequest($this->anilistModel->incrementListItem($data, 'ANIME'), 'anilist'); } @@ -218,7 +218,7 @@ class Anime extends API { $array = $data->toArray(); - if (array_key_exists('mal_id', $array) && $this->anilistEnabled) + if ($array['mal_id'] !== null && $this->anilistEnabled) { $requester->addRequest($this->anilistModel->updateListItem($data, 'ANIME'), 'anilist'); } diff --git a/src/Model/AnimeCollection.php b/src/Model/AnimeCollection.php index c69888c6..100739f5 100644 --- a/src/Model/AnimeCollection.php +++ b/src/Model/AnimeCollection.php @@ -140,7 +140,7 @@ final class AnimeCollection extends Collection { // Check that the anime doesn't already exist $existing = $this->get($id); - if ($existing === FALSE) + if ( ! empty($existing)) { return; } @@ -160,7 +160,20 @@ final class AnimeCollection extends Collection { 'notes' => $data['notes'] ])->insert('anime_set'); - $this->updateGenre($data['id']); + $this->updateGenre($id); + } + + /** + * Verify that an item was added + * + * @param $data + * @return bool + */ + public function wasAdded($data): bool + { + $row = $this->get($data['id']); + + return ! empty($row); } /** @@ -183,6 +196,30 @@ final class AnimeCollection extends Collection { $this->db->set($data) ->where('hummingbird_id', $id) ->update('anime_set'); + + // Just in case, also update genres + $this->updateGenre($id); + } + + /** + * Verify that the collection item was updated + * + * @param $data + * @return bool + */ + public function wasUpdated($data): bool + { + $row = $this->get($data['hummingbird_id']); + + foreach ($data as $key => $value) + { + if ((string)$row[$key] !== (string)$value) + { + return FALSE; + } + } + + return TRUE; } /** @@ -206,6 +243,13 @@ final class AnimeCollection extends Collection { ->delete('anime_set'); } + public function wasDeleted($data): bool + { + $animeRow = $this->get($data['hummingbird_id']); + + return empty($animeRow); + } + /** * Get the details of a collection item * @@ -264,7 +308,8 @@ final class AnimeCollection extends Collection { if (array_key_exists($id, $output)) { $output[$id][] = $genre; - } else + } + else { $output[$id] = [$genre]; } @@ -272,6 +317,8 @@ final class AnimeCollection extends Collection { } catch (PDOException $e) {} + $this->db->reset_query(); + return $output; } @@ -283,44 +330,68 @@ final class AnimeCollection extends Collection { */ private function updateGenre($animeId): void { + // Get api information + $anime = $this->animeModel->getAnimeById($animeId); + + $this->addNewGenres($anime['genres']); + $genreInfo = $this->getGenreData(); $genres = $genreInfo['genres']; $links = $genreInfo['links']; - // Get api information - $anime = $this->animeModel->getAnimeById($animeId); + $linksToInsert = []; - foreach ($anime['genres'] as $genre) + foreach ($anime['genres'] as $animeGenre) { - // Add genres that don't currently exist - if ( ! \in_array($genre, $genres, TRUE)) - { - $this->db->set('genre', $genre) - ->insert('genres'); - - $genres[] = $genre; - } - // Update link table // Get id of genre to put in link table $flippedGenres = array_flip($genres); + $genreId = $flippedGenres[$animeGenre]; - $insertArray = [ - 'hummingbird_id' => $animeId, - 'genre_id' => $flippedGenres[$genre] + $animeLinks = $links[$animeId] ?? []; + + if ( ! \in_array($flippedGenres[$animeGenre], $animeLinks, TRUE)) + { + $linksToInsert[] = [ + 'hummingbird_id' => $animeId, + 'genre_id' => $genreId, + ]; + } + } + + if ( ! empty($linksToInsert)) + { + // dump($linksToInsert); + $this->db->insertBatch('genre_anime_set_link', $linksToInsert); + } + } + + /** + * Add genres to the database + * + * @param array $genres + */ + private function addNewGenres(array $genres): void + { + $existingGenres = $this->getExistingGenres(); + $newGenres = array_diff($genres, $existingGenres); + + $insert = []; + + foreach ($newGenres as $genre) + { + $insert[] = [ + 'genre' => $genre, ]; + } - if (array_key_exists($animeId, $links)) - { - if ( ! \in_array($flippedGenres[$genre], $links[$animeId], TRUE)) - { - $this->db->set($insertArray)->insert('genre_anime_set_link'); - } - } - else - { - $this->db->set($insertArray)->insert('genre_anime_set_link'); - } + try + { + $this->db->insert_batch('genres', $insert); + } + catch (PDOException $e) + { + dump($e); } } @@ -345,11 +416,14 @@ final class AnimeCollection extends Collection { $query = $this->db->select('id, genre') ->from('genres') ->get(); + foreach ($query->fetchAll(PDO::FETCH_ASSOC) as $genre) { $genres[$genre['id']] = $genre['genre']; } + $this->db->reset_query(); + return $genres; } @@ -360,6 +434,7 @@ final class AnimeCollection extends Collection { $query = $this->db->select('hummingbird_id, genre_id') ->from('genre_anime_set_link') ->get(); + foreach ($query->fetchAll(PDO::FETCH_ASSOC) as $link) { if (array_key_exists($link['hummingbird_id'], $links)) @@ -371,6 +446,8 @@ final class AnimeCollection extends Collection { } } + $this->db->reset_query(); + return $links; } } diff --git a/src/Model/Collection.php b/src/Model/Collection.php index 44a33e4f..ea99f191 100644 --- a/src/Model/Collection.php +++ b/src/Model/Collection.php @@ -19,6 +19,8 @@ namespace Aviat\AnimeClient\Model; use Aviat\Ion\Di\ContainerInterface; use PDOException; +use function Query; + /** * Base model for anime and manga collections */ @@ -47,7 +49,7 @@ class Collection extends DB { try { - $this->db = \Query($this->dbConfig); + $this->db = Query($this->dbConfig); $this->validDatabase = TRUE; } catch (PDOException $e) {}