Passed
Push — master ( 458bc4...32b27b )
by Pauli
03:16
created

ShivaApiController::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 17
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 8
nc 1
nop 9
dl 0
loc 17
rs 10
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 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 Morris Jobke <[email protected]>
10
 * @author Pauli Järvinen <[email protected]>
11
 * @copyright Morris Jobke 2013, 2014
12
 * @copyright Pauli Järvinen 2017 - 2025
13
 */
14
15
namespace OCA\Music\Controller;
16
17
use OCP\AppFramework\Controller;
18
use OCP\AppFramework\Http;
19
use OCP\AppFramework\Http\JSONResponse;
20
use OCP\IL10N;
21
use OCP\IRequest;
22
use OCP\IURLGenerator;
23
24
use OCA\Music\AppFramework\BusinessLayer\BusinessLayer;
25
use OCA\Music\AppFramework\BusinessLayer\BusinessLayerException;
26
use OCA\Music\AppFramework\Core\Logger;
27
use OCA\Music\BusinessLayer\AlbumBusinessLayer;
28
use OCA\Music\BusinessLayer\ArtistBusinessLayer;
29
use OCA\Music\BusinessLayer\TrackBusinessLayer;
30
use OCA\Music\Db\Album;
31
use OCA\Music\Db\Artist;
32
use OCA\Music\Db\SortBy;
33
use OCA\Music\Db\Track;
34
use OCA\Music\Http\ErrorResponse;
35
use OCA\Music\Utility\Random;
36
37
class ShivaApiController extends Controller {
38
39
	private IL10N $l10n;
40
	private TrackBusinessLayer $trackBusinessLayer;
41
	private ArtistBusinessLayer $artistBusinessLayer;
42
	private AlbumBusinessLayer $albumBusinessLayer;
43
	private string $userId;
44
	private IURLGenerator $urlGenerator;
45
	private Logger $logger;
46
47
	public function __construct(string $appname,
48
								IRequest $request,
49
								IURLGenerator $urlGenerator,
50
								TrackBusinessLayer $trackBusinessLayer,
51
								ArtistBusinessLayer $artistBusinessLayer,
52
								AlbumBusinessLayer $albumBusinessLayer,
53
								?string $userId, // null if this gets called after the user has logged out
54
								IL10N $l10n,
55
								Logger $logger) {
56
		parent::__construct($appname, $request);
57
		$this->l10n = $l10n;
58
		$this->trackBusinessLayer = $trackBusinessLayer;
59
		$this->artistBusinessLayer = $artistBusinessLayer;
60
		$this->albumBusinessLayer = $albumBusinessLayer;
61
		$this->userId = $userId ?? '';
62
		$this->urlGenerator = $urlGenerator;
63
		$this->logger = $logger;
64
	}
65
66
	private static function shivaPageToLimits(?int $pageSize, ?int $page) : array {
67
		if (\is_int($page) && \is_int($pageSize) && $page > 0 && $pageSize > 0) {
68
			$limit = $pageSize;
69
			$offset = ($page - 1) * $pageSize;
70
		} else {
71
			$limit = $offset = null;
72
		}
73
		return [$limit, $offset];
74
	}
75
76
	/**
77
	 * @NoAdminRequired
78
	 * @NoCSRFRequired
79
	 */
80
	public function artists($fulltree, $albums, ?int $page_size=null, ?int $page=null) {
81
		$fulltree = \filter_var($fulltree, FILTER_VALIDATE_BOOLEAN);
82
		$includeAlbums = \filter_var($albums, FILTER_VALIDATE_BOOLEAN);
83
		list($limit, $offset) = self::shivaPageToLimits($page_size, $page);
84
85
		/** @var Artist[] $artists */
86
		$artists = $this->artistBusinessLayer->findAll($this->userId, SortBy::Name, $limit, $offset);
87
88
		$artists = \array_map(fn($a) => $this->artistToApi($a, $includeAlbums || $fulltree, $fulltree), $artists);
89
90
		return new JSONResponse($artists);
91
	}
92
93
	/**
94
	 * @NoAdminRequired
95
	 * @NoCSRFRequired
96
	 */
97
	public function artist(int $id, $fulltree) {
98
		$fulltree = \filter_var($fulltree, FILTER_VALIDATE_BOOLEAN);
99
		try {
100
			/** @var Artist $artist */
101
			$artist = $this->artistBusinessLayer->find($id, $this->userId);
102
			$artist = $this->artistToApi($artist, $fulltree, $fulltree);
103
			return new JSONResponse($artist);
104
		} catch (BusinessLayerException $e) {
105
			return new ErrorResponse(Http::STATUS_NOT_FOUND);
106
		}
107
	}
108
109
	/**
110
	 * Return given artist in Shia API format
111
	 * @param Artist $artist
112
	 * @param boolean $includeAlbums
113
	 * @param boolean $includeTracks (ignored if $includeAlbums==false)
114
	 * @return array
115
	 */
116
	private function artistToApi(Artist $artist, bool $includeAlbums, bool $includeTracks) : array {
117
		$artistInApi = $artist->toAPI($this->urlGenerator, $this->l10n);
118
		if ($includeAlbums) {
119
			$artistId = $artist->getId();
120
			$albums = $this->albumBusinessLayer->findAllByArtist($artistId, $this->userId);
121
122
			$artistInApi['albums'] = \array_map(fn($a) => $this->albumToApi($a, $includeTracks, false), $albums);
123
		}
124
		return $artistInApi;
125
	}
126
127
	/**
128
	 * @NoAdminRequired
129
	 * @NoCSRFRequired
130
	 */
131
	public function albums(?int $artist=null, $fulltree=null, ?int $page_size=null, ?int $page=null) {
132
		$fulltree = \filter_var($fulltree, FILTER_VALIDATE_BOOLEAN);
133
		list($limit, $offset) = self::shivaPageToLimits($page_size, $page);
134
135
		if ($artist !== null) {
136
			$albums = $this->albumBusinessLayer->findAllByArtist($artist, $this->userId, $limit, $offset);
137
		} else {
138
			$albums = $this->albumBusinessLayer->findAll($this->userId, SortBy::Name, $limit, $offset);
139
		}
140
141
		$albums = \array_map(fn($a) => $this->albumToApi($a, $fulltree, $fulltree), $albums);
142
143
		return new JSONResponse($albums);
144
	}
145
146
	/**
147
	 * @NoAdminRequired
148
	 * @NoCSRFRequired
149
	 */
150
	public function album(int $id, $fulltree) {
151
		$fulltree = \filter_var($fulltree, FILTER_VALIDATE_BOOLEAN);
152
		try {
153
			$album = $this->albumBusinessLayer->find($id, $this->userId);
154
			$album = $this->albumToApi($album, $fulltree, $fulltree);
155
			return new JSONResponse($album);
156
		} catch (BusinessLayerException $e) {
157
			return new ErrorResponse(Http::STATUS_NOT_FOUND);
158
		}
159
	}
160
161
	/**
162
	 * Return given album in the Shiva API format
163
	 */
164
	private function albumToApi(Album $album, bool $includeTracks, bool $includeArtists) : array {
165
		$albumInApi = $album->toAPI($this->urlGenerator, $this->l10n);
166
167
		if ($includeTracks) {
168
			$albumId = $album->getId();
169
			$tracks = $this->trackBusinessLayer->findAllByAlbum($albumId, $this->userId);
170
			$albumInApi['tracks'] = \array_map(fn($t) => $t->toAPI($this->urlGenerator), $tracks);
171
		}
172
173
		if ($includeArtists) {
174
			$artistIds = $album->getArtistIds();
175
			$artists = $this->artistBusinessLayer->findById($artistIds, $this->userId);
176
			$albumInApi['artists'] = \array_map(fn($a) => $a->toAPI($this->urlGenerator, $this->l10n), $artists);
177
		}
178
179
		return $albumInApi;
180
	}
181
182
	/**
183
	 * @NoAdminRequired
184
	 * @NoCSRFRequired
185
	 */
186
	public function tracks(?int $artist=null, ?int $album=null, $fulltree=null, ?int $page_size=null, ?int $page=null) {
187
		$fulltree = \filter_var($fulltree, FILTER_VALIDATE_BOOLEAN);
188
		list($limit, $offset) = self::shivaPageToLimits($page_size, $page);
189
190
		if ($album !== null) {
191
			$tracks = $this->trackBusinessLayer->findAllByAlbum($album, $this->userId, $artist, $limit, $offset);
192
		} elseif ($artist !== null) {
193
			$tracks = $this->trackBusinessLayer->findAllByArtist($artist, $this->userId, $limit, $offset);
194
		} else {
195
			$tracks = $this->trackBusinessLayer->findAll($this->userId, SortBy::Name, $limit, $offset);
196
		}
197
		foreach ($tracks as &$track) {
198
			$artistId = $track->getArtistId();
199
			$albumId = $track->getAlbumId();
200
			$track = $track->toAPI($this->urlGenerator);
201
			if ($fulltree) {
202
				$artist = $this->artistBusinessLayer->find($artistId, $this->userId);
203
				$track['artist'] = $artist->toAPI($this->urlGenerator, $this->l10n);
204
				$album = $this->albumBusinessLayer->find($albumId, $this->userId);
205
				$track['album'] = $album->toAPI($this->urlGenerator, $this->l10n);
206
			}
207
		}
208
		return new JSONResponse($tracks);
209
	}
210
211
	/**
212
	 * @NoAdminRequired
213
	 * @NoCSRFRequired
214
	 */
215
	public function track(int $id) {
216
		try {
217
			/** @var Track $track */
218
			$track = $this->trackBusinessLayer->find($id, $this->userId);
219
			return new JSONResponse($track->toAPI($this->urlGenerator));
220
		} catch (BusinessLayerException $e) {
221
			return new ErrorResponse(Http::STATUS_NOT_FOUND);
222
		}
223
	}
224
225
	/**
226
	 * @NoAdminRequired
227
	 * @NoCSRFRequired
228
	 */
229
	public function randomArtist() {
230
		return $this->randomItem($this->artistBusinessLayer, 'artist');
231
	}
232
233
	/**
234
	 * @NoAdminRequired
235
	 * @NoCSRFRequired
236
	 */
237
	public function randomAlbum() {
238
		return $this->randomItem($this->albumBusinessLayer, 'album');
239
	}
240
241
	/**
242
	 * @NoAdminRequired
243
	 * @NoCSRFRequired
244
	 */
245
	public function randomTrack() {
246
		return $this->randomItem($this->trackBusinessLayer, 'track');
247
	}
248
249
	private function randomItem(BusinessLayer $businessLayer, string $type) {
250
		$ids = $businessLayer->findAllIds($this->userId);
251
		$id = Random::pickItem($ids);
252
253
		if ($id !== null) {
254
			return new JSONResponse([
255
				'id' => $id,
256
				'uri' => $this->urlGenerator->linkToRoute("music.shivaApi.$type", ['id' => $id])
257
			]);
258
		} else {
259
			return new ErrorResponse(Http::STATUS_NOT_FOUND);
260
		}
261
	}
262
}
263