diff --git a/app/Artist.php b/app/Artist.php index c7303067d..3c3258f27 100644 --- a/app/Artist.php +++ b/app/Artist.php @@ -588,10 +588,10 @@ class Artist extends BaseAttrObject implements Bookmarked, CollageEntry { Artist $old, bool $redirect, User $user, - Manager\Collage $collMan, - Manager\Comment $commMan, - Manager\Request $reqMan, - Manager\TGroup $tgMan, + Manager\Collage $collMan = new Manager\Collage(), + Manager\Comment $commMan = new Manager\Comment(), + Manager\Request $reqMan = new Manager\Request(), + Manager\TGroup $tgMan = new Manager\TGroup(), ): int { self::$db->begin_transaction(); @@ -727,10 +727,17 @@ class Artist extends BaseAttrObject implements Bookmarked, CollageEntry { $collMan->findById($collageId)?->flush(); } foreach ($groupList as $tgroupId) { - $tgMan->findById($tgroupId)?->refresh(); + $tgroup = $tgMan->findById($tgroupId); + if ($tgroup) { + $tgroup->refresh()->artistRole()->flush(); + } } foreach ($requestList as $requestId) { - $reqMan->findById($requestId)?->reindex(); + $request = $reqMan->findById($requestId); + if ($request) { + $request->reindex(); + $request->artistRole()->flush(); + } } // Delete the old artist @@ -754,7 +761,13 @@ class Artist extends BaseAttrObject implements Bookmarked, CollageEntry { /** * rename an alias */ - public function renameAlias(int $aliasId, string $newName, User $user, Manager\Request $reqMan, Manager\TGroup $tgMan): ?int { + public function renameAlias( + int $aliasId, + string $newName, + User $user, + Manager\Request $reqMan = new Manager\Request(), + Manager\TGroup $tgMan = new Manager\TGroup(), + ): ?int { $alias = $this->aliasList()[$aliasId]; if ($alias['redirect_id']) { @@ -838,13 +851,17 @@ class Artist extends BaseAttrObject implements Bookmarked, CollageEntry { SELECT GroupID FROM torrents_artists WHERE AliasID = ? ", $aliasId ); - $groups = self::$db->collect('GroupID'); + $tgroupList = self::$db->collect(0); self::$db->prepared_query(" UPDATE IGNORE torrents_artists SET AliasID = ? WHERE AliasID = ? ", $newId, $aliasId ); - foreach ($groups as $groupId) { - $tgMan->findById($groupId)?->refresh(); + foreach ($tgroupList as $tgroupId) { + $tgroup = $tgMan->findById($tgroupId); + if ($tgroup) { + $tgroup->refresh(); + $tgroup->artistRole()->flush(); + } } // process artists in requests @@ -852,7 +869,7 @@ class Artist extends BaseAttrObject implements Bookmarked, CollageEntry { SELECT RequestID FROM requests_artists WHERE AliasID = ? ", $aliasId ); - $requests = self::$db->collect('RequestID'); + $requestList = self::$db->collect(0); self::$db->prepared_query(" UPDATE IGNORE requests_artists SET AliasID = ? WHERE AliasID = ? ", $newId, $aliasId @@ -872,8 +889,12 @@ class Artist extends BaseAttrObject implements Bookmarked, CollageEntry { self::$db->commit(); - foreach ($requests as $requestId) { - $reqMan->findById($requestId)->reindex(); + foreach ($requestList as $requestId) { + $request = $reqMan->findById($requestId); + if ($request) { + $request->reindex(); + $request->artistRole()->flush(); + } } $this->flush(); return $newId; diff --git a/app/ArtistRole.php b/app/ArtistRole.php index 9952e3c29..97d5a1b79 100644 --- a/app/ArtistRole.php +++ b/app/ArtistRole.php @@ -9,10 +9,12 @@ abstract class ArtistRole extends Base { protected const RENDER_HTML = 2; protected array $artistList; - protected array $roleList; protected array $idList; + protected array $roleList; - abstract protected function artistListQuery(): \mysqli_result|bool; + abstract protected function cacheKey(): string; + + abstract protected function artistListRaw(): array; abstract public function idList(): array; @@ -23,14 +25,23 @@ abstract class ArtistRole extends Base { 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)) { - if ($this->artistListQuery()) { - $this->artistList = self::$db->to_array(false, MYSQLI_ASSOC); - } else { - $this->artistList = []; - } + 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; } @@ -114,7 +125,7 @@ abstract class ArtistRole extends Base { $djCount = count($roleList['dj'] ?? []); $mainCount = count($roleList['main'] ?? []); - if ($composerCount + $mainCount + $conductorCount + $djCount == 0) { + if ($composerCount + $mainCount + $conductorCount + $djCount === 0) { return ''; } @@ -127,54 +138,53 @@ abstract class ArtistRole extends Base { 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]), + 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]), + 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]), + 2 => $this->artistLink($mode, $roleList['arranger'][0]) + . $and . $this->artistLink($mode, $roleList['arranger'][1]), default => $this->various('Arrangers', $roleList['arranger'], $mode), }; } - if ($mainCount + $conductorCount > 0) { + if ($mainCount == 0 and $conductorCount > 0) { + $chunk[] = 'conducted by'; + } elseif ($mainCount > 0) { $chunk[] = 'performed by'; } } - if ( - $composerCount > 0 - && $mainCount > 1 - && $conductorCount > 1 - ) { - $chunk[] = 'Various Artists'; - } else { - 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 ($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 + $composerCount > 0 && ($composerCount < 3 || $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), - }; + 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); @@ -182,8 +192,10 @@ abstract class ArtistRole extends Base { protected function various(string $role, array $artistList, int $mode): string { return match ($mode) { - self::RENDER_HTML => 'Various $role", - default => "Various $role", + self::RENDER_HTML => 'Various $role", + default => "Various $role", }; } @@ -192,8 +204,9 @@ abstract class ArtistRole extends Base { */ protected function artistLink(int $mode, array $info): string { return match ($mode) { - self::RENDER_HTML => '' . html_escape($info['name']) . '', - default => $info['name'], + self::RENDER_HTML => '' . html_escape($info['name']) . '', + default => $info['name'], }; } } diff --git a/app/ArtistRole/Request.php b/app/ArtistRole/Request.php index bcb5b7b4c..6edc25760 100644 --- a/app/ArtistRole/Request.php +++ b/app/ArtistRole/Request.php @@ -5,6 +5,10 @@ declare(strict_types=1); namespace Gazelle\ArtistRole; class Request extends \Gazelle\ArtistRole { + protected function cacheKey(): string { + return sprintf('ar_request_%d', $this->object->id()); + } + /** * Create or modify the set of artists associated with a request */ @@ -85,11 +89,12 @@ class Request extends \Gazelle\ArtistRole { ); $this->pg()->pdo()->commit(); self::$db->commit(); + $this->flush(); return $affected; } - protected function artistListQuery(): \mysqli_result|bool { - return self::$db->prepared_query(" + protected function artistListRaw(): array { + self::$db->prepared_query(" SELECT r.artist_role_id, r.slug AS slug, aa.ArtistID AS artist_id, @@ -102,6 +107,7 @@ class Request extends \Gazelle\ArtistRole { ORDER BY r.artist_role_id ASC, aa.Name ASC ", $this->object->id() ); + return self::$db->to_array(false, MYSQLI_ASSOC); } /** diff --git a/app/ArtistRole/TGroup.php b/app/ArtistRole/TGroup.php index 4f645f9c1..f841deeca 100644 --- a/app/ArtistRole/TGroup.php +++ b/app/ArtistRole/TGroup.php @@ -4,9 +4,11 @@ declare(strict_types=1); namespace Gazelle\ArtistRole; -use Gazelle\Intf\CategoryHasArtist; - class TGroup extends \Gazelle\ArtistRole { + protected function cacheKey(): string { + return sprintf('ar_tgroup_%d', $this->object->id()); + } + protected const MAP = [ 1 => 'main', 2 => 'guest', @@ -18,34 +20,36 @@ class TGroup extends \Gazelle\ArtistRole { 8 => 'arranger', ]; - protected function artistListQuery(): \mysqli_result|bool { - return self::$db->prepared_query(" + protected function artistListRaw(): array { + self::$db->prepared_query(" SELECT ta.artist_role_id, - aa.ArtistID, - aa.Name, - ta.AliasID - FROM torrents_artists AS ta - INNER JOIN artists_alias AS aa USING (AliasID) + aa.ArtistID AS artist_id, + aa.Name AS name, + ta.AliasID AS alias_id + FROM torrents_artists ta + INNER JOIN artists_alias aa USING (AliasID) WHERE ta.GroupID = ? ORDER BY ta.GroupID, ta.artist_role_id ASC, aa.Name ASC ", $this->object->id() ); + return self::$db->to_array(false, MYSQLI_ASSOC); } protected function init(): void { $this->artistList = $this->artistList(); $this->roleList = array_fill_keys(array_values(self::MAP), []); $this->idList = []; - while ([$role, $artistId, $artistName, $aliasId] = self::$db->next_record(MYSQLI_NUM)) { - $this->idList[$role][] = [ - 'id' => $artistId, - 'aliasid' => $aliasId, - 'name' => $artistName, + foreach ($this->artistList as $artist) { + $roleId = $artist['artist_role_id']; + $this->idList[$roleId][] = [ + 'id' => $artist['artist_id'], + 'aliasid' => $artist['alias_id'], + 'name' => $artist['name'], ]; - $this->roleList[self::MAP[$role]][] = [ - 'id' => $artistId, - 'aliasid' => $aliasId, - 'name' => $artistName, + $this->roleList[self::MAP[$roleId]][] = [ + 'id' => $artist['artist_id'], + 'aliasid' => $artist['alias_id'], + 'name' => $artist['name'], ]; } } @@ -174,6 +178,7 @@ class TGroup extends \Gazelle\ArtistRole { ); ++$affected; } + $this->flush(); return $affected; } @@ -207,6 +212,7 @@ class TGroup extends \Gazelle\ArtistRole { $artist->remove(); } } + $this->flush(); return count($changed); } } diff --git a/app/TGroup.php b/app/TGroup.php index c8025c544..370cf27c0 100644 --- a/app/TGroup.php +++ b/app/TGroup.php @@ -648,7 +648,8 @@ class TGroup extends BaseAttrObject implements Bookmarked, CategoryHasArtist, Co $add[] = "{$artist->label()} as " . ARTIST_TYPE[$role]; } } - if (empty($add)) { + $this->artistRole()->flush(); + if ($add === []) { return 0; } self::$db->prepared_query(" @@ -688,6 +689,7 @@ class TGroup extends BaseAttrObject implements Bookmarked, CategoryHasArtist, Co if ($artist->usageTotal() === 0) { $artist->remove(); } + $this->artistRole()?->flush(); $this->flush(); return true; } diff --git a/sections/artist/change_artistid.php b/sections/artist/change_artistid.php index e5ee4cba1..7404a7a25 100644 --- a/sections/artist/change_artistid.php +++ b/sections/artist/change_artistid.php @@ -27,23 +27,15 @@ if (is_null($new)) { } } -if ($artist->id() == $new->id()) { +if ($artist->id == $new->id) { Error400::error('You cannot merge an artist with itself.'); } $redirect = (bool)$_POST['redirect']; if (isset($_POST['confirm'])) { - $new->merge( - $artist, - $redirect, - $Viewer, - new \Gazelle\Manager\Collage(), - new \Gazelle\Manager\Comment(), - new \Gazelle\Manager\Request(), - new \Gazelle\Manager\TGroup(), - ); - header("Location: artist.php?action=edit&artistid={$new->id()}"); + $new->merge($artist, $redirect, $Viewer); + header("Location: artist.php?action=edit&artistid={$new->id}"); exit; } diff --git a/sections/artist/rename.php b/sections/artist/rename.php index c82852015..e5123c47a 100644 --- a/sections/artist/rename.php +++ b/sections/artist/rename.php @@ -31,22 +31,15 @@ if (empty($newName)) { $oldName = $artist->aliasList()[$aliasId]['name']; $otherArtist = $artistMan->findByName($newName); -if (!is_null($otherArtist) && $otherArtist->id() !== $artist->id()) { +if (!is_null($otherArtist) && $otherArtist->id !== $artist->id) { Error400::error( - "An artist with this alias already exists: {$otherArtist->name()} ({$otherArtist->id()})" + "An artist with this alias already exists: {$otherArtist->name()} ({$otherArtist->id})" ); } -$result = $artist->renameAlias( - $aliasId, - $newName, - $Viewer, - new Manager\Request(), - new Manager\TGroup(), -); - +$result = $artist->renameAlias($aliasId, $newName, $Viewer); if (is_null($result)) { Error400::error("The specified name is already in use."); } -header("Location: artist.php?artistid={$artist->id()}&action=edit"); +header("Location: artist.php?artistid={$artist->id}&action=edit"); diff --git a/tests/phpunit/ArtistTest.php b/tests/phpunit/ArtistTest.php index e22e0a347..f06a3e9a5 100644 --- a/tests/phpunit/ArtistTest.php +++ b/tests/phpunit/ArtistTest.php @@ -45,16 +45,17 @@ class ArtistTest extends TestCase { $artist = $manager->create('phpunit.' . randomString(12)); $this->artistIdList[] = $artist->id; + // fake it DB::DB()->prepared_query(" INSERT INTO artist_usage (artist_id, artist_role_id, uses) VALUES (?, ?, ?) ", $artist->id, 1, RANDOM_ARTIST_MIN_ENTRIES ); - // If the following test fails locally: - // before test run: TRUNCATE TABLE artist_usage; - // after test run: (new Stats\Artists)->updateUsage(); - $this->assertEquals($artist->id, $manager->findRandom()?->id, 'artist-find-random'); + + // before test run: TRUNCATE TABLE artst_usage; + // and then: new Stats\Artists()->updateUsage(); + $this->assertEquals($artist->id, $manager->findRandom()->id, 'artist-find-random'); $this->assertNull($manager->findByIdAndRevision($artist->id, -666), 'artist-find-revision-fail'); $this->assertGreaterThan(0, $artist->id, 'artist-create-artist-id'); @@ -265,10 +266,6 @@ class ArtistTest extends TestCase { $old, false, $this->user, - new Manager\Collage(), - new Manager\Comment(), - new Manager\Request(), - new Manager\TGroup(), ), 'artist-merge-n', ); @@ -336,7 +333,7 @@ class ArtistTest extends TestCase { $rename = $artist->name() . '-rename'; $this->assertEquals( $artist->aliasId() + 1, - $artist->renameAlias($artist->aliasId(), $rename, $this->user, new Manager\Request(), new Manager\TGroup()), + $artist->renameAlias($artist->aliasId(), $rename, $this->user), 'alias-rename' ); $this->assertContains($rename, $artist->aliasNameList(), 'alias-is-renamed'); @@ -383,13 +380,7 @@ class ArtistTest extends TestCase { ]; $name = $artist->name() . '-rename2'; - $artist->renameAlias( - $artist->primaryAliasId(), - $name, - $this->user, - $requestMan, - new Manager\TGroup(), - ); + $artist->renameAlias($artist->primaryAliasId(), $name, $this->user); $this->assertEquals($name, $artist->name(), 'artist-is-smart-renamed'); $commentPage = new Comment\Artist($artist->id, 1, 0); @@ -408,7 +399,7 @@ class ArtistTest extends TestCase { $this->assertEquals($artist->id, $idList[ARTIST_MAIN][0]['id'], 'artist-renamed-request'); $request->remove(); - $this->tgroupList[0]->flush(); + $this->tgroupList[0]->artistRole()->flush(); $idList = $this->tgroupList[0]->artistRole()->idList(); $this->assertEquals($artist->id, $idList[ARTIST_MAIN][0]['id'], 'artist-renamed-tgroup'); } @@ -426,9 +417,21 @@ class ArtistTest extends TestCase { $aliasUpper = strtoupper($aliasName); $aliasId = $artist->getAlias($aliasName); $this->assertNotNull($aliasId, 'artist-rename-capchange-create'); - $this->assertEquals($aliasId, $artist->renameAlias($aliasId, $aliasUpper, $this->user, $reqMan, $tgMan), 'artist-rename-capchange-1'); - $this->assertEquals($aliasId, $artist->getAlias($aliasName), 'artist-rename-capchange-2'); - $this->assertEquals($mainAliasId, $artist->primaryAliasId(), 'artist-rename-capchange-sanity'); + $this->assertEquals( + $aliasId, + $artist->renameAlias($aliasId, $aliasUpper, $this->user), + 'artist-rename-capchange-1', + ); + $this->assertEquals( + $aliasId, + $artist->getAlias($aliasName), + 'artist-rename-capchange-2', + ); + $this->assertEquals( + $mainAliasId, + $artist->primaryAliasId(), + 'artist-rename-capchange-sanity', + ); } public function testRenameAliasNraMerge(): void { @@ -451,7 +454,11 @@ class ArtistTest extends TestCase { $a2Name = 'phpunit.' . randomString(12) . '-alias'; $a2Id = $artist->addAlias($a2Name, null, $this->user); - $this->assertEquals($a2Id, $artist->renameAlias($a1Id, $a2Name, $this->user, $reqMan, $tgMan), 'artist-rename-nramerge-1'); + $this->assertEquals( + $a2Id, + $artist->renameAlias($a1Id, $a2Name, $this->user), + 'artist-rename-nramerge-1', + ); $a1 = $artist->aliasList()[$a1Id]; $a2 = $artist->aliasList()[$a2Id]; @@ -465,7 +472,7 @@ class ArtistTest extends TestCase { // rename a2 and test redirects $a2NewName = 'phpunit.' . randomString(12) . '-new'; - $a3Id = $artist->renameAlias($a2Id, $a2NewName, $this->user, $reqMan, $tgMan); + $a3Id = $artist->renameAlias($a2Id, $a2NewName, $this->user); $this->assertNotEquals($a2Id, $a3Id, 'artist-rename-nramerge-6'); $a1 = $artist->aliasList()[$a1Id]; diff --git a/tests/phpunit/TGroupTest.php b/tests/phpunit/TGroupTest.php index ab252b1e7..c37db8a42 100644 --- a/tests/phpunit/TGroupTest.php +++ b/tests/phpunit/TGroupTest.php @@ -72,6 +72,13 @@ class TGroupTest extends TestCase { } } + /* Random artist names may not be in alphabetical order, but + * will be rendered in order, so arrange as appropriate. + */ + protected function namePair(string $one, string $two): array { + return $two < $one ? [$two, $one] : [$one, $two]; + } + public function testTGroupCreate(): void { $this->assertGreaterThan(1, $this->tgroup->id, 'tgroup-create-id'); @@ -185,13 +192,11 @@ class TGroupTest extends TestCase { $this->assertNotNull($this->tgroup->primaryArtist(), 'tgroup-artist-primary'); $artistRole = $this->tgroup->artistRole(); - $this->assertNotNull($artistRole, 'tgroup-artist-artist-role'); - $idList = $artistRole->idList(); - $this->assertCount(1, $idList, 'tgroup-artist-role-idlist'); + $this->assertCount(1, $idList, 'tgroup-artistrole-idlist'); $main = $idList[ARTIST_MAIN]; - $this->assertCount(1, $main, 'tgroup-artist-role-main'); + $this->assertCount(1, $main, 'tgroup-artistrole-main'); $artist = $artMan->findByName($artistName); $this->assertEquals( [ @@ -209,7 +214,7 @@ class TGroupTest extends TestCase { "arranger" => [], ], $artistRole->roleListByType(), - 'tgroup-artist-role-by-type', + 'tgroup-artistrole-by-type', ); $this->assertEquals( [ @@ -227,13 +232,18 @@ class TGroupTest extends TestCase { "8" => null, ], $artistRole->legacyList(), - 'tgroup-artist-role-legacy', + 'tgroup-artistrole-legacy', + ); + $this->assertEquals( + ["1" => [$artist->name()]], + $artistRole->nameList(), + 'tgroup-artistrole-namelist', ); $first = current($main); $this->assertEquals($artistName, $first['name'], 'tgroup-artist-first-name'); $foundByArtist = $this->manager->findByArtistReleaseYear( - (string)$this->tgroup->artistRole()?->text(), + $this->tgroup->artistRole()->text(), $this->tgroup->name(), (int)$this->tgroup->releaseType(), (int)$this->tgroup->year(), @@ -268,30 +278,29 @@ class TGroupTest extends TestCase { ); /* turn the two Main and Guest into DJs */ - $roleList = $this->tgroup->artistRole()?->roleList(); - $this->assertIsArray($roleList, 'tgroup-dj-role'); + $roleList = $this->tgroup->artistRole()->roleList(); $roleAliasList = [ ...array_map(fn ($artist) => [ARTIST_MAIN, $artist['aliasid']], $roleList['main']), ...array_map(fn ($artist) => [ARTIST_GUEST, $artist['aliasid']], $roleList['guest']), ]; $this->assertEquals( 3, - $this->tgroup->artistRole()?->modifyList($roleAliasList, ARTIST_DJ, $user), + $this->tgroup->artistRole()->modifyList($roleAliasList, ARTIST_DJ, $user), 'tgroup-a-dj-saved-my-life' ); $this->assertEquals( 'Various DJs', - $this->tgroup->flush()->artistRole()?->text(), + $this->tgroup->flush()->artistRole()->text(), 'tgroup-2manydjs' ); $this->assertEquals( 1, - $this->tgroup->artistRole()?->removeList([[ARTIST_DJ, $roleAliasList[0][1]]], $user), + $this->tgroup->artistRole()->removeList([[ARTIST_DJ, $roleAliasList[0][1]]], $user), 'tgroup-hang-the-dj' ); $this->assertEquals( "$addName and $artistName-guest", - $this->tgroup->flush()->artistRole()?->text(), + $this->tgroup->flush()->artistRole()->text(), 'tgroup-dj-final' ); $this->assertEquals( @@ -623,4 +632,187 @@ class TGroupTest extends TestCase { 'tgroup-bookmark-unsnatched', ); } + + public function testTGroupNameDJRender(): void { + $artistName = [ + 'phpunit-name-' . randomString(10), + 'phpunit-name-' . randomString(10), + 'phpunit-name-' . randomString(10), + 'phpunit-name-' . randomString(10), + ]; + $artMan = new Manager\Artist(); + + $this->tgroup->addArtists([ARTIST_DJ], [$artistName[0]]); + $this->assertEquals( + $artistName[0], + $this->tgroup->artistRole()->text(), + 'tgroup-dj-1-text', + ); + $artist = $artMan->findByName($artistName[0]); + $this->assertEquals( + "id}\" dir=\"ltr\">{$artist->name()}", + $this->tgroup->artistRole()->link(), + 'tgroup-dj-1-html', + ); + $this->tgroup->addArtists([ARTIST_DJ], [$artistName[1]]); + $this->assertEquals( + implode(' and ', $this->namePair($artistName[0], $artistName[1])), + $this->tgroup->artistRole()->text(), + 'tgroup-dj-2-text', + ); + // Getting two artist objects in alphabetical order is another matter entirely + $artMan = new Manager\Artist(); + $artistMap = [ + $artistName[0] => $artMan->findByName($artistName[0]), + $artistName[1] => $artMan->findByName($artistName[1]), + ]; + $order = $this->namePair($artistName[0], $artistName[1]); + $this->assertEquals( + implode( + ' & ', + array_map( + fn ($a) => "id}\" dir=\"ltr\">{$a->name()}", + [ + $artistMap[$order[0]], + $artistMap[$order[1]], + ], + ) + ), + $this->tgroup->artistRole()->link(), + 'tgroup-dj-2-link', + ); + $this->tgroup->addArtists([ARTIST_DJ], [$artistName[2]]); + $this->assertEquals( + "Various DJs", + $this->tgroup->artistRole()->text(), + 'tgroup-dj-3-text', + ); + $sortedArtistList = [ + $artistName[0], + $artistName[1], + $artistName[2], + ]; + sort($sortedArtistList); + $this->assertEquals( + 'Various DJs', + $this->tgroup->artistRole()->link(), + 'tgroup-dj-3-link', + ); + $this->tgroup->addArtists([ARTIST_MAIN], [$artistName[3]]); + $this->assertEquals( + "Various DJs", + $this->tgroup->artistRole()->text(), + 'tgroup-dj-4-text', + ); + } + + public function testTGroupNameClassicalEraRender(): void { + $artistName = [ + 'phpunit-name-' . randomString(10), + 'phpunit-name-' . randomString(10), + 'phpunit-name-' . randomString(10), + 'phpunit-name-' . randomString(10), + 'phpunit-name-' . randomString(10), + 'phpunit-name-' . randomString(10), + 'phpunit-name-' . randomString(10), + 'phpunit-name-' . randomString(10), + 'phpunit-name-' . randomString(10), + 'phpunit-name-' . randomString(10), + 'phpunit-name-' . randomString(10), + 'phpunit-name-' . randomString(10), + ]; + + $this->tgroup->addArtists([ARTIST_COMPOSER], [$artistName[0]]); + $this->assertEquals( + $artistName[0], + $this->tgroup->artistRole()->text(), + 'tgroup-composer-1-text', + ); + $this->tgroup->addArtists([ARTIST_CONDUCTOR], [$artistName[1]]); + $this->assertEquals( + "{$artistName[0]} conducted by {$artistName[1]}", + $this->tgroup->artistRole()->text(), + 'tgroup-composer-1-conductor-1-text', + ); + $this->tgroup->addArtists([ARTIST_CONDUCTOR], [$artistName[2]]); + $this->assertEquals( + "{$artistName[0]} conducted by " + . implode(' and ', $this->namePair($artistName[1], $artistName[2])), + $this->tgroup->artistRole()->text(), + 'tgroup-composer-1-conductor-2-text', + ); + $this->tgroup->addArtists([ARTIST_COMPOSER], [$artistName[3]]); + $this->assertEquals( + implode(' and ', $this->namePair($artistName[0], $artistName[3])) + . ' conducted by ' + . implode(' and ', $this->namePair($artistName[1], $artistName[2])), + $this->tgroup->artistRole()->text(), + 'tgroup-composer-2-conductor-2-text', + ); + $this->tgroup->addArtists([ARTIST_ARRANGER], [$artistName[4]]); + $this->assertEquals( + implode(' and ', $this->namePair($artistName[0], $artistName[3])) + . " arranged by {$artistName[4]} conducted by " + . implode(' and ', $this->namePair($artistName[1], $artistName[2])), + $this->tgroup->artistRole()->text(), + 'tgroup-composer-2-arranger-1-conductor-2-text', + ); + $this->tgroup->addArtists([ARTIST_MAIN], [$artistName[5]]); + $this->assertEquals( + implode(' and ', $this->namePair($artistName[0], $artistName[3])) + . " arranged by {$artistName[4]} performed by {$artistName[5]} under " + . implode(' and ', $this->namePair($artistName[1], $artistName[2])), + $this->tgroup->artistRole()->text(), + 'tgroup-main-1-composer-2-arranger-1-conductor-2-text', + ); + $this->tgroup->addArtists([ARTIST_MAIN], [$artistName[6]]); + $this->assertEquals( + implode(' and ', $this->namePair($artistName[0], $artistName[3])) + . " arranged by {$artistName[4]} performed by " + . implode(' and ', $this->namePair($artistName[5], $artistName[6])) + . ' under ' + . implode(' and ', $this->namePair($artistName[1], $artistName[2])), + $this->tgroup->artistRole()->text(), + 'tgroup-main-2-composer-2-arranger-1-conductor-2-text', + ); + $this->tgroup->addArtists([ARTIST_ARRANGER], [$artistName[7]]); + $this->assertEquals( + implode(' and ', $this->namePair($artistName[0], $artistName[3])) + . ' arranged by ' + . implode(' and ', $this->namePair($artistName[4], $artistName[7])) + . ' performed by ' + . implode(' and ', $this->namePair($artistName[5], $artistName[6])) + . ' under ' + . implode(' and ', $this->namePair($artistName[1], $artistName[2])), + $this->tgroup->artistRole()->text(), + 'tgroup-main-2-composer-2-arranger-2-conductor-2-text', + ); + $this->tgroup->addArtists( + [ARTIST_COMPOSER, ARTIST_CONDUCTOR, ARTIST_MAIN, ARTIST_ARRANGER], + [$artistName[8], $artistName[9], $artistName[10], $artistName[11], ] + ); + $this->assertEquals( + "Various Composers arranged by Various Arrangers performed by Various Artists under Various Conductors", + $this->tgroup->artistRole()->text(), + 'tgroup-main-3-composer-3-arranger-3-conductor-3-text', + ); + } + + public function testTGroupArtistRole(): void { + $artistName = 'phpunit-name-' . randomString(10); + + $this->tgroup->addArtists( + [ARTIST_COMPOSER, ARTIST_CONDUCTOR, ARTIST_MAIN, ARTIST_PRODUCER], + [$artistName, $artistName, $artistName, $artistName] + ); + $artistRole = new Manager\Artist()->findByName($artistName)->artistRole(); + $this->assertCount(8, $artistRole, 'tgroup-artistrole-count'); + $this->assertEquals(0, $artistRole[ARTIST_GUEST], 'tgroup-artistrole-guest'); + $this->assertEquals(1, $artistRole[ARTIST_COMPOSER], 'tgroup-artistrole-composer'); + $this->assertEquals(1, $artistRole[ARTIST_CONDUCTOR], 'tgroup-artistrole-conductor'); + $this->assertEquals(1, $artistRole[ARTIST_MAIN], 'tgroup-artistrole-main'); + $this->assertEquals(1, $artistRole[ARTIST_PRODUCER], 'tgroup-artistrole-producer'); + } }