mirror of
https://github.com/ceratic/MediaCollectorLibary.git
synced 2026-05-13 23:56:46 +02:00
198 lines
5.4 KiB
PHP
198 lines
5.4 KiB
PHP
<?php
|
|
|
|
namespace App\Models;
|
|
|
|
class MusicArtist extends Model
|
|
{
|
|
protected string $table = 'music_artists';
|
|
protected array $fillable = [
|
|
'name',
|
|
'biography',
|
|
'formed_date',
|
|
'genre',
|
|
'country',
|
|
'image_url',
|
|
'banner_url',
|
|
'spotify_id',
|
|
'musicbrainz_id',
|
|
'is_favorite',
|
|
'metadata',
|
|
'source_id'
|
|
];
|
|
|
|
protected array $casts = [
|
|
'formed_date' => 'date',
|
|
'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 all albums by this artist
|
|
*/
|
|
public function albums()
|
|
{
|
|
$stmt = $this->pdo->prepare("
|
|
SELECT * FROM music_albums
|
|
WHERE artist_id = :artist_id
|
|
ORDER BY release_date DESC, title ASC
|
|
");
|
|
$stmt->execute(['artist_id' => $this->id]);
|
|
return $stmt->fetchAll(\PDO::FETCH_ASSOC);
|
|
}
|
|
|
|
/**
|
|
* Get all tracks by this artist
|
|
*/
|
|
public function tracks()
|
|
{
|
|
$stmt = $this->pdo->prepare("
|
|
SELECT * FROM music_tracks
|
|
WHERE artist_id = :artist_id
|
|
ORDER BY album_name ASC, track_number ASC, title ASC
|
|
");
|
|
$stmt->execute(['artist_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 artists with optional filters
|
|
*/
|
|
public static function getTotalCount(\PDO $pdo, string $search = '', array $genres = []): int
|
|
{
|
|
$where = [];
|
|
$params = [];
|
|
|
|
$sql = "SELECT COUNT(*) as count FROM music_artists ma JOIN sources s ON ma.source_id = s.id";
|
|
|
|
if (!empty($search)) {
|
|
$where[] = "(ma.name LIKE :search OR ma.biography 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($where)) {
|
|
$sql .= " WHERE " . implode(' AND ', $where);
|
|
}
|
|
|
|
$stmt = $pdo->prepare($sql);
|
|
$stmt->execute($params);
|
|
|
|
return (int)$stmt->fetchColumn();
|
|
}
|
|
|
|
/**
|
|
* Get paginated artists with optional filters
|
|
*/
|
|
public static function getAllWithPagination(
|
|
\PDO $pdo,
|
|
int $page = 1,
|
|
int $perPage = 20,
|
|
string $search = '',
|
|
array $genres = [],
|
|
string $sort = 'name_asc'
|
|
): array {
|
|
$offset = ($page - 1) * $perPage;
|
|
$where = [];
|
|
$params = [];
|
|
|
|
if (!empty($search)) {
|
|
$where[] = "(name LIKE :search OR biography 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) . ")";
|
|
}
|
|
|
|
// Determine sort order
|
|
$orderBy = 'name ASC';
|
|
switch ($sort) {
|
|
case 'name_desc':
|
|
$orderBy = 'name DESC';
|
|
break;
|
|
case 'formed_asc':
|
|
$orderBy = 'formed_date ASC';
|
|
break;
|
|
case 'formed_desc':
|
|
$orderBy = 'formed_date DESC';
|
|
break;
|
|
}
|
|
|
|
$sql = "SELECT ma.*, s.display_name as source_name FROM music_artists 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 artists
|
|
*/
|
|
public static function getAvailableGenres(\PDO $pdo): array
|
|
{
|
|
$stmt = $pdo->query("SELECT DISTINCT genre FROM music_artists WHERE genre IS NOT NULL AND genre != '' ORDER BY genre");
|
|
return $stmt->fetchAll(\PDO::FETCH_COLUMN);
|
|
}
|
|
|
|
/**
|
|
* Get artist statistics
|
|
*/
|
|
public static function getStats(\PDO $pdo): array
|
|
{
|
|
$stmt = $pdo->query("
|
|
SELECT
|
|
COUNT(*) as total_artists,
|
|
COUNT(CASE WHEN is_favorite = 1 THEN 1 END) as favorite_artists,
|
|
COUNT(DISTINCT genre) as total_genres
|
|
FROM music_artists
|
|
");
|
|
return $stmt->fetch(\PDO::FETCH_ASSOC);
|
|
}
|
|
}
|