mirror of
https://github.com/ceratic/MediaCollectorLibary.git
synced 2026-05-13 23:56:46 +02:00
jellyfin music :)
This commit is contained in:
235
app/Models/MusicAlbum.php
Normal file
235
app/Models/MusicAlbum.php
Normal file
@@ -0,0 +1,235 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
class MusicAlbum extends Model
|
||||
{
|
||||
protected string $table = 'music_albums';
|
||||
protected array $fillable = [
|
||||
'title',
|
||||
'artist_name',
|
||||
'release_date',
|
||||
'genre',
|
||||
'track_count',
|
||||
'total_duration_seconds',
|
||||
'cover_url',
|
||||
'spotify_id',
|
||||
'musicbrainz_id',
|
||||
'is_favorite',
|
||||
'metadata',
|
||||
'artist_id',
|
||||
'source_id'
|
||||
];
|
||||
|
||||
protected array $casts = [
|
||||
'release_date' => 'date',
|
||||
'track_count' => 'int',
|
||||
'total_duration_seconds' => 'int',
|
||||
'is_favorite' => 'bool'
|
||||
];
|
||||
|
||||
public function source()
|
||||
{
|
||||
$stmt = $this->pdo->prepare("SELECT * FROM sources WHERE id = :source_id");
|
||||
$stmt->execute(['source_id' => $this->source_id]);
|
||||
$sourceData = $stmt->fetch(\PDO::FETCH_ASSOC);
|
||||
|
||||
return $sourceData ? new Source($this->pdo, $sourceData) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the artist for this album
|
||||
*/
|
||||
public function artist()
|
||||
{
|
||||
$stmt = $this->pdo->prepare("SELECT * FROM music_artists WHERE id = :artist_id");
|
||||
$stmt->execute(['artist_id' => $this->artist_id]);
|
||||
$artistData = $stmt->fetch(\PDO::FETCH_ASSOC);
|
||||
|
||||
return $artistData ? new MusicArtist($this->pdo, $artistData) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all tracks for this album
|
||||
*/
|
||||
public function tracks()
|
||||
{
|
||||
$stmt = $this->pdo->prepare("
|
||||
SELECT * FROM music_tracks
|
||||
WHERE album_id = :album_id
|
||||
ORDER BY track_number ASC, title ASC
|
||||
");
|
||||
$stmt->execute(['album_id' => $this->id]);
|
||||
return $stmt->fetchAll(\PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle favorite status
|
||||
*/
|
||||
public function toggleFavorite(): bool
|
||||
{
|
||||
return $this->update($this->id, [
|
||||
'is_favorite' => !$this->is_favorite
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get total count of albums with optional filters
|
||||
*/
|
||||
public static function getTotalCount(\PDO $pdo, string $search = '', array $genres = [], array $artists = []): int
|
||||
{
|
||||
$where = [];
|
||||
$params = [];
|
||||
|
||||
$sql = "SELECT COUNT(*) as count FROM music_albums ma JOIN sources s ON ma.source_id = s.id";
|
||||
|
||||
if (!empty($search)) {
|
||||
$where[] = "(ma.title LIKE :search OR ma.artist_name LIKE :search)";
|
||||
$params[':search'] = "%$search%";
|
||||
}
|
||||
|
||||
if (!empty($genres)) {
|
||||
$genreConditions = [];
|
||||
foreach ($genres as $i => $genre) {
|
||||
$param = ":genre_$i";
|
||||
$genreConditions[] = "ma.genre LIKE $param";
|
||||
$params[$param] = "%$genre%";
|
||||
}
|
||||
$where[] = "(" . implode(' OR ', $genreConditions) . ")";
|
||||
}
|
||||
|
||||
if (!empty($artists)) {
|
||||
$artistConditions = [];
|
||||
foreach ($artists as $i => $artist) {
|
||||
$param = ":artist_$i";
|
||||
$artistConditions[] = "ma.artist_name LIKE $param";
|
||||
$params[$param] = "%$artist%";
|
||||
}
|
||||
$where[] = "(" . implode(' OR ', $artistConditions) . ")";
|
||||
}
|
||||
|
||||
if (!empty($where)) {
|
||||
$sql .= " WHERE " . implode(' AND ', $where);
|
||||
}
|
||||
|
||||
$stmt = $pdo->prepare($sql);
|
||||
$stmt->execute($params);
|
||||
|
||||
return (int)$stmt->fetchColumn();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get paginated albums with optional filters
|
||||
*/
|
||||
public static function getAllWithPagination(
|
||||
\PDO $pdo,
|
||||
int $page = 1,
|
||||
int $perPage = 20,
|
||||
string $search = '',
|
||||
array $genres = [],
|
||||
array $artists = [],
|
||||
string $sort = 'title_asc'
|
||||
): array {
|
||||
$offset = ($page - 1) * $perPage;
|
||||
$where = [];
|
||||
$params = [];
|
||||
|
||||
if (!empty($search)) {
|
||||
$where[] = "(title LIKE :search OR artist_name LIKE :search)";
|
||||
$params[':search'] = "%$search%";
|
||||
}
|
||||
|
||||
if (!empty($genres)) {
|
||||
$genreConditions = [];
|
||||
foreach ($genres as $i => $genre) {
|
||||
$param = ":genre$i";
|
||||
$genreConditions[] = "genre LIKE $param";
|
||||
$params[$param] = "%$genre%";
|
||||
}
|
||||
$where[] = "(" . implode(' OR ', $genreConditions) . ")";
|
||||
}
|
||||
|
||||
if (!empty($artists)) {
|
||||
$artistConditions = [];
|
||||
foreach ($artists as $i => $artist) {
|
||||
$param = ":artist$i";
|
||||
$artistConditions[] = "artist_name LIKE $param";
|
||||
$params[$param] = "%$artist%";
|
||||
}
|
||||
$where[] = "(" . implode(' OR ', $artistConditions) . ")";
|
||||
}
|
||||
|
||||
// Determine sort order
|
||||
$orderBy = 'title ASC';
|
||||
switch ($sort) {
|
||||
case 'title_desc':
|
||||
$orderBy = 'title DESC';
|
||||
break;
|
||||
case 'artist_asc':
|
||||
$orderBy = 'artist_name ASC';
|
||||
break;
|
||||
case 'artist_desc':
|
||||
$orderBy = 'artist_name DESC';
|
||||
break;
|
||||
case 'release_asc':
|
||||
$orderBy = 'release_date ASC';
|
||||
break;
|
||||
case 'release_desc':
|
||||
$orderBy = 'release_date DESC';
|
||||
break;
|
||||
}
|
||||
|
||||
$sql = "SELECT ma.*, s.display_name as source_name FROM music_albums ma JOIN sources s ON ma.source_id = s.id";
|
||||
if (!empty($where)) {
|
||||
$sql .= " WHERE " . implode(' AND ', $where);
|
||||
}
|
||||
$sql .= " ORDER BY $orderBy LIMIT :limit OFFSET :offset";
|
||||
|
||||
$stmt = $pdo->prepare($sql);
|
||||
|
||||
// Bind parameters
|
||||
foreach ($params as $key => $value) {
|
||||
$stmt->bindValue($key, $value);
|
||||
}
|
||||
$stmt->bindValue(':limit', $perPage, \PDO::PARAM_INT);
|
||||
$stmt->bindValue(':offset', $offset, \PDO::PARAM_INT);
|
||||
|
||||
$stmt->execute();
|
||||
|
||||
return $stmt->fetchAll(\PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all unique genres from albums
|
||||
*/
|
||||
public static function getAvailableGenres(\PDO $pdo): array
|
||||
{
|
||||
$stmt = $pdo->query("SELECT DISTINCT genre FROM music_albums WHERE genre IS NOT NULL AND genre != '' ORDER BY genre");
|
||||
return $stmt->fetchAll(\PDO::FETCH_COLUMN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all unique artists from albums
|
||||
*/
|
||||
public static function getAvailableArtists(\PDO $pdo): array
|
||||
{
|
||||
$stmt = $pdo->query("SELECT DISTINCT artist_name FROM music_albums WHERE artist_name IS NOT NULL AND artist_name != '' ORDER BY artist_name");
|
||||
return $stmt->fetchAll(\PDO::FETCH_COLUMN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get album statistics
|
||||
*/
|
||||
public static function getStats(\PDO $pdo): array
|
||||
{
|
||||
$stmt = $pdo->query("
|
||||
SELECT
|
||||
COUNT(*) as total_albums,
|
||||
COUNT(CASE WHEN is_favorite = 1 THEN 1 END) as favorite_albums,
|
||||
SUM(track_count) as total_tracks,
|
||||
SUM(total_duration_seconds) as total_duration
|
||||
FROM music_albums
|
||||
");
|
||||
return $stmt->fetch(\PDO::FETCH_ASSOC);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user