db = \Query($this->db_config['collection']); $this->anime_model = new AnimeModel($config); // Is database valid? If not, set a flag so the // app can be run without a valid database $db_file = file_get_contents($this->db_config['collection']['file']); $this->valid_database = (strpos($db_file, 'SQLite format 3') === 0); // Do an import if an import file exists $this->json_import(); } /** * Get genres for anime collection items * * @param array $filter * @return array */ public function get_genre_list($filter=[]) { $this->db->select('hummingbird_id, genre') ->from('genre_anime_set_link gl') ->join('genres g', 'g.id=gl.genre_id', 'left'); if ( ! empty($filter)) $this->db->where_in('hummingbird_id', $filter); $query = $this->db->order_by('hummingbird_id') ->order_by('genre') ->get(); $output = []; foreach($query->fetchAll(\PDO::FETCH_ASSOC) as $row) { $id = $row['hummingbird_id']; $genre = $row['genre']; // Empty genre names aren't useful if (empty($genre)) continue; if (array_key_exists($id, $output)) { array_push($output[$id], $genre); } else { $output[$id] = [$genre]; } } return $output; } /** * Get collection from the database, and organize by media type * * @return array */ public function get_collection() { $raw_collection = $this->_get_collection(); $collection = []; foreach($raw_collection as $row) { if (array_key_exists($row['media'], $collection)) { $collection[$row['media']][] = $row; } else { $collection[$row['media']] = [$row]; } } return $collection; } /** * Get list of media types * * @return array */ public function get_media_type_list() { $output = array(); $query = $this->db->select('id, type') ->from('media') ->get(); foreach($query->fetchAll(\PDO::FETCH_ASSOC) as $row) { $output[$row['id']] = $row['type']; } return $output; } /** * Get item from collection for editing * * @param int $id * @return array */ public function get_collection_entry($id) { $query = $this->db->from('anime_set') ->where('hummingbird_id', (int) $id) ->get(); return $query->fetch(\PDO::FETCH_ASSOC); } /** * Get full collection from the database * * @return array */ private function _get_collection() { if ( ! $this->valid_database) return []; $query = $this->db->select('hummingbird_id, slug, title, alternate_title, show_type, age_rating, episode_count, episode_length, cover_image, notes, media.type as media') ->from('anime_set a') ->join('media', 'media.id=a.media_id', 'inner') ->order_by('media') ->order_by('title') ->get(); return $query->fetchAll(\PDO::FETCH_ASSOC); } /** * Add an item to the anime collection * * @param array $data * @return void */ public function add($data) { $anime = (object) $this->anime_model->get_anime($data['id']); $this->db->set([ 'hummingbird_id' => $data['id'], 'slug' => $anime->slug, 'title' => $anime->title, 'alternate_title' => $anime->alternate_title, 'show_type' => $anime->show_type, 'age_rating' => $anime->age_rating, 'cover_image' => basename($this->get_cached_image($anime->cover_image, $anime->slug, 'anime')), 'episode_count' => $anime->episode_count, 'episode_length' => $anime->episode_length, 'media_id' => $data['media_id'], 'notes' => $data['notes'] ])->insert('anime_set'); $this->update_genre($data['id']); } /** * Update a collection item * * @param array $data * @return void */ public function update($data) { // If there's no id to update, don't update if ( ! array_key_exists('hummingbird_id', $data)) return; $id = $data['hummingbird_id']; unset($data['hummingbird_id']); $this->db->set($data) ->where('hummingbird_id', $id) ->update('anime_set'); } /** * Get the details of a collection item * * @param int $hummingbird_id * @return array */ public function get($hummingbird_id) { $query = $this->db->from('anime_set') ->where('hummingbird_id', $hummingbird_id) ->get(); return $query->fetch(\PDO::FETCH_ASSOC); } /** * Import anime into collection from a json file * * @return void */ private function json_import() { if ( ! file_exists('import.json')) return; if ( ! $this->valid_database) return; $anime = json_decode(file_get_contents("import.json")); foreach($anime as $item) { $this->db->set([ 'hummingbird_id' => $item->id, 'slug' => $item->slug, 'title' => $item->title, 'alternate_title' => $item->alternate_title, 'show_type' => $item->show_type, 'age_rating' => $item->age_rating, 'cover_image' => basename($this->get_cached_image($item->cover_image, $item->slug, 'anime')), 'episode_count' => $item->episode_count, 'episode_length' => $item->episode_length ])->insert('anime_set'); } // Delete the import file unlink('import.json'); // Update genre info $this->update_genres(); } /** * Update genre information for selected anime * * @return void */ private function update_genre($anime_id) { $genre_info = $this->get_genre_data(); extract($genre_info); // Get api information $anime = $this->anime_model->get_anime($anime_id); foreach($anime['genres'] as $genre) { // Add genres that don't currently exist if ( ! in_array($genre['name'], $genres)) { $this->db->set('genre', $genre['name']) ->insert('genres'); $genres[] = $genre['name']; } // Update link table // Get id of genre to put in link table $flipped_genres = array_flip($genres); $insert_array = [ 'hummingbird_id' => $anime['id'], 'genre_id' => $flipped_genres[$genre['name']] ]; if (array_key_exists($anime['id'], $links)) { if ( ! in_array($flipped_genres[$genre['name']], $links[$anime['id']])) { $this->db->set($insert_array)->insert('genre_anime_set_link'); } } else { $this->db->set($insert_array)->insert('genre_anime_set_link'); } } } /** * Get list of existing genres * * @return array */ private function get_genre_data() { $genres = []; $links = []; // Get existing genres $query = $this->db->select('id, genre') ->from('genres') ->get(); foreach($query->fetchAll(\PDO::FETCH_ASSOC) as $genre) { $genres[$genre['id']] = $genre['genre']; } // Get existing link table entries $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)) { $links[$link['hummingbird_id']][] = $link['genre_id']; } else { $links[$link['hummingbird_id']] = [$link['genre_id']]; } } return [ 'genres' => $genres, 'links' => $links ]; } /** * Update genre information for the entire collection * * @return void */ private function update_genres() { // Get the anime collection $collection = $this->_get_collection(); foreach($collection as $anime) { // Get api information $this->update_genre($anime['hummingbird_id']); } } } // End of AnimeCollectionModel.php