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 => 'Various $role",
default => "Various $role",
};
}
/**
* Generate an HTML anchor for an artist
*/
protected function artistLink(int $mode, array $info): string {
return match ($mode) {
self::RENDER_HTML => '' . html_escape($info['name']) . '',
default => $info['name'],
};
}
}