Completed
Pull Request — master (#777)
by Pauli
13:39 queued 11:25
created

ApiController::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 33
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 16
nc 1
nop 17
dl 0
loc 33
ccs 17
cts 17
cp 1
crap 1
rs 9.7333
c 0
b 0
f 0

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
/**
4
 * ownCloud - Music app
5
 *
6
 * This file is licensed under the Affero General Public License version 3 or
7
 * later. See the COPYING file.
8
 *
9
 * @author Morris Jobke <[email protected]>
10
 * @author Pauli Järvinen <[email protected]>
11
 * @copyright Morris Jobke 2013, 2014
12
 * @copyright Pauli Järvinen 2017 - 2020
13
 */
14
15
namespace OCA\Music\Controller;
16
17
use \OCP\AppFramework\Controller;
0 ignored issues
show
Bug introduced by
The type OCP\AppFramework\Controller was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
18
use \OCP\AppFramework\Http;
0 ignored issues
show
Bug introduced by
The type OCP\AppFramework\Http was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
19
use \OCP\AppFramework\Http\DataDisplayResponse;
0 ignored issues
show
Bug introduced by
The type OCP\AppFramework\Http\DataDisplayResponse was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
20
use \OCP\AppFramework\Http\JSONResponse;
0 ignored issues
show
Bug introduced by
The type OCP\AppFramework\Http\JSONResponse was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
21
use \OCP\AppFramework\Http\RedirectResponse;
0 ignored issues
show
Bug introduced by
The type OCP\AppFramework\Http\RedirectResponse was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
22
use \OCP\Files\Folder;
0 ignored issues
show
Bug introduced by
The type OCP\Files\Folder was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
23
use \OCP\IL10N;
0 ignored issues
show
Bug introduced by
The type OCP\IL10N was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
24
use \OCP\IRequest;
0 ignored issues
show
Bug introduced by
The type OCP\IRequest was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
25
use \OCP\IURLGenerator;
0 ignored issues
show
Bug introduced by
The type OCP\IURLGenerator was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
26
27
use \OCA\Music\AppFramework\BusinessLayer\BusinessLayerException;
28
use \OCA\Music\AppFramework\Core\Logger;
29
use \OCA\Music\BusinessLayer\AlbumBusinessLayer;
30
use \OCA\Music\BusinessLayer\ArtistBusinessLayer;
31
use \OCA\Music\BusinessLayer\GenreBusinessLayer;
32
use \OCA\Music\BusinessLayer\TrackBusinessLayer;
33
use \OCA\Music\Db\Album;
34
use \OCA\Music\Db\Artist;
35
use \OCA\Music\Db\Maintenance;
36
use \OCA\Music\Db\Track;
37
use \OCA\Music\Http\ErrorResponse;
38
use \OCA\Music\Http\FileResponse;
39
use \OCA\Music\Utility\CollectionHelper;
40
use \OCA\Music\Utility\CoverHelper;
41
use \OCA\Music\Utility\DetailsHelper;
42
use \OCA\Music\Utility\LastfmService;
43
use \OCA\Music\Utility\Scanner;
44
use \OCA\Music\Utility\Util;
45
46
class ApiController extends Controller {
47
48
	/** @var IL10N */
49
	private $l10n;
50
	/** @var TrackBusinessLayer */
51
	private $trackBusinessLayer;
52
	/** @var ArtistBusinessLayer */
53
	private $artistBusinessLayer;
54
	/** @var AlbumBusinessLayer */
55
	private $albumBusinessLayer;
56
	/** @var GenreBusinessLayer */
57
	private $genreBusinessLayer;
58
	/** @var Scanner */
59
	private $scanner;
60
	/** @var CollectionHelper */
61
	private $collectionHelper;
62
	/** @var CoverHelper */
63
	private $coverHelper;
64
	/** @var DetailsHelper */
65
	private $detailsHelper;
66
	/** @var LastfmService */
67
	private $lastfmService;
68
	/** @var Maintenance */
69
	private $maintenance;
70
	/** @var string */
71
	private $userId;
72
	/** @var IURLGenerator */
73
	private $urlGenerator;
74
	/** @var Folder */
75
	private $userFolder;
76
	/** @var Logger */
77
	private $logger;
78
79 16
	public function __construct($appname,
80
								IRequest $request,
81
								IURLGenerator $urlGenerator,
82
								TrackBusinessLayer $trackbusinesslayer,
83
								ArtistBusinessLayer $artistbusinesslayer,
84
								AlbumBusinessLayer $albumbusinesslayer,
85
								GenreBusinessLayer $genreBusinessLayer,
86
								Scanner $scanner,
87
								CollectionHelper $collectionHelper,
88
								CoverHelper $coverHelper,
89
								DetailsHelper $detailsHelper,
90
								LastfmService $lastfmService,
91
								Maintenance $maintenance,
92
								$userId,
93
								IL10N $l10n,
94
								/*Folder*/ $userFolder, // no type-hint as this may sometimes be null
95
								Logger $logger) {
96 16
		parent::__construct($appname, $request);
97 16
		$this->l10n = $l10n;
98 16
		$this->trackBusinessLayer = $trackbusinesslayer;
99 16
		$this->artistBusinessLayer = $artistbusinesslayer;
100 16
		$this->albumBusinessLayer = $albumbusinesslayer;
101 16
		$this->genreBusinessLayer = $genreBusinessLayer;
102 16
		$this->scanner = $scanner;
103 16
		$this->collectionHelper = $collectionHelper;
104 16
		$this->coverHelper = $coverHelper;
105 16
		$this->detailsHelper = $detailsHelper;
106 16
		$this->lastfmService = $lastfmService;
107 16
		$this->maintenance = $maintenance;
108 16
		$this->userId = $userId;
109 16
		$this->urlGenerator = $urlGenerator;
110 16
		$this->userFolder = $userFolder;
111 16
		$this->logger = $logger;
112 16
	}
113
114
	/**
115
	 * Extracts the id from an unique slug (id-slug)
116
	 * @param string $slug the slug
117
	 * @return integer the id
118
	 */
119 5
	protected static function getIdFromSlug($slug) {
120 5
		$split = \explode('-', $slug, 2);
121
122 5
		return (int)$split[0];
123
	}
124
125
	/**
126
	 * @NoAdminRequired
127
	 * @NoCSRFRequired
128
	 */
129
	public function prepareCollection() {
130
		$hash = $this->collectionHelper->getCachedJsonHash();
131
		if ($hash === null) {
132
			// build the collection but ignore the data for now
133
			$this->collectionHelper->getJson();
134
			$hash = $this->collectionHelper->getCachedJsonHash();
135
		}
136
		return new JSONResponse(['hash' => $hash]);
137
	}
138
139
	/**
140
	 * @NoAdminRequired
141
	 * @NoCSRFRequired
142
	 */
143
	public function collection() {
144
145
		$collectionJson = $this->collectionHelper->getJson();
146
		$response = new DataDisplayResponse($collectionJson);
147
		$response->addHeader('Content-Type', 'application/json; charset=utf-8');
148
149
		// Instruct the client to cache the result in case it requested the collection with
150
		// the correct hash. The hash could be incorrect if the collection would have changed
151
		// between calls to prepareCollection() and colletion().
152
		$requestHash = $this->request->getParam('hash');
153
		$actualHash = $this->collectionHelper->getCachedJsonHash();
154
		if (!empty($actualHash) && $requestHash === $actualHash) {
155
			self::setClientCaching($response, 90); // cache for 3 months
156
		}
157
158
		return $response;
159
	}
160
161
	/**
162
	 * @NoAdminRequired
163
	 * @NoCSRFRequired
164
	 */
165
	public function folders() {
166
		$folders = $this->trackBusinessLayer->findAllFolders($this->userId, $this->userFolder);
167
		return new JSONResponse($folders);
168
	}
169
170
	/**
171
	 * @NoAdminRequired
172
	 * @NoCSRFRequired
173
	 */
174
	public function genres() {
175
		$genres = $this->genreBusinessLayer->findAllWithTrackIds($this->userId);
176
		$unscanned =  $this->trackBusinessLayer->findFilesWithoutScannedGenre($this->userId);
177
		return new JSONResponse([
178
			'genres' => \array_map(function($g) {return $g->toApi();}, $genres),
179
			'unscanned' => $unscanned
180
		]);
181
	}
182
183
	/**
184
	 * @NoAdminRequired
185
	 * @NoCSRFRequired
186
	 */
187 3
	public function artists($fulltree, $albums) {
188 3
		$fulltree = \filter_var($fulltree, FILTER_VALIDATE_BOOLEAN);
189 3
		$includeAlbums = \filter_var($albums, FILTER_VALIDATE_BOOLEAN);
190
		/** @var Artist[] $artists */
191 3
		$artists = $this->artistBusinessLayer->findAll($this->userId);
192
193
		$artists = \array_map(function($a) use ($fulltree, $includeAlbums) {
194 3
			return $this->artistToApi($a, $includeAlbums || $fulltree, $fulltree);
195 3
		}, $artists);
196
197 3
		return new JSONResponse($artists);
198
	}
199
200
	/**
201
	 * @NoAdminRequired
202
	 * @NoCSRFRequired
203
	 */
204 2
	public function artist($artistIdOrSlug, $fulltree) {
205 2
		$fulltree = \filter_var($fulltree, FILTER_VALIDATE_BOOLEAN);
206 2
		$artistId = $this->getIdFromSlug($artistIdOrSlug);
207
		/** @var Artist $artist */
208 2
		$artist = $this->artistBusinessLayer->find($artistId, $this->userId);
209 2
		$artist = $this->artistToApi($artist, $fulltree, $fulltree);
210 2
		return new JSONResponse($artist);
211
	}
212
213
	/**
214
	 * Return given artist in Shia API format
215
	 * @param Artist $artist
216
	 * @param boolean $includeAlbums
217
	 * @param boolean $includeTracks (ignored if $includeAlbums==false)
218
	 * @return array
219
	 */
220 5
	private function artistToApi($artist, $includeAlbums, $includeTracks) {
221 5
		$artistInApi = $artist->toAPI($this->urlGenerator, $this->l10n);
222 5
		if ($includeAlbums) {
223 3
			$artistId = $artist->getId();
224 3
			$albums = $this->albumBusinessLayer->findAllByArtist($artistId, $this->userId);
225
226
			$artistInApi['albums'] = \array_map(function($a) use ($includeTracks) {
227 3
				return $this->albumToApi($a, $includeTracks, false);
228 3
			}, $albums);
229
		}
230 5
		return $artistInApi;
231
	}
232
233
	/**
234
	 * @NoAdminRequired
235
	 * @NoCSRFRequired
236
	 */
237 2
	public function albums($artist, $fulltree) {
238 2
		$fulltree = \filter_var($fulltree, FILTER_VALIDATE_BOOLEAN);
239 2
		if ($artist) {
240
			$albums = $this->albumBusinessLayer->findAllByArtist($artist, $this->userId);
241
		} else {
242 2
			$albums = $this->albumBusinessLayer->findAll($this->userId);
243
		}
244
245
		$albums = \array_map(function($a) use ($fulltree) {
246 2
			return $this->albumToApi($a, $fulltree, $fulltree);
247 2
		}, $albums);
248
249 2
		return new JSONResponse($albums);
250
	}
251
252
	/**
253
	 * @NoAdminRequired
254
	 * @NoCSRFRequired
255
	 */
256 2
	public function album($albumIdOrSlug, $fulltree) {
257 2
		$fulltree = \filter_var($fulltree, FILTER_VALIDATE_BOOLEAN);
258 2
		$albumId = $this->getIdFromSlug($albumIdOrSlug);
259 2
		$album = $this->albumBusinessLayer->find($albumId, $this->userId);
260 2
		$album = $this->albumToApi($album, $fulltree, $fulltree);
261 2
		return new JSONResponse($album);
262
	}
263
264
	/**
265
	 * Return given album in the Shiva API format
266
	 * @param Album $album
267
	 * @param boolean $includeTracks
268
	 * @param boolean $includeAlbums
269
	 * @return array
270
	 */
271 7
	private function albumToApi($album, $includeTracks, $includeArtists) {
272 7
		$albumInApi = $album->toAPI($this->urlGenerator, $this->l10n);
273
274 7
		if ($includeTracks) {
275 4
			$albumId = $album->getId();
276 4
			$tracks = $this->trackBusinessLayer->findAllByAlbum($albumId, $this->userId);
277
			$albumInApi['tracks'] = \array_map(function($t) {
278 4
				return $t->toAPI($this->urlGenerator);
279 4
			}, $tracks);
280
		}
281
282 7
		if ($includeArtists) {
283 2
			$artistIds = $album->getArtistIds();
284 2
			$artists = $this->artistBusinessLayer->findById($artistIds, $this->userId);
285 2
			$albumInApi['artists'] = \array_map(function($a) {
286 2
				return $a->toAPI($this->urlGenerator, $this->l10n);
287 2
			}, $artists);
288
		}
289
290 7
		return $albumInApi;
291
	}
292
293
	/**
294
	 * @NoAdminRequired
295
	 * @NoCSRFRequired
296
	 */
297 4
	public function tracks($artist, $album, $fulltree) {
298 4
		$fulltree = \filter_var($fulltree, FILTER_VALIDATE_BOOLEAN);
299 4
		if ($artist) {
300 1
			$tracks = $this->trackBusinessLayer->findAllByArtist($artist, $this->userId);
301 3
		} elseif ($album) {
302 1
			$tracks = $this->trackBusinessLayer->findAllByAlbum($album, $this->userId);
303
		} else {
304 2
			$tracks = $this->trackBusinessLayer->findAll($this->userId);
305
		}
306 4
		foreach ($tracks as &$track) {
307 4
			$artistId = $track->getArtistId();
308 4
			$albumId = $track->getAlbumId();
309 4
			$track = $track->toAPI($this->urlGenerator);
310 4
			if ($fulltree) {
311
				/** @var Artist $artist */
312 1
				$artist = $this->artistBusinessLayer->find($artistId, $this->userId);
313 1
				$track['artist'] = $artist->toAPI($this->urlGenerator, $this->l10n);
314 1
				$album = $this->albumBusinessLayer->find($albumId, $this->userId);
315 1
				$track['album'] = $album->toAPI($this->urlGenerator, $this->l10n);
316
			}
317
		}
318 4
		return new JSONResponse($tracks);
319
	}
320
321
	/**
322
	 * @NoAdminRequired
323
	 * @NoCSRFRequired
324
	 */
325 1
	public function track($trackIdOrSlug) {
326 1
		$trackId = $this->getIdFromSlug($trackIdOrSlug);
327
		/** @var Track $track */
328 1
		$track = $this->trackBusinessLayer->find($trackId, $this->userId);
329 1
		return new JSONResponse($track->toAPI($this->urlGenerator));
330
	}
331
332
	/**
333
	 * @NoAdminRequired
334
	 * @NoCSRFRequired
335
	 */
336 1
	public function trackByFileId($fileId) {
337 1
		$track = $this->trackBusinessLayer->findByFileId($fileId, $this->userId);
338 1
		if ($track !== null) {
339 1
			return new JSONResponse($track->toCollection($this->l10n));
340
		} else {
341
			return new ErrorResponse(Http::STATUS_NOT_FOUND);
342
		}
343
	}
344
345
	/**
346
	 * @NoAdminRequired
347
	 * @NoCSRFRequired
348
	 */
349
	public function getScanState() {
350
		return new JSONResponse([
351
			'unscannedFiles' => $this->scanner->getUnscannedMusicFileIds($this->userId),
352
			'scannedCount' => $this->trackBusinessLayer->count($this->userId)
353
		]);
354
	}
355
356
	/**
357
	 * @NoAdminRequired
358
	 * @UseSession to keep the session reserved while execution in progress
359
	 */
360
	public function scan($files, $finalize) {
361
		// extract the parameters
362
		$fileIds = \array_map('intval', \explode(',', $files));
363
		$finalize = \filter_var($finalize, FILTER_VALIDATE_BOOLEAN);
364
365
		$filesScanned = $this->scanner->scanFiles($this->userId, $this->userFolder, $fileIds);
366
367
		$coversUpdated = false;
368
		if ($finalize) {
369
			$coversUpdated = $this->scanner->findAlbumCovers($this->userId)
370
							|| $this->scanner->findArtistCovers($this->userId);
371
			$totalCount = $this->trackBusinessLayer->count($this->userId);
372
			$this->logger->log("Scanning finished, user $this->userId has $totalCount scanned tracks in total", 'info');
373
		}
374
375
		return new JSONResponse([
376
			'filesScanned' => $filesScanned,
377
			'coversUpdated' => $coversUpdated
378
		]);
379
	}
380
381
	/**
382
	 * @NoAdminRequired
383
	 * @UseSession to keep the session reserved while execution in progress
384
	 */
385
	public function resetScanned() {
386
		$this->maintenance->resetDb($this->userId);
387
		return new JSONResponse(['success' => true]);
388
	}
389
390
	/**
391
	 * @NoAdminRequired
392
	 * @NoCSRFRequired
393
	 */
394
	public function download($fileId) {
395
		$track = $this->trackBusinessLayer->findByFileId($fileId, $this->userId);
396
		if ($track === null) {
397
			return new ErrorResponse(Http::STATUS_NOT_FOUND, 'track not found');
398
		}
399
400
		$nodes = $this->userFolder->getById($track->getFileId());
401
		if (\count($nodes) > 0) {
402
			// get the first valid node
403
			$node = $nodes[0];
404
405
			$mime = $node->getMimeType();
406
			$content = $node->getContent();
407
			return new FileResponse(['mimetype' => $mime, 'content' => $content]);
408
		}
409
410
		return new ErrorResponse(Http::STATUS_NOT_FOUND, 'file not found');
411
	}
412
413
	/**
414
	 * @NoAdminRequired
415
	 * @NoCSRFRequired
416
	 */
417
	public function filePath($fileId) {
418
		$nodes = $this->userFolder->getById($fileId);
419
		if (\count($nodes) == 0) {
420
			return new ErrorResponse(Http::STATUS_NOT_FOUND);
421
		} else {
422
			$node = $nodes[0];
423
			$path = $this->userFolder->getRelativePath($node->getPath());
424
			return new JSONResponse(['path' => Util::urlEncodePath($path)]);
425
		}
426
	}
427
428
	/**
429
	 * @NoAdminRequired
430
	 * @NoCSRFRequired
431
	 */
432
	public function fileInfo($fileId) {
433
		$info = $this->scanner->getFileInfo($fileId, $this->userId, $this->userFolder);
434
		if ($info) {
435
			return new JSONResponse($info);
436
		} else {
437
			return new ErrorResponse(Http::STATUS_NOT_FOUND);
438
		}
439
	}
440
441
	/**
442
	 * @NoAdminRequired
443
	 * @NoCSRFRequired
444
	 */
445
	public function fileDetails($fileId) {
446
		$details = $this->detailsHelper->getDetails($fileId, $this->userFolder);
447
		if ($details) {
448
			return new JSONResponse($details);
449
		} else {
450
			return new ErrorResponse(Http::STATUS_NOT_FOUND);
451
		}
452
	}
453
454
	/**
455
	 * @NoAdminRequired
456
	 * @NoCSRFRequired
457
	 */
458
	public function artistDetails($artistIdOrSlug) {
459
		try {
460
			$artistId = $this->getIdFromSlug($artistIdOrSlug);
461
			$info = $this->lastfmService->getArtistInfo($artistId, $this->userId);
462
			return new JSONResponse($info);
463
		}
464
		catch (BusinessLayerException $e) {
465
			return new ErrorResponse(Http::STATUS_NOT_FOUND);
466
		}
467
	}
468
469
	/**
470
	 * @NoAdminRequired
471
	 * @NoCSRFRequired
472
	 */
473
	public function albumCover($albumIdOrSlug) {
474
		$albumId = $this->getIdFromSlug($albumIdOrSlug);
475
		$album = $this->albumBusinessLayer->find($albumId, $this->userId);
476
		return $this->cover($album);
477
	}
478
479
	/**
480
	 * @NoAdminRequired
481
	 * @NoCSRFRequired
482
	 */
483
	public function artistCover($artistIdOrSlug, $originalSize) {
484
		$originalSize = \filter_var($originalSize, FILTER_VALIDATE_BOOLEAN);
485
486
		$artistId = $this->getIdFromSlug($artistIdOrSlug);
487
		$artist = $this->artistBusinessLayer->find($artistId, $this->userId);
488
489
		if ($originalSize) {
490
			$cover = $this->coverHelper->getCover(
491
					$artist, $this->userId, $this->userFolder, CoverHelper::DO_NOT_CROP_OR_SCALE);
492
			if ($cover !== null) {
493
				return new FileResponse($cover);
494
			} else {
495
				return new ErrorResponse(Http::STATUS_NOT_FOUND);
496
			}
497
		}
498
		else {
499
			return $this->cover($artist);
500
		}
501
	}
502
503
	private function cover($entity) {
504
		$coverAndHash = $this->coverHelper->getCoverAndHash($entity, $this->userId, $this->userFolder);
505
506
		if ($coverAndHash['hash'] !== null) {
507
			// Cover is in cache. Return a redirection response so that the client
508
			// will fetch the content through a cacheable route.
509
			$link = $this->urlGenerator->linkToRoute('music.api.cachedCover', ['hash' => $coverAndHash['hash']]);
510
			return new RedirectResponse($link);
511
		} else if ($coverAndHash['data'] !== null) {
512
			return new FileResponse($coverAndHash['data']);
513
		} else {
514
			return new ErrorResponse(Http::STATUS_NOT_FOUND);
515
		}
516
	}
517
518
	/**
519
	 * @NoAdminRequired
520
	 * @NoCSRFRequired
521
	 */
522
	public function cachedCover($hash) {
523
		$coverData = $this->coverHelper->getCoverFromCache($hash, $this->userId);
524
525
		if ($coverData !== null) {
526
			$response =  new FileResponse($coverData);
527
			// instruct also the client-side to cache the result, this is safe
528
			// as the resource URI contains the image hash
529
			self::setClientCaching($response);
530
			return $response;
531
		} else {
532
			return new ErrorResponse(Http::STATUS_NOT_FOUND);
533
		}
534
	}
535
536
	private static function setClientCaching(&$httpResponse, $days=365) {
537
		$httpResponse->cacheFor($days * 24 * 60 * 60);
538
		$httpResponse->addHeader('Pragma', 'cache');
539
	}
540
}
541