No more genre-related database errors, and other collection improvements

This commit is contained in:
Timothy Warren 2019-07-10 10:20:37 -04:00
parent 62781355b1
commit 4de92a3591
6 changed files with 159 additions and 46 deletions

View File

@ -110,6 +110,7 @@ $routes = [
], ],
'anime.collection.view' => [ 'anime.collection.view' => [
'path' => '/anime-collection/view{/view}', 'path' => '/anime-collection/view{/view}',
'action' => 'view',
'tokens' => [ 'tokens' => [
'view' => ALPHA_SLUG_PATTERN, 'view' => ALPHA_SLUG_PATTERN,
], ],
@ -119,6 +120,12 @@ $routes = [
'action' => 'delete', 'action' => 'delete',
'verb' => 'post', 'verb' => 'post',
], ],
'anime.collection.redirect' => [
'path' => '/anime-collection',
],
'anime.collection.redirect2' => [
'path' => '/anime-collection/',
],
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
// Manga Collection Routes // Manga Collection Routes
// --------------------------------------------------------------------- // ---------------------------------------------------------------------

View File

@ -26,7 +26,7 @@
<td class="align-left"> <td class="align-left">
<select name="media_id" id="media_id"> <select name="media_id" id="media_id">
<?php foreach($media_items as $id => $name): ?> <?php foreach($media_items as $id => $name): ?>
<option <?= $item['media_id'] === (string)$id ? 'selected="selected"' : '' ?> value="<?= $id ?>"><?= $name ?></option> <option <?= $item['media_id'] === $id ? 'selected="selected"' : '' ?> value="<?= $id ?>"><?= $name ?></option>
<?php endforeach ?> <?php endforeach ?>
</select> </select>
</td> </td>

View File

@ -61,6 +61,11 @@ final class AnimeCollection extends BaseController {
]); ]);
} }
public function index(): void
{
$this->redirect('/anime-collection/view', 303);
}
/** /**
* Search for anime * Search for anime
* *
@ -83,7 +88,7 @@ final class AnimeCollection extends BaseController {
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
* @return void * @return void
*/ */
public function index($view): void public function view($view): void
{ {
$viewMap = [ $viewMap = [
'' => 'cover', '' => 'cover',
@ -145,13 +150,21 @@ final class AnimeCollection extends BaseController {
$data = $this->request->getParsedBody(); $data = $this->request->getParsedBody();
if (array_key_exists('hummingbird_id', $data)) if (array_key_exists('hummingbird_id', $data))
{ {
// @TODO verify data was updated correctly
$this->animeCollectionModel->update($data); $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 else
{ {
$this->setFlashMessage('Failed to update collection item', 'error'); $this->setFlashMessage('No item id to update. Update failed.', 'error');
} }
$this->sessionRedirect(); $this->sessionRedirect();
@ -175,21 +188,26 @@ final class AnimeCollection extends BaseController {
// Check for existing entry // Check for existing entry
if ($this->animeCollectionModel->get($data['id']) !== FALSE) 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->setFlashMessage('Successfully added collection item', 'success');
$this->sessionRedirect();
} }
} }
else else
{ {
$this->setFlashMessage('Failed to add collection item.', 'error'); $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(); $data = $this->request->getParsedBody();
if ( ! array_key_exists('hummingbird_id', $data)) if ( ! array_key_exists('hummingbird_id', $data))
{ {
$this->setFlashMessage("Can't delete item that doesn't exist", 'error');
$this->redirect('/anime-collection/view', 303); $this->redirect('/anime-collection/view', 303);
} }
// @TODO verify that item was actually deleted
$this->animeCollectionModel->delete($data); $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); $this->redirect('/anime-collection/view', 303);
} }

View File

@ -166,7 +166,7 @@ class Anime extends API {
$requester = new ParallelAPIRequest(); $requester = new ParallelAPIRequest();
$requester->addRequest($this->kitsuModel->createListItem($data), 'kitsu'); $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'); $requester->addRequest($this->anilistModel->createListItem($data, 'ANIME'), 'anilist');
} }
@ -189,7 +189,7 @@ class Anime extends API {
$array = $data->toArray(); $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'); $requester->addRequest($this->anilistModel->incrementListItem($data, 'ANIME'), 'anilist');
} }
@ -218,7 +218,7 @@ class Anime extends API {
$array = $data->toArray(); $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'); $requester->addRequest($this->anilistModel->updateListItem($data, 'ANIME'), 'anilist');
} }

View File

