Configured swagger-php for documentation at /docs, probably needs a refactor lol; paginated searchAlbums to fix limit bug with null filters.
This commit is contained in:
1 parent
56dea097d6
commit
c1b1c2f372
19 files changed
+840
-273
No files matched your search
@@ -146,57 +146,120 @@ class AlbumSearchService
|
||||
*/
|
||||
private function fetchExternalPayloads(AlbumSearchCriteria $criteria, string $externalQuery): array
|
||||
{
|
||||
$result = $this->lastFmClient->searchAlbums($externalQuery, $criteria->limit);
|
||||
$searchItems = (array) ($result['albums']['items'] ?? []);
|
||||
$perPage = max($criteria->limit, 10);
|
||||
$maxPages = 5;
|
||||
$seenSearchIds = [];
|
||||
$persistableIds = [];
|
||||
$persistableLookup = [];
|
||||
$pagesScanned = 0;
|
||||
|
||||
$this->logger->info('Album search results received', [
|
||||
for ($page = 1; $page <= $maxPages && count($persistableIds) < $criteria->limit; $page++) {
|
||||
$pagesScanned++;
|
||||
$result = $this->lastFmClient->searchAlbums($externalQuery, $perPage, $page);
|
||||
$searchItems = (array) ($result['albums']['items'] ?? []);
|
||||
if ($searchItems === []) {
|
||||
break;
|
||||
}
|
||||
|
||||
$ids = $this->extractExternalIds($searchItems);
|
||||
$ids = array_values(array_filter($ids, function (string $id) use (&$seenSearchIds): bool {
|
||||
if ($id === '' || isset($seenSearchIds[$id])) {
|
||||
return false;
|
||||
}
|
||||
$seenSearchIds[$id] = true;
|
||||
return true;
|
||||
}));
|
||||
if ($ids === []) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$full = $this->lastFmClient->getAlbums($ids);
|
||||
$albumsPayload = is_array($full) ? ((array) ($full['albums'] ?? [])) : [];
|
||||
if ($albumsPayload === []) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$genresByAlbum = $this->tagResolver->resolveGenresForAlbums($albumsPayload);
|
||||
foreach ($albumsPayload as $payload) {
|
||||
$albumId = (string) ($payload['id'] ?? '');
|
||||
if ($albumId === '' || !$this->isIngestableExternalAlbum((array) $payload)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->albumRepository->upsertFromExternalAlbum(
|
||||
(array) $payload,
|
||||
$genresByAlbum[$albumId] ?? []
|
||||
);
|
||||
|
||||
if (!isset($persistableLookup[$albumId])) {
|
||||
$persistableLookup[$albumId] = true;
|
||||
$persistableIds[] = $albumId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->logger->info('External album ingestion candidate resolution complete', [
|
||||
'query' => $externalQuery,
|
||||
'items' => count($searchItems),
|
||||
'requested_limit' => $criteria->limit,
|
||||
'persistable_found' => count($persistableIds),
|
||||
'pages_scanned' => $pagesScanned,
|
||||
]);
|
||||
|
||||
if ($searchItems === []) {
|
||||
if ($persistableIds === []) {
|
||||
return ['payloads' => [], 'stats' => [], 'savedIds' => []];
|
||||
}
|
||||
|
||||
$ids = $this->extractExternalIds($searchItems);
|
||||
if ($ids === []) {
|
||||
return ['payloads' => [], 'stats' => [], 'savedIds' => []];
|
||||
}
|
||||
|
||||
$full = $this->lastFmClient->getAlbums($ids);
|
||||
$albumsPayload = is_array($full) ? ((array) ($full['albums'] ?? [])) : [];
|
||||
if ($albumsPayload === []) {
|
||||
$albumsPayload = $searchItems;
|
||||
}
|
||||
|
||||
$genresByAlbum = $this->tagResolver->resolveGenresForAlbums($albumsPayload);
|
||||
|
||||
foreach ($albumsPayload as $payload) {
|
||||
$albumId = (string) ($payload['id'] ?? '');
|
||||
$this->albumRepository->upsertFromExternalAlbum(
|
||||
(array) $payload,
|
||||
$albumId !== '' ? ($genresByAlbum[$albumId] ?? []) : []
|
||||
);
|
||||
}
|
||||
|
||||
$this->entityManager->flush();
|
||||
|
||||
$existing = $this->albumRepository->findByExternalIdsKeyed($ids);
|
||||
$payloads = [];
|
||||
foreach ($ids as $externalId) {
|
||||
$existing = $this->albumRepository->findByExternalIdsKeyed($persistableIds);
|
||||
$orderedIds = [];
|
||||
foreach ($persistableIds as $externalId) {
|
||||
if (isset($existing[$externalId])) {
|
||||
$payloads[] = $existing[$externalId]->toTemplateArray();
|
||||
$orderedIds[] = $externalId;
|
||||
}
|
||||
if (count($orderedIds) >= $criteria->limit) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$payloads = [];
|
||||
foreach ($orderedIds as $externalId) {
|
||||
$payloads[] = $existing[$externalId]->toTemplateArray();
|
||||
}
|
||||
$payloads = $this->hydrateExternalImages($payloads);
|
||||
|
||||
return [
|
||||
'payloads' => $payloads,
|
||||
'stats' => $this->reviewRepository->getAggregatesForAlbumIds($ids),
|
||||
'savedIds' => array_keys($existing),
|
||||
'stats' => $this->reviewRepository->getAggregatesForAlbumIds($orderedIds),
|
||||
'savedIds' => $orderedIds,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string,mixed> $payload
|
||||
*/
|
||||
private function isIngestableExternalAlbum(array $payload): bool
|
||||
{
|
||||
$releaseDate = trim((string) ($payload['release_date'] ?? ''));
|
||||
if ($releaseDate === '') {
|
||||
return false;
|
||||
}
|
||||
|
||||
$tracks = $payload['tracks']['items'] ?? null;
|
||||
if (!is_array($tracks) || $tracks === []) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ($tracks as $track) {
|
||||
$name = trim((string) ($track['name'] ?? ''));
|
||||
if ($name !== '') {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{payloads:array<int,array<mixed>>,stats:array<string,array{count:int,avg:float}>}
|
||||
*/
|
||||
@@ -221,7 +284,7 @@ class AlbumSearchService
|
||||
|
||||
return [
|
||||
'payloads' => array_map(static fn(Album $album) => $album->toTemplateArray(), $userAlbums),
|
||||
'stats' => $this->mapUserStatsToLocalIds($userAlbums, $userStats),
|
||||
'stats' => $this->mapUserStatsToAlbumIds($userAlbums, $userStats),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -230,14 +293,14 @@ class AlbumSearchService
|
||||
* @param array<int,array{count:int,avg:float}> $userStats
|
||||
* @return array<string,array{count:int,avg:float}>
|
||||
*/
|
||||
private function mapUserStatsToLocalIds(array $userAlbums, array $userStats): array
|
||||
private function mapUserStatsToAlbumIds(array $userAlbums, array $userStats): array
|
||||
{
|
||||
$mapped = [];
|
||||
foreach ($userAlbums as $album) {
|
||||
$entityId = (int) $album->getId();
|
||||
$localId = (string) $album->getLocalId();
|
||||
if ($localId !== '' && isset($userStats[$entityId])) {
|
||||
$mapped[$localId] = $userStats[$entityId];
|
||||
$albumId = (string) $album->getExternalId();
|
||||
if ($albumId !== '' && isset($userStats[$entityId])) {
|
||||
$mapped[$albumId] = $userStats[$entityId];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user