Passed
Push — master ( d62d52...23afda )
by Pauli
03:02
created

AmpacheImageController::setClientCaching()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
c 0
b 0
f 0
nc 1
nop 2
dl 0
loc 3
rs 10
1
<?php declare(strict_types=1);
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 Pauli Järvinen <[email protected]>
10
 * @copyright Pauli Järvinen 2023 - 2025
11
 */
12
13
namespace OCA\Music\Controller;
14
15
use OCA\Music\BusinessLayer\AlbumBusinessLayer;
16
use OCA\Music\BusinessLayer\ArtistBusinessLayer;
17
use OCA\Music\BusinessLayer\PlaylistBusinessLayer;
18
use OCA\Music\AppFramework\BusinessLayer\BusinessLayer;
19
use OCA\Music\AppFramework\BusinessLayer\BusinessLayerException;
20
use OCA\Music\AppFramework\Core\Logger;
21
use OCA\Music\Http\ErrorResponse;
22
use OCA\Music\Http\FileResponse;
23
use OCA\Music\Utility\AmpacheImageService;
24
use OCA\Music\Utility\CoverHelper;
25
use OCA\Music\Utility\LibrarySettings;
26
use OCA\Music\Utility\PlaceholderImage;
27
use OCP\AppFramework\Controller;
28
use OCP\AppFramework\Http;
29
use OCP\AppFramework\Http\Response;
30
use OCP\IRequest;
31
32
class AmpacheImageController extends Controller {
33
	private AmpacheImageService $service;
34
	private CoverHelper $coverHelper;
35
	private LibrarySettings $librarySettings;
36
	private AlbumBusinessLayer $albumBusinessLayer;
37
	private ArtistBusinessLayer $artistBusinessLayer;
38
	private PlaylistBusinessLayer $playlistBusinessLayer;
39
	private Logger $logger;
40
41
	public function __construct(
42
			string $appname,
43
			IRequest $request,
44
			AmpacheImageService $service,
45
			CoverHelper $coverHelper,
46
			LibrarySettings $librarySettings,
47
			AlbumBusinessLayer $albumBusinessLayer,
48
			ArtistBusinessLayer $artistBusinessLayer,
49
			PlaylistBusinessLayer $playlistBusinessLayer,
50
			Logger $logger) {
51
		parent::__construct($appname, $request);
52
		$this->service = $service;
53
		$this->coverHelper = $coverHelper;
54
		$this->librarySettings = $librarySettings;
55
		$this->albumBusinessLayer = $albumBusinessLayer;
56
		$this->artistBusinessLayer = $artistBusinessLayer;
57
		$this->playlistBusinessLayer = $playlistBusinessLayer;
58
		$this->logger = $logger;
59
	}
60
61
	/**
62
	 * @NoAdminRequired
63
	 * @PublicPage
64
	 * @NoCSRFRequired
65
	 * @NoSameSiteCookieRequired
66
	 * @CORS
67
	 */
68
	public function image(?string $token, ?string $object_id, string $object_type='album', ?int $size=null) : Response {
69
		if ($token === null) {
70
			// Workaround for Ample client which uses this kind of call to get the placeholder graphics
71
			$response = new FileResponse(PlaceholderImage::generateForResponse('?', $object_type, 200));
72
			self::setClientCaching($response);
73
			return $response;
74
		}
75
76
		$userId = $this->service->getUserForToken($token, $object_type, (int)$object_id);
77
		if ($userId === null) {
78
			return new ErrorResponse(Http::STATUS_FORBIDDEN, 'invalid token');
79
		}
80
81
		$businessLayer = $this->getBusinessLayer($object_type);
82
		if ($businessLayer === null) {
83
			return new ErrorResponse(Http::STATUS_NOT_FOUND, "invalid object_type $object_type");
84
		}
85
86
		try {
87
			$entity = $businessLayer->find((int)$object_id, $userId);
88
		} catch (BusinessLayerException $e) {
89
			return new ErrorResponse(Http::STATUS_NOT_FOUND, "$object_type $object_id not found");
90
		}
91
92
		$coverImage = $this->coverHelper->getCover($entity, $userId, $this->librarySettings->getFolder($userId), $size);
93
		if ($coverImage === null) {
94
			return new ErrorResponse(Http::STATUS_NOT_FOUND, "$object_type $object_id has no cover image");
95
		}
96
97
		$response = new FileResponse($coverImage);
98
		self::setClientCaching($response, 30);
99
		return $response;
100
	}
101
102
	private function getBusinessLayer(string $object_type) : ?BusinessLayer {
103
		switch ($object_type) {
104
			case 'album':		return $this->albumBusinessLayer;
105
			case 'artist':		return $this->artistBusinessLayer;
106
			case 'playlist':	return $this->playlistBusinessLayer;
107
			default:			return null;
108
		}
109
	}
110
111
	private static function setClientCaching(Response &$httpResponse, int $days=365) : void {
112
		$httpResponse->cacheFor($days * 24 * 60 * 60);
113
		$httpResponse->addHeader('Pragma', 'cache');
114
	}
115
}
116