Collection updates for 'all' tab
timw4mail/HummingBirdAnimeClient/pipeline/head This commit looks good Details

This commit is contained in:
Timothy Warren 2020-04-30 15:33:16 -04:00
parent bbd375e464
commit a80284a4ee
6 changed files with 164 additions and 13 deletions

View File

@ -0,0 +1,26 @@
<?php
use Phinx\Migration\AbstractMigration;
class AnimeCollectionCleanup extends AbstractMigration
{
public function up()
{
if ($this->hasTable('genre_anime_set_link'))
{
$this->table('genre_anime_set_link')
->rename('anime_set_genre_link')
->update();
}
}
public function down()
{
if ($this->hasTable('anime_set_genre_link'))
{
$this->table('anime_set_genre_link')
->rename('genre_anime_set_link')
->update();
}
}
}

View File

@ -332,4 +332,17 @@ function createPlaceholderImage ($path, ?int $width, ?int $height, $text = 'Imag
imagewebp($pngImage, $path . '/placeholder.webp'); imagewebp($pngImage, $path . '/placeholder.webp');
imagedestroy($pngImage); imagedestroy($pngImage);
}
/**
* Check that there is a value for at least one item in a collection with the specified key
*
* @param array $search
* @param string $key
* @return bool
*/
function col_not_empty(array $search, string $key): bool
{
$items = array_filter(array_column($search, $key), fn ($x) => ( ! empty($x)));
return count($items) > 0;
} }

View File

