mirror of
https://github.com/OPSnet/Gazelle.git
synced 2026-01-16 18:04:34 -05:00
213 lines
7.7 KiB
PHP
213 lines
7.7 KiB
PHP
<?php
|
|
|
|
namespace Gazelle;
|
|
|
|
use Gazelle\Intf\CategoryHasArtist;
|
|
|
|
abstract class ArtistRole extends Base {
|
|
protected const RENDER_TEXT = 1;
|
|
protected const RENDER_HTML = 2;
|
|
|
|
protected array $artistList;
|
|
protected array $idList;
|
|
protected array $roleList;
|
|
|
|
abstract protected function cacheKey(): string;
|
|
|
|
abstract protected function artistListRaw(): array;
|
|
|
|
abstract public function idList(): array;
|
|
|
|
abstract public function roleList(): array;
|
|
|
|
public function __construct(
|
|
protected readonly CategoryHasArtist $object,
|
|
protected readonly Manager\Artist $manager,
|
|
) {}
|
|
|
|
public function flush(): static {
|
|
unset($this->artistList, $this->idList, $this->roleList);
|
|
self::$cache->delete_value($this->cacheKey());
|
|
return $this;
|
|
}
|
|
|
|
protected function artistList(): array {
|
|
if (isset($this->artistList)) {
|
|
return $this->artistList;
|
|
}
|
|
$key = $this->cacheKey();
|
|
$artistList = self::$cache->get_value($key);
|
|
if ($artistList === false) {
|
|
$artistList = $this->artistListRaw();
|
|
self::$cache->cache_value($key, $artistList, 86400 * 7);
|
|
}
|
|
$this->artistList = $artistList;
|
|
return $this->artistList;
|
|
}
|
|
|
|
/**
|
|
* Generate the artist name. (Individual artists will be clickable, or VA)
|
|
*/
|
|
public function link(): string {
|
|
return $this->renderRole(self::RENDER_HTML);
|
|
}
|
|
|
|
/**
|
|
* Generate the artist name as text.
|
|
*/
|
|
public function text(): string {
|
|
return $this->renderRole(self::RENDER_TEXT);
|
|
}
|
|
|
|
public function nameList(): array {
|
|
$list = [];
|
|
foreach ($this->idList() as $role => $artistList) {
|
|
$list[$role] = array_map(fn ($a) => $a['name'], $artistList);
|
|
}
|
|
return $list;
|
|
}
|
|
|
|
/**
|
|
* A readable representation of the artists grouped by their roles in a
|
|
* release group. All artist roles are present as arrays (no need to see if
|
|
* the key exists). Like roleList() but some of the key names change.
|
|
* 'main' becomes 'artists'
|
|
* 'guest' becomes 'with'
|
|
* 'remixer' becomes 'remixedBy'
|
|
* 'composer' becomes 'composers'
|
|
* A role is an array of three keys: ["id" => 801, "aliasid" => 768, "name" => "The Group"]
|
|
*/
|
|
public function roleListByType(): array {
|
|
$list = $this->idList();
|
|
return [
|
|
'artists' => $list[ARTIST_MAIN] ?? [],
|
|
'with' => $list[ARTIST_GUEST] ?? [],
|
|
'remixedBy' => $list[ARTIST_REMIXER] ?? [],
|
|
'composers' => $list[ARTIST_COMPOSER] ?? [],
|
|
'conductor' => $list[ARTIST_CONDUCTOR] ?? [],
|
|
'dj' => $list[ARTIST_DJ] ?? [],
|
|
'producer' => $list[ARTIST_PRODUCER] ?? [],
|
|
'arranger' => $list[ARTIST_ARRANGER] ?? [],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Returns the id of the first artist that would be shown in the renderRole
|
|
* display. If it would be shown as "various ...", then it's the first
|
|
* artist of that role type.
|
|
*
|
|
* @return int|null
|
|
*/
|
|
public function primaryId(): int|null {
|
|
$roleList = $this->roleList();
|
|
$composerCount = count($roleList['composer'] ?? []);
|
|
$conductorCount = count($roleList['conductor'] ?? []);
|
|
$djCount = count($roleList['dj'] ?? []);
|
|
$mainCount = count($roleList['main'] ?? []);
|
|
|
|
if ($djCount) {
|
|
return $roleList['dj'][0]['id'];
|
|
} elseif ($composerCount) {
|
|
return $roleList['composer'][0]['id'];
|
|
} elseif ($mainCount) {
|
|
return $roleList['main'][0]['id'];
|
|
} elseif ($conductorCount) {
|
|
return $roleList['conductor'][0]['id'];
|
|
}
|
|
return null;
|
|
}
|
|
|
|
protected function renderRole(int $mode): string {
|
|
$roleList = $this->roleList();
|
|
$arrangerCount = count($roleList['arranger'] ?? []);
|
|
$composerCount = count($roleList['composer'] ?? []);
|
|
$conductorCount = count($roleList['conductor'] ?? []);
|
|
$djCount = count($roleList['dj'] ?? []);
|
|
$mainCount = count($roleList['main'] ?? []);
|
|
|
|
if ($composerCount + $mainCount + $conductorCount + $djCount === 0) {
|
|
return '';
|
|
}
|
|
|
|
$and = match ($mode) {
|
|
self::RENDER_HTML => ' & ',
|
|
default => ' and ',
|
|
};
|
|
|
|
$chunk = [];
|
|
if ($djCount > 0) {
|
|
$chunk[] = match ($djCount) {
|
|
1 => $this->artistLink($mode, $roleList['dj'][0]),
|
|
2 => $this->artistLink($mode, $roleList['dj'][0])
|
|
. $and . $this->artistLink($mode, $roleList['dj'][1]),
|
|
default => $this->various('DJs', $roleList['dj'], $mode),
|
|
};
|
|
} else {
|
|
if ($composerCount > 0) {
|
|
$chunk[] = match ($composerCount) {
|
|
1 => $this->artistLink($mode, $roleList['composer'][0]),
|
|
2 => $this->artistLink($mode, $roleList['composer'][0])
|
|
. $and . $this->artistLink($mode, $roleList['composer'][1]),
|
|
default => $this->various('Composers', $roleList['composer'], $mode),
|
|
};
|
|
if ($arrangerCount > 0) {
|
|
$chunk[] = 'arranged by';
|
|
$chunk[] = match ($arrangerCount) {
|
|
1 => $this->artistLink($mode, $roleList['arranger'][0]),
|
|
2 => $this->artistLink($mode, $roleList['arranger'][0])
|
|
. $and . $this->artistLink($mode, $roleList['arranger'][1]),
|
|
default => $this->various('Arrangers', $roleList['arranger'], $mode),
|
|
};
|
|
}
|
|
if ($mainCount == 0 and $conductorCount > 0) {
|
|
$chunk[] = 'conducted by';
|
|
} elseif ($mainCount > 0) {
|
|
$chunk[] = 'performed by';
|
|
}
|
|
}
|
|
|
|
if ($mainCount > 0) {
|
|
$chunk[] = match ($mainCount) {
|
|
1 => $this->artistLink($mode, $roleList['main'][0]),
|
|
2 => $this->artistLink($mode, $roleList['main'][0])
|
|
. $and . $this->artistLink($mode, $roleList['main'][1]),
|
|
default => $this->various('Artists', $roleList['main'], $mode),
|
|
};
|
|
}
|
|
|
|
if ($conductorCount > 0) {
|
|
if ($mainCount > 0) {
|
|
$chunk[] = 'under';
|
|
}
|
|
$chunk[] = match ($conductorCount) {
|
|
1 => $this->artistLink($mode, $roleList['conductor'][0]),
|
|
2 => $this->artistLink($mode, $roleList['conductor'][0])
|
|
. $and . $this->artistLink($mode, $roleList['conductor'][1]),
|
|
default => $this->various('Conductors', $roleList['conductor'], $mode),
|
|
};
|
|
}
|
|
}
|
|
return implode(' ', $chunk);
|
|
}
|
|
|
|
protected function various(string $role, array $artistList, int $mode): string {
|
|
return match ($mode) {
|
|
self::RENDER_HTML => '<span class="tooltip" style="float: none" title="'
|
|
. implode(' ⁝ ', array_map(fn ($a) => $a['name'], $artistList))
|
|
. "\">Various $role</span>",
|
|
default => "Various $role",
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Generate an HTML anchor for an artist
|
|
*/
|
|
protected function artistLink(int $mode, array $info): string {
|
|
return match ($mode) {
|
|
self::RENDER_HTML => '<a href="artist.php?id=' . $info['id']
|
|
. '" dir="ltr">' . html_escape($info['name']) . '</a>',
|
|
default => $info['name'],
|
|
};
|
|
}
|
|
}
|