@ -140,7 +140,7 @@ final class AnimeCollection extends Collection {
// Check that the anime doesn't already exist // Check that the anime doesn't already exist
$existing = $this->get($id); $existing = $this->get($id);
if ($existing === FALSE) if ( ! empty($existing))
{ {
return; return;
} }
@ -160,7 +160,20 @@ final class AnimeCollection extends Collection {
'notes' => $data['notes'] 'notes' => $data['notes']
])->insert('anime_set'); ])->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) $this->db->set($data)
->where('hummingbird_id', $id) ->where('hummingbird_id', $id)
->update('anime_set'); ->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'); ->delete('anime_set');
} }
public function wasDeleted($data): bool
{
$animeRow = $this->get($data['hummingbird_id']);
return empty($animeRow);
}
/** /**
* Get the details of a collection item * Get the details of a collection item
* *
@ -264,7 +308,8 @@ final class AnimeCollection extends Collection {
if (array_key_exists($id, $output)) if (array_key_exists($id, $output))
{ {
$output[$id][] = $genre; $output[$id][] = $genre;
} else }
else
{ {
$output[$id] = [$genre]; $output[$id] = [$genre];
} }
@ -272,6 +317,8 @@ final class AnimeCollection extends Collection {
} }
catch (PDOException $e) {} catch (PDOException $e) {}
$this->db->reset_query();
return $output; return $output;
} }
@ -283,44 +330,68 @@ final class AnimeCollection extends Collection {
*/ */
private function updateGenre($animeId): void private function updateGenre($animeId): void
{ {
// Get api information
$anime = $this->animeModel->getAnimeById($animeId);
$this->addNewGenres($anime['genres']);
$genreInfo = $this->getGenreData(); $genreInfo = $this->getGenreData();
$genres = $genreInfo['genres']; $genres = $genreInfo['genres'];
$links = $genreInfo['links']; $links = $genreInfo['links'];
// Get api information $linksToInsert = [];
$anime = $this->animeModel->getAnimeById($animeId);
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 // Update link table
// Get id of genre to put in link table // Get id of genre to put in link table
$flippedGenres = array_flip($genres); $flippedGenres = array_flip($genres);
$genreId = $flippedGenres[$animeGenre];
$insertArray = [ $animeLinks = $links[$animeId] ?? [];
'hummingbird_id' => $animeId,
'genre_id' => $flippedGenres[$genre] 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)) try
{ {
if ( ! \in_array($flippedGenres[$genre], $links[$animeId], TRUE)) $this->db->insert_batch('genres', $insert);
{ }
$this->db->set($insertArray)->insert('genre_anime_set_link'); catch (PDOException $e)
} {
} dump($e);
else
{
$this->db->set($insertArray)->insert('genre_anime_set_link');
}
} }
} }
@ -345,11 +416,14 @@ final class AnimeCollection extends Collection {
$query = $this->db->select('id, genre') $query = $this->db->select('id, genre')
->from('genres') ->from('genres')
->get(); ->get();
foreach ($query->fetchAll(PDO::FETCH_ASSOC) as $genre) foreach ($query->fetchAll(PDO::FETCH_ASSOC) as $genre)
{ {
$genres[$genre['id']] = $genre['genre']; $genres[$genre['id']] = $genre['genre'];
} }
$this->db->reset_query();
return $genres; return $genres;
} }
@ -360,6 +434,7 @@ final class AnimeCollection extends Collection {
$query = $this->db->select('hummingbird_id, genre_id') $query = $this->db->select('hummingbird_id, genre_id')
->from('genre_anime_set_link') ->from('genre_anime_set_link')
->get(); ->get();
foreach ($query->fetchAll(PDO::FETCH_ASSOC) as $link) foreach ($query->fetchAll(PDO::FETCH_ASSOC) as $link)
{ {
if (array_key_exists($link['hummingbird_id'], $links)) if (array_key_exists($link['hummingbird_id'], $links))
@ -371,6 +446,8 @@ final class AnimeCollection extends Collection {
} }
} }
$this->db->reset_query();
return $links; return $links;
} }
} }

View File

@ -19,6 +19,8 @@ namespace Aviat\AnimeClient\Model;
use Aviat\Ion\Di\ContainerInterface; use Aviat\Ion\Di\ContainerInterface;
use PDOException; use PDOException;
use function Query;
/** /**
* Base model for anime and manga collections * Base model for anime and manga collections
*/ */
@ -47,7 +49,7 @@ class Collection extends DB {
try try
{ {
$this->db = \Query($this->dbConfig); $this->db = Query($this->dbConfig);
$this->validDatabase = TRUE; $this->validDatabase = TRUE;
} }
catch (PDOException $e) {} catch (PDOException $e) {}