@ -101,12 +101,10 @@ final class AnimeCollection extends BaseController {
'list' => 'list' 'list' => 'list'
]; ];
$data = $this->animeCollectionModel->getCollection();
$this->outputHTML('collection/' . $viewMap[$view], [ $this->outputHTML('collection/' . $viewMap[$view], [
'title' => $this->config->get('whose_list') . "'s Anime Collection", 'title' => $this->config->get('whose_list') . "'s Anime Collection",
'sections' => $data, 'sections' => $this->animeCollectionModel->getCollection(),
'genres' => $this->animeCollectionModel->getGenreList() 'all' => $this->animeCollectionModel->getFlatCollection(),
]); ]);
} }
@ -233,6 +231,13 @@ final class AnimeCollection extends BaseController {
$this->redirect('/anime-collection/view', 303); $this->redirect('/anime-collection/view', 303);
} }
/**
* Update a collection item
*
* @param $data
* @throws ContainerException
* @throws NotFoundException
*/
protected function update($data): void protected function update($data): void
{ {
if (array_key_exists('hummingbird_id', $data)) if (array_key_exists('hummingbird_id', $data))

View File

@ -69,6 +69,47 @@ final class AnimeCollection extends Collection {
return $collection; return $collection;
} }
/**
* Get the collection from the database
*
* @return array
*/
public function getFlatCollection(): array
{
if ( ! $this->validDatabase)
{
return [];
}
$query = $this->db->select('a.hummingbird_id, slug, title, alternate_title, show_type,
age_rating, episode_count, episode_length, cover_image, notes')
->from('anime_set a')
->orderBy('title')
->get();
// Add genres associated with each item
$rows = $query->fetchAll(PDO::FETCH_ASSOC);
$genres = $this->getGenreList();
$media = $this->getMediaList();
foreach($rows as &$row)
{
$id = $row['hummingbird_id'];
$row['genres'] = array_key_exists($id, $genres)
? $genres[$id]
: [];
$row['media'] = array_key_exists($id, $media)
? $media[$id]
: [];
sort($row['genres']);
}
return $rows;
}
/** /**
* Get list of media types * Get list of media types
* *
@ -262,7 +303,7 @@ final class AnimeCollection extends Collection {
$this->db->beginTransaction(); $this->db->beginTransaction();
$this->db->where('hummingbird_id', $data['hummingbird_id']) $this->db->where('hummingbird_id', $data['hummingbird_id'])
->delete('genre_anime_set_link'); ->delete('anime_set_genre_link');
$this->db->where('hummingbird_id', $data['hummingbird_id']) $this->db->where('hummingbird_id', $data['hummingbird_id'])
->delete('anime_set_media_link'); ->delete('anime_set_media_link');
@ -361,7 +402,7 @@ final class AnimeCollection extends Collection {
try try
{ {
$this->db->select('hummingbird_id, genre') $this->db->select('hummingbird_id, genre')
->from('genre_anime_set_link gl') ->from('anime_set_genre_link gl')
->join('genres g', 'g.id=gl.genre_id', 'left'); ->join('genres g', 'g.id=gl.genre_id', 'left');
@ -402,6 +443,68 @@ final class AnimeCollection extends Collection {
return $output; return $output;
} }
/**
* Get media for anime collection items
*
* @param array $filter
* @return array
*/
public function getMediaList(array $filter = []): array
{
if ($this->validDatabase === FALSE)
{
return [];
}
$output = [];
// Catch the missing table PDOException
// so that the collection does not show an
// error by default
try
{
$this->db->select('m.type as media, hummingbird_id')
->from('anime_set_media_link ml')
->join('media m', 'm.id=ml.media_id', 'left');
if ( ! empty($filter))
{
$this->db->whereIn('hummingbird_id', $filter);
}
$query = $this->db->orderBy('hummingbird_id')
->orderBy('media')
->get();
foreach ($query->fetchAll(PDO::FETCH_ASSOC) as $row)
{
$id = $row['hummingbird_id'];
$media = $row['media'];
// Empty genre names aren't useful
if (empty($media))
{
continue;
}
if (array_key_exists($id, $output))
{
$output[$id][] = $media;
}
else
{
$output[$id] = [$media];
}
}
}
catch (PDOException $e) {}
$this->db->resetQuery();
return $output;
}
private function updateMediaLink(string $animeId, array $media): void private function updateMediaLink(string $animeId, array $media): void
{ {
$this->db->beginTransaction(); $this->db->beginTransaction();
@ -469,7 +572,11 @@ final class AnimeCollection extends Collection {
if ( ! empty($linksToInsert)) if ( ! empty($linksToInsert))
{ {
$this->db->insertBatch('genre_anime_set_link', $linksToInsert); try
{
$this->db->insertBatch('anime_set_genre_link', $linksToInsert);
}
catch (PDOException $e) {}
} }
} }
@ -554,7 +661,7 @@ final class AnimeCollection extends Collection {
$links = []; $links = [];
$query = $this->db->select('hummingbird_id, genre_id') $query = $this->db->select('hummingbird_id, genre_id')
->from('genre_anime_set_link') ->from('anime_set_genre_link')
->get(); ->get();
foreach ($query->fetchAll(PDO::FETCH_ASSOC) as $link) foreach ($query->fetchAll(PDO::FETCH_ASSOC) as $link)

View File

@ -98,12 +98,12 @@ class Config extends AbstractType {
/** /**
* @var bool * @var bool
*/ */
public bool $show_anime_collection = FALSE; public $show_anime_collection = FALSE;
/** /**
* @var bool * @var bool
*/ */
public bool $show_manga_collection = FALSE; public $show_manga_collection = FALSE;
/** /**
* CSS theme: light, dark, or auto-switching * CSS theme: light, dark, or auto-switching

View File

@ -21,7 +21,7 @@ namespace Aviat\AnimeClient\Types;
*/ */
class FormItem extends AbstractType { class FormItem extends AbstractType {
/** /**
* @var string * @var string|int
*/ */
public $id; public $id;
@ -31,9 +31,9 @@ class FormItem extends AbstractType {
public ?string $anilist_item_id; public ?string $anilist_item_id;
/** /**
* @var string * @var string|int
*/ */
public ?string $mal_id; public $mal_id;
/** /**
* @var FormItemData * @var FormItemData