| Total Complexity | 66 |
| Total Lines | 567 |
| Duplicated Lines | 0 % |
| Changes | 3 | ||
| Bugs | 0 | Features | 0 |
Complex classes like ApiController often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use ApiController, and based on these observations, apply Extract Interface, too.
| 1 | <?php declare(strict_types=1); |
||
| 49 | class ApiController extends Controller { |
||
| 50 | |||
| 51 | /** @var IL10N */ |
||
| 52 | private $l10n; |
||
| 53 | /** @var TrackBusinessLayer */ |
||
| 54 | private $trackBusinessLayer; |
||
| 55 | /** @var ArtistBusinessLayer */ |
||
| 56 | private $artistBusinessLayer; |
||
| 57 | /** @var AlbumBusinessLayer */ |
||
| 58 | private $albumBusinessLayer; |
||
| 59 | /** @var GenreBusinessLayer */ |
||
| 60 | private $genreBusinessLayer; |
||
| 61 | /** @var Scanner */ |
||
| 62 | private $scanner; |
||
| 63 | /** @var CollectionHelper */ |
||
| 64 | private $collectionHelper; |
||
| 65 | /** @var CoverHelper */ |
||
| 66 | private $coverHelper; |
||
| 67 | /** @var DetailsHelper */ |
||
| 68 | private $detailsHelper; |
||
| 69 | /** @var LastfmService */ |
||
| 70 | private $lastfmService; |
||
| 71 | /** @var Maintenance */ |
||
| 72 | private $maintenance; |
||
| 73 | /** @var UserMusicFolder */ |
||
| 74 | private $userMusicFolder; |
||
| 75 | /** @var string */ |
||
| 76 | private $userId; |
||
| 77 | /** @var IURLGenerator */ |
||
| 78 | private $urlGenerator; |
||
| 79 | /** @var Folder */ |
||
| 80 | private $userFolder; |
||
| 81 | /** @var Logger */ |
||
| 82 | private $logger; |
||
| 83 | |||
| 84 | public function __construct(string $appname, |
||
| 85 | IRequest $request, |
||
| 86 | IURLGenerator $urlGenerator, |
||
| 87 | TrackBusinessLayer $trackbusinesslayer, |
||
| 88 | ArtistBusinessLayer $artistbusinesslayer, |
||
| 89 | AlbumBusinessLayer $albumbusinesslayer, |
||
| 90 | GenreBusinessLayer $genreBusinessLayer, |
||
| 91 | Scanner $scanner, |
||
| 92 | CollectionHelper $collectionHelper, |
||
| 93 | CoverHelper $coverHelper, |
||
| 94 | DetailsHelper $detailsHelper, |
||
| 95 | LastfmService $lastfmService, |
||
| 96 | Maintenance $maintenance, |
||
| 97 | UserMusicFolder $userMusicFolder, |
||
| 98 | ?string $userId, // null if this gets called after the user has logged out |
||
| 99 | IL10N $l10n, |
||
| 100 | ?Folder $userFolder, // null if this gets called after the user has logged out |
||
| 101 | Logger $logger) { |
||
| 102 | parent::__construct($appname, $request); |
||
| 103 | $this->l10n = $l10n; |
||
| 104 | $this->trackBusinessLayer = $trackbusinesslayer; |
||
| 105 | $this->artistBusinessLayer = $artistbusinesslayer; |
||
| 106 | $this->albumBusinessLayer = $albumbusinesslayer; |
||
| 107 | $this->genreBusinessLayer = $genreBusinessLayer; |
||
| 108 | $this->scanner = $scanner; |
||
| 109 | $this->collectionHelper = $collectionHelper; |
||
| 110 | $this->coverHelper = $coverHelper; |
||
| 111 | $this->detailsHelper = $detailsHelper; |
||
| 112 | $this->lastfmService = $lastfmService; |
||
| 113 | $this->maintenance = $maintenance; |
||
| 114 | $this->userMusicFolder = $userMusicFolder; |
||
| 115 | $this->userId = $userId; |
||
| 116 | $this->urlGenerator = $urlGenerator; |
||
| 117 | $this->userFolder = $userFolder; |
||
| 118 | $this->logger = $logger; |
||
| 119 | } |
||
| 120 | |||
| 121 | /** |
||
| 122 | * Extracts the id from an unique slug (id-slug) |
||
| 123 | * @param string|int $slug the slug |
||
| 124 | * @return int the id |
||
| 125 | */ |
||
| 126 | protected static function getIdFromSlug($slug) : int { |
||
| 127 | if (\is_string($slug)) { |
||
| 128 | $split = \explode('-', $slug, 2); |
||
| 129 | return (int)$split[0]; |
||
| 130 | } elseif (\is_int($slug)) { |
||
|
|
|||
| 131 | return $slug; |
||
| 132 | } else { |
||
| 133 | throw new \InvalidArgumentException(); |
||
| 134 | } |
||
| 135 | } |
||
| 136 | |||
| 137 | /** |
||
| 138 | * @NoAdminRequired |
||
| 139 | * @NoCSRFRequired |
||
| 140 | */ |
||
| 141 | public function prepareCollection() { |
||
| 142 | $hash = $this->collectionHelper->getCachedJsonHash(); |
||
| 143 | if ($hash === null) { |
||
| 144 | // build the collection but ignore the data for now |
||
| 145 | $this->collectionHelper->getJson(); |
||
| 146 | $hash = $this->collectionHelper->getCachedJsonHash(); |
||
| 147 | } |
||
| 148 | $coverToken = $this->coverHelper->createAccessToken($this->userId); |
||
| 149 | |||
| 150 | return new JSONResponse([ |
||
| 151 | 'hash' => $hash, |
||
| 152 | 'cover_token' => $coverToken |
||
| 153 | ]); |
||
| 154 | } |
||
| 155 | |||
| 156 | /** |
||
| 157 | * @NoAdminRequired |
||
| 158 | * @NoCSRFRequired |
||
| 159 | */ |
||
| 160 | public function collection() { |
||
| 161 | $collectionJson = $this->collectionHelper->getJson(); |
||
| 162 | $response = new DataDisplayResponse($collectionJson); |
||
| 163 | $response->addHeader('Content-Type', 'application/json; charset=utf-8'); |
||
| 164 | |||
| 165 | // Instruct the client to cache the result in case it requested the collection with |
||
| 166 | // the correct hash. The hash could be incorrect if the collection would have changed |
||
| 167 | // between calls to prepareCollection() and colletion(). |
||
| 168 | $requestHash = $this->request->getParam('hash'); |
||
| 169 | $actualHash = $this->collectionHelper->getCachedJsonHash(); |
||
| 170 | if (!empty($actualHash) && $requestHash === $actualHash) { |
||
| 171 | self::setClientCaching($response, 90); // cache for 3 months |
||
| 172 | } |
||
| 173 | |||
| 174 | return $response; |
||
| 175 | } |
||
| 176 | |||
| 177 | /** |
||
| 178 | * @NoAdminRequired |
||
| 179 | * @NoCSRFRequired |
||
| 180 | */ |
||
| 181 | public function folders() { |
||
| 182 | $musicFolder = $this->userMusicFolder->getFolder($this->userId); |
||
| 183 | $folders = $this->trackBusinessLayer->findAllFolders($this->userId, $musicFolder); |
||
| 184 | return new JSONResponse($folders); |
||
| 185 | } |
||
| 186 | |||
| 187 | /** |
||
| 188 | * @NoAdminRequired |
||
| 189 | * @NoCSRFRequired |
||
| 190 | */ |
||
| 191 | public function genres() { |
||
| 192 | $genres = $this->genreBusinessLayer->findAllWithTrackIds($this->userId); |
||
| 193 | $unscanned = $this->trackBusinessLayer->findFilesWithoutScannedGenre($this->userId); |
||
| 194 | return new JSONResponse([ |
||
| 195 | 'genres' => \array_map(function ($g) { |
||
| 196 | return $g->toApi(); |
||
| 197 | }, $genres), |
||
| 198 | 'unscanned' => $unscanned |
||
| 199 | ]); |
||
| 200 | } |
||
| 201 | |||
| 202 | /** |
||
| 203 | * @NoAdminRequired |
||
| 204 | * @NoCSRFRequired |
||
| 205 | */ |
||
| 206 | public function artists($fulltree, $albums) { |
||
| 207 | $fulltree = \filter_var($fulltree, FILTER_VALIDATE_BOOLEAN); |
||
| 208 | $includeAlbums = \filter_var($albums, FILTER_VALIDATE_BOOLEAN); |
||
| 209 | /** @var Artist[] $artists */ |
||
| 210 | $artists = $this->artistBusinessLayer->findAll($this->userId); |
||
| 211 | |||
| 212 | $artists = \array_map(function ($a) use ($fulltree, $includeAlbums) { |
||
| 213 | return $this->artistToApi($a, $includeAlbums || $fulltree, $fulltree); |
||
| 214 | }, $artists); |
||
| 215 | |||
| 216 | return new JSONResponse($artists); |
||
| 217 | } |
||
| 218 | |||
| 219 | /** |
||
| 220 | * @NoAdminRequired |
||
| 221 | * @NoCSRFRequired |
||
| 222 | */ |
||
| 223 | public function artist($artistIdOrSlug, $fulltree) { |
||
| 224 | $fulltree = \filter_var($fulltree, FILTER_VALIDATE_BOOLEAN); |
||
| 225 | $artistId = $this->getIdFromSlug($artistIdOrSlug); |
||
| 226 | /** @var Artist $artist */ |
||
| 227 | $artist = $this->artistBusinessLayer->find($artistId, $this->userId); |
||
| 228 | $artist = $this->artistToApi($artist, $fulltree, $fulltree); |
||
| 229 | return new JSONResponse($artist); |
||
| 230 | } |
||
| 231 | |||
| 232 | /** |
||
| 233 | * Return given artist in Shia API format |
||
| 234 | * @param Artist $artist |
||
| 235 | * @param boolean $includeAlbums |
||
| 236 | * @param boolean $includeTracks (ignored if $includeAlbums==false) |
||
| 237 | * @return array |
||
| 238 | */ |
||
| 239 | private function artistToApi(Artist $artist, bool $includeAlbums, bool $includeTracks) : array { |
||
| 240 | $artistInApi = $artist->toAPI($this->urlGenerator, $this->l10n); |
||
| 241 | if ($includeAlbums) { |
||
| 242 | $artistId = $artist->getId(); |
||
| 243 | $albums = $this->albumBusinessLayer->findAllByArtist($artistId, $this->userId); |
||
| 244 | |||
| 245 | $artistInApi['albums'] = \array_map(function ($a) use ($includeTracks) { |
||
| 246 | return $this->albumToApi($a, $includeTracks, false); |
||
| 247 | }, $albums); |
||
| 248 | } |
||
| 249 | return $artistInApi; |
||
| 250 | } |
||
| 251 | |||
| 252 | /** |
||
| 253 | * @NoAdminRequired |
||
| 254 | * @NoCSRFRequired |
||
| 255 | */ |
||
| 256 | public function albums(?int $artist, $fulltree) { |
||
| 257 | $fulltree = \filter_var($fulltree, FILTER_VALIDATE_BOOLEAN); |
||
| 258 | if ($artist !== null) { |
||
| 259 | $albums = $this->albumBusinessLayer->findAllByArtist($artist, $this->userId); |
||
| 260 | } else { |
||
| 261 | $albums = $this->albumBusinessLayer->findAll($this->userId); |
||
| 262 | } |
||
| 263 | |||
| 264 | $albums = \array_map(function ($a) use ($fulltree) { |
||
| 265 | return $this->albumToApi($a, $fulltree, $fulltree); |
||
| 266 | }, $albums); |
||
| 267 | |||
| 268 | return new JSONResponse($albums); |
||
| 269 | } |
||
| 270 | |||
| 271 | /** |
||
| 272 | * @NoAdminRequired |
||
| 273 | * @NoCSRFRequired |
||
| 274 | */ |
||
| 275 | public function album($albumIdOrSlug, $fulltree) { |
||
| 281 | } |
||
| 282 | |||
| 283 | /** |
||
| 284 | * Return given album in the Shiva API format |
||
| 285 | */ |
||
| 286 | private function albumToApi(Album $album, bool $includeTracks, bool $includeArtists) : array { |
||
| 287 | $albumInApi = $album->toAPI($this->urlGenerator, $this->l10n); |
||
| 288 | |||
| 289 | if ($includeTracks) { |
||
| 290 | $albumId = $album->getId(); |
||
| 291 | $tracks = $this->trackBusinessLayer->findAllByAlbum($albumId, $this->userId); |
||
| 292 | $albumInApi['tracks'] = \array_map(function ($t) { |
||
| 293 | return $t->toAPI($this->urlGenerator); |
||
| 294 | }, $tracks); |
||
| 295 | } |
||
| 296 | |||
| 297 | if ($includeArtists) { |
||
| 298 | $artistIds = $album->getArtistIds(); |
||
| 299 | $artists = $this->artistBusinessLayer->findById($artistIds, $this->userId); |
||
| 300 | $albumInApi['artists'] = \array_map(function ($a) { |
||
| 301 | return $a->toAPI($this->urlGenerator, $this->l10n); |
||
| 302 | }, $artists); |
||
| 303 | } |
||
| 304 | |||
| 305 | return $albumInApi; |
||
| 306 | } |
||
| 307 | |||
| 308 | /** |
||
| 309 | * @NoAdminRequired |
||
| 310 | * @NoCSRFRequired |
||
| 311 | */ |
||
| 312 | public function tracks($artist, $album, $fulltree) { |
||
| 313 | $fulltree = \filter_var($fulltree, FILTER_VALIDATE_BOOLEAN); |
||
| 314 | if ($artist) { |
||
| 315 | $tracks = $this->trackBusinessLayer->findAllByArtist($artist, $this->userId); |
||
| 316 | } elseif ($album) { |
||
| 317 | $tracks = $this->trackBusinessLayer->findAllByAlbum($album, $this->userId); |
||
| 318 | } else { |
||
| 319 | $tracks = $this->trackBusinessLayer->findAll($this->userId); |
||
| 320 | } |
||
| 321 | foreach ($tracks as &$track) { |
||
| 322 | $artistId = $track->getArtistId(); |
||
| 323 | $albumId = $track->getAlbumId(); |
||
| 324 | $track = $track->toAPI($this->urlGenerator); |
||
| 325 | if ($fulltree) { |
||
| 326 | /** @var Artist $artist */ |
||
| 327 | $artist = $this->artistBusinessLayer->find($artistId, $this->userId); |
||
| 328 | $track['artist'] = $artist->toAPI($this->urlGenerator, $this->l10n); |
||
| 329 | $album = $this->albumBusinessLayer->find($albumId, $this->userId); |
||
| 330 | $track['album'] = $album->toAPI($this->urlGenerator, $this->l10n); |
||
| 331 | } |
||
| 332 | } |
||
| 333 | return new JSONResponse($tracks); |
||
| 334 | } |
||
| 335 | |||
| 336 | /** |
||
| 337 | * @NoAdminRequired |
||
| 338 | * @NoCSRFRequired |
||
| 339 | */ |
||
| 340 | public function track($trackIdOrSlug) { |
||
| 341 | $trackId = $this->getIdFromSlug($trackIdOrSlug); |
||
| 342 | /** @var Track $track */ |
||
| 343 | $track = $this->trackBusinessLayer->find($trackId, $this->userId); |
||
| 344 | return new JSONResponse($track->toAPI($this->urlGenerator)); |
||
| 345 | } |
||
| 346 | |||
| 347 | /** |
||
| 348 | * @NoAdminRequired |
||
| 349 | * @NoCSRFRequired |
||
| 350 | */ |
||
| 351 | public function trackByFileId(int $fileId) { |
||
| 352 | $track = $this->trackBusinessLayer->findByFileId($fileId, $this->userId); |
||
| 353 | if ($track !== null) { |
||
| 354 | return new JSONResponse($track->toCollection($this->l10n)); |
||
| 355 | } else { |
||
| 356 | return new ErrorResponse(Http::STATUS_NOT_FOUND); |
||
| 357 | } |
||
| 358 | } |
||
| 359 | |||
| 360 | /** |
||
| 361 | * @NoAdminRequired |
||
| 362 | * @NoCSRFRequired |
||
| 363 | */ |
||
| 364 | public function getScanState() { |
||
| 365 | return new JSONResponse([ |
||
| 366 | 'unscannedFiles' => $this->scanner->getUnscannedMusicFileIds($this->userId), |
||
| 367 | 'scannedCount' => $this->trackBusinessLayer->count($this->userId) |
||
| 368 | ]); |
||
| 369 | } |
||
| 370 | |||
| 371 | /** |
||
| 372 | * @NoAdminRequired |
||
| 373 | * @UseSession to keep the session reserved while execution in progress |
||
| 374 | */ |
||
| 375 | public function scan(string $files, $finalize) { |
||
| 376 | // extract the parameters |
||
| 377 | $fileIds = \array_map('intval', \explode(',', $files)); |
||
| 378 | $finalize = \filter_var($finalize, FILTER_VALIDATE_BOOLEAN); |
||
| 379 | |||
| 380 | $filesScanned = $this->scanner->scanFiles($this->userId, $this->userFolder, $fileIds); |
||
| 381 | |||
| 382 | $coversUpdated = false; |
||
| 383 | if ($finalize) { |
||
| 384 | $coversUpdated = $this->scanner->findAlbumCovers($this->userId) |
||
| 385 | || $this->scanner->findArtistCovers($this->userId); |
||
| 386 | $totalCount = $this->trackBusinessLayer->count($this->userId); |
||
| 387 | $this->logger->log("Scanning finished, user $this->userId has $totalCount scanned tracks in total", 'info'); |
||
| 388 | } |
||
| 389 | |||
| 390 | return new JSONResponse([ |
||
| 391 | 'filesScanned' => $filesScanned, |
||
| 392 | 'coversUpdated' => $coversUpdated |
||
| 393 | ]); |
||
| 394 | } |
||
| 395 | |||
| 396 | /** |
||
| 397 | * @NoAdminRequired |
||
| 398 | * @UseSession to keep the session reserved while execution in progress |
||
| 399 | */ |
||
| 400 | public function resetScanned() { |
||
| 401 | $this->maintenance->resetDb($this->userId); |
||
| 402 | return new JSONResponse(['success' => true]); |
||
| 403 | } |
||
| 404 | |||
| 405 | /** |
||
| 406 | * @NoAdminRequired |
||
| 407 | * @NoCSRFRequired |
||
| 408 | */ |
||
| 409 | public function download(int $fileId) { |
||
| 410 | $nodes = $this->userFolder->getById($fileId); |
||
| 411 | $node = $nodes[0] ?? null; |
||
| 412 | if ($node instanceof \OCP\Files\File) { |
||
| 413 | return new FileStreamResponse($node); |
||
| 414 | } |
||
| 415 | |||
| 416 | return new ErrorResponse(Http::STATUS_NOT_FOUND, 'file not found'); |
||
| 417 | } |
||
| 418 | |||
| 419 | /** |
||
| 420 | * @NoAdminRequired |
||
| 421 | * @NoCSRFRequired |
||
| 422 | */ |
||
| 423 | public function filePath(int $fileId) { |
||
| 424 | $nodes = $this->userFolder->getById($fileId); |
||
| 425 | if (\count($nodes) == 0) { |
||
| 426 | return new ErrorResponse(Http::STATUS_NOT_FOUND); |
||
| 427 | } else { |
||
| 428 | $node = $nodes[0]; |
||
| 429 | $path = $this->userFolder->getRelativePath($node->getPath()); |
||
| 430 | return new JSONResponse(['path' => Util::urlEncodePath($path)]); |
||
| 431 | } |
||
| 432 | } |
||
| 433 | |||
| 434 | /** |
||
| 435 | * @NoAdminRequired |
||
| 436 | * @NoCSRFRequired |
||
| 437 | */ |
||
| 438 | public function fileInfo(int $fileId) { |
||
| 444 | } |
||
| 445 | } |
||
| 446 | |||
| 447 | /** |
||
| 448 | * @NoAdminRequired |
||
| 449 | * @NoCSRFRequired |
||
| 450 | */ |
||
| 451 | public function fileDetails(int $fileId) { |
||
| 465 | } |
||
| 466 | } |
||
| 467 | |||
| 468 | /** |
||
| 469 | * @NoAdminRequired |
||
| 470 | * @NoCSRFRequired |
||
| 471 | */ |
||
| 472 | public function scrobble(int $trackId) { |
||
| 473 | try { |
||
| 474 | $this->trackBusinessLayer->recordTrackPlayed($trackId, $this->userId); |
||
| 475 | return new JSONResponse(['success' => true]); |
||
| 476 | } catch (BusinessLayerException $e) { |
||
| 477 | return new ErrorResponse(Http::STATUS_NOT_FOUND); |
||
| 478 | } |
||
| 479 | } |
||
| 480 | |||
| 481 | /** |
||
| 482 | * @NoAdminRequired |
||
| 483 | * @NoCSRFRequired |
||
| 484 | */ |
||
| 485 | public function albumDetails($albumIdOrSlug) { |
||
| 486 | try { |
||
| 487 | $albumId = $this->getIdFromSlug($albumIdOrSlug); |
||
| 488 | $info = $this->lastfmService->getAlbumInfo($albumId, $this->userId); |
||
| 489 | return new JSONResponse($info); |
||
| 490 | } catch (BusinessLayerException $e) { |
||
| 491 | return new ErrorResponse(Http::STATUS_NOT_FOUND); |
||
| 492 | } |
||
| 493 | } |
||
| 494 | |||
| 495 | /** |
||
| 496 | * @NoAdminRequired |
||
| 497 | * @NoCSRFRequired |
||
| 498 | */ |
||
| 499 | public function artistDetails($artistIdOrSlug) { |
||
| 500 | try { |
||
| 501 | $artistId = $this->getIdFromSlug($artistIdOrSlug); |
||
| 502 | $info = $this->lastfmService->getArtistInfo($artistId, $this->userId); |
||
| 503 | return new JSONResponse($info); |
||
| 504 | } catch (BusinessLayerException $e) { |
||
| 505 | return new ErrorResponse(Http::STATUS_NOT_FOUND); |
||
| 506 | } |
||
| 507 | } |
||
| 508 | |||
| 509 | /** |
||
| 510 | * @NoAdminRequired |
||
| 511 | * @NoCSRFRequired |
||
| 512 | */ |
||
| 513 | public function similarArtists($artistIdOrSlug) { |
||
| 514 | try { |
||
| 515 | $artistId = $this->getIdFromSlug($artistIdOrSlug); |
||
| 516 | $similar = $this->lastfmService->getSimilarArtists($artistId, $this->userId, /*includeNotPresent=*/true); |
||
| 517 | return new JSONResponse(\array_map(function ($artist) { |
||
| 518 | return [ |
||
| 519 | 'id' => $artist->getId(), |
||
| 520 | 'name' => $artist->getName(), |
||
| 521 | 'url' => $artist->getLastfmUrl() |
||
| 522 | ]; |
||
| 523 | }, $similar)); |
||
| 524 | } catch (BusinessLayerException $e) { |
||
| 525 | return new ErrorResponse(Http::STATUS_NOT_FOUND); |
||
| 526 | } |
||
| 527 | } |
||
| 528 | |||
| 529 | /** |
||
| 530 | * @PublicPage |
||
| 531 | * @NoCSRFRequired |
||
| 532 | */ |
||
| 533 | public function albumCover($albumIdOrSlug, $originalSize, $coverToken) { |
||
| 534 | try { |
||
| 535 | $userId = $this->userId ?? $this->coverHelper->getUserForAccessToken($coverToken); |
||
| 536 | $albumId = $this->getIdFromSlug($albumIdOrSlug); |
||
| 537 | $album = $this->albumBusinessLayer->find($albumId, $userId); |
||
| 538 | return $this->cover($album, $userId, $originalSize); |
||
| 539 | } catch (BusinessLayerException | \OutOfBoundsException $ex) { |
||
| 540 | $this->logger->log("Failed to get the requested cover: $ex", 'debug'); |
||
| 541 | return new ErrorResponse(Http::STATUS_NOT_FOUND); |
||
| 542 | } |
||
| 543 | } |
||
| 544 | |||
| 545 | /** |
||
| 546 | * @PublicPage |
||
| 547 | * @NoCSRFRequired |
||
| 548 | */ |
||
| 549 | public function artistCover($artistIdOrSlug, $originalSize, $coverToken) { |
||
| 550 | try { |
||
| 551 | $userId = $this->userId ?? $this->coverHelper->getUserForAccessToken($coverToken); |
||
| 552 | $artistId = $this->getIdFromSlug($artistIdOrSlug); |
||
| 553 | $artist = $this->artistBusinessLayer->find($artistId, $userId); |
||
| 554 | return $this->cover($artist, $userId, $originalSize); |
||
| 555 | } catch (BusinessLayerException | \OutOfBoundsException $ex) { |
||
| 556 | $this->logger->log("Failed to get the requested cover: $ex", 'debug'); |
||
| 557 | return new ErrorResponse(Http::STATUS_NOT_FOUND); |
||
| 558 | } |
||
| 559 | } |
||
| 560 | |||
| 561 | private function cover($entity, $userId, $originalSize) { |
||
| 587 | } |
||
| 588 | } |
||
| 589 | } |
||
| 590 | |||
| 591 | /** |
||
| 592 | * @PublicPage |
||
| 593 | * @NoCSRFRequired |
||
| 594 | */ |
||
| 595 | public function cachedCover(string $hash, ?string $coverToken) { |
||
| 596 | try { |
||
| 597 | $userId = $this->userId ?? $this->coverHelper->getUserForAccessToken($coverToken); |
||
| 598 | $coverData = $this->coverHelper->getCoverFromCache($hash, $userId); |
||
| 599 | if ($coverData === null) { |
||
| 600 | throw new \OutOfBoundsException("Cover with hash $hash not found"); |
||
| 601 | } |
||
| 602 | $response = new FileResponse($coverData); |
||
| 603 | // instruct also the client-side to cache the result, this is safe |
||
| 604 | // as the resource URI contains the image hash |
||
| 605 | self::setClientCaching($response); |
||
| 606 | return $response; |
||
| 607 | } catch (\OutOfBoundsException $ex) { |
||
| 608 | $this->logger->log("Failed to get the requested cover: $ex", 'debug'); |
||
| 609 | return new ErrorResponse(Http::STATUS_NOT_FOUND); |
||
| 610 | } |
||
| 611 | } |
||
| 612 | |||
| 613 | private static function setClientCaching(Response &$httpResponse, int $days=365) : void { |
||
| 616 | } |
||
| 617 | } |
||
| 618 |