Completed
Push — scalability_improvements ( 1f54dd...dcfdac )
by Pauli
19:38 queued 05:25
created

ApiController::__construct()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 24
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 24
rs 8.9713
c 0
b 0
f 0
cc 1
eloc 23
nc 1
nop 12

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
 * @copyright Morris Jobke 2013, 2014
11
 */
12
13
namespace OCA\Music\Controller;
14
15
use OCA\Music\Db\Artist;
16
use OCA\Music\Db\Cache;
17
use OCA\Music\Db\Track;
18
use \OCP\AppFramework\Controller;
19
use \OCP\AppFramework\Http;
20
use \OCP\AppFramework\Http\DataDisplayResponse;
21
use \OCP\AppFramework\Http\JSONResponse;
22
use \OCP\AppFramework\Http\Response;
23
use \OCP\Files\Folder;
24
use \OCP\IL10N;
25
use \OCP\IRequest;
26
use \OCP\IURLGenerator;
27
28
use \OCP\AppFramework\Db\DoesNotExistException;
29
30
use \OCA\Music\BusinessLayer\TrackBusinessLayer;
31
use \OCA\Music\BusinessLayer\ArtistBusinessLayer;
32
use \OCA\Music\BusinessLayer\AlbumBusinessLayer;
33
use \OCA\Music\Http\FileResponse;
34
use \OCA\Music\Utility\Scanner;
35
36
37
class ApiController extends Controller {
38
39
	/** @var IL10N */
40
	private $l10n;
41
	/** @var TrackBusinessLayer */
42
	private $trackBusinessLayer;
43
	/** @var ArtistBusinessLayer */
44
	private $artistBusinessLayer;
45
	/** @var AlbumBusinessLayer */
46
	private $albumBusinessLayer;
47
	/** @var Cache */
48
	private $cache;
49
	/** @var Scanner */
50
	private $scanner;
51
	/** @var string */
52
	private $userId;
53
	/** @var IURLGenerator */
54
	private $urlGenerator;
55
	/** @var Folder */
56
	private $userFolder;
57
	/** @var Logger */
58
	private $logger;
59
60
	public function __construct($appname,
61
								IRequest $request,
62
								IURLGenerator $urlGenerator,
63
								TrackBusinessLayer $trackbusinesslayer,
64
								ArtistBusinessLayer $artistbusinesslayer,
65
								AlbumBusinessLayer $albumbusinesslayer,
66
								Cache $cache,
67
								Scanner $scanner,
68
								$userId,
69
								$l10n,
70
								Folder $userFolder,
71
								Logger $logger){
72
		parent::__construct($appname, $request);
73
		$this->l10n = $l10n;
74
		$this->trackBusinessLayer = $trackbusinesslayer;
75
		$this->artistBusinessLayer = $artistbusinesslayer;
76
		$this->albumBusinessLayer = $albumbusinesslayer;
77
		$this->cache = $cache;
78
		$this->scanner = $scanner;
79
		$this->userId = $userId;
80
		$this->urlGenerator = $urlGenerator;
81
		$this->userFolder = $userFolder;
82
		$this->logger = $logger;
83
	}
84
85
	/**
86
	 * Extracts the id from an unique slug (id-slug)
87
	 * @param string $slug the slug
88
	 * @return string the id
89
	 */
90
	protected function getIdFromSlug($slug){
91
		$split = explode('-', $slug, 2);
92
93
		return $split[0];
94
	}
95
96
	/**
97
	 * @NoAdminRequired
98
	 * @NoCSRFRequired
99
	 */
100
	public function collection() {
101
		$collectionJson = $this->cache->get($this->userId, 'collection');
102
103
		if ($collectionJson == null) {
104
			$collectionJson = $this->buildCollectionJson();
105
			$this->cache->add($this->userId, 'collection', $collectionJson);
106
		}
107
		return new DataDisplayResponse($collectionJson);
108
	}
109
110
	private function buildCollectionJson() {
111
		/** @var Artist[] $allArtists */
112
		$allArtists = $this->artistBusinessLayer->findAll($this->userId);
113
		$allArtistsByIdAsObj = array();
114
		$allArtistsByIdAsArr = array();
115
		foreach ($allArtists as &$artist) {
116
			$allArtistsByIdAsObj[$artist->getId()] = $artist;
117
			$allArtistsByIdAsArr[$artist->getId()] = $artist->toCollection($this->l10n);
118
		}
119
		
120
		$allAlbums = $this->albumBusinessLayer->findAll($this->userId);
121
		$allAlbumsByIdAsObj = array();
122
		$allAlbumsByIdAsArr = array();
123
		foreach ($allAlbums as &$album) {
124
			$allAlbumsByIdAsObj[$album->getId()] = $album;
125
			$allAlbumsByIdAsArr[$album->getId()] = $album->toCollection($this->urlGenerator, $this->l10n);
126
		}
127
128
		/** @var Track[] $allTracks */
129
		$allTracks = $this->trackBusinessLayer->findAll($this->userId);
130
131
		$artists = array();
132
		foreach ($allTracks as $track) {
133
			$albumObj = $allAlbumsByIdAsObj[$track->getAlbumId()];
134
			$trackArtistObj = $allArtistsByIdAsObj[$track->getArtistId()];
135
			$track->setAlbum($albumObj);
136
			$track->setArtist($trackArtistObj);
137
138
			$albumArtist = &$allArtistsByIdAsArr[$albumObj->getAlbumArtistId()];
139
			if (!isset($albumArtist['albums'])) {
140
				$albumArtist['albums'] = array();
141
				$artists[] = &$albumArtist;
142
			}
143
			$album = &$allAlbumsByIdAsArr[$track->getAlbumId()];
144
			if (!isset($album['tracks'])) {
145
				$album['tracks'] = array();
146
				$albumArtist['albums'][] = &$album;
147
			}
148
			try {
149
				$album['tracks'][] = $track->toCollection($this->urlGenerator, $this->userFolder, $this->l10n);
150
			} catch (\OCP\Files\NotFoundException $e) {
151
				//ignore not found
152
			}
153
		}
154
		return json_encode($artists);
155
	}
156
157
	/**
158
	 * @NoAdminRequired
159
	 * @NoCSRFRequired
160
	 */
161
	public function artists() {
162
		$fulltree = filter_var($this->params('fulltree'), FILTER_VALIDATE_BOOLEAN);
163
		$includeAlbums = filter_var($this->params('albums'), FILTER_VALIDATE_BOOLEAN);
164
		/** @var Artist[] $artists */
165
		$artists = $this->artistBusinessLayer->findAll($this->userId);
166
		foreach($artists as &$artist) {
167
			$artist = $artist->toAPI($this->urlGenerator, $this->l10n);
168
			if($fulltree || $includeAlbums) {
169
				$artistId = $artist['id'];
170
				$albums = $this->albumBusinessLayer->findAllByArtist($artistId, $this->userId);
171
				foreach($albums as &$album) {
172
					$album = $album->toAPI($this->urlGenerator, $this->l10n);
173
					if($fulltree) {
174
						$albumId = $album['id'];
175
						$tracks = $this->trackBusinessLayer->findAllByAlbum($albumId, $this->userId, $artistId);
176
						foreach($tracks as &$track) {
177
							$track = $track->toAPI($this->urlGenerator);
178
						}
179
						$album['tracks'] = $tracks;
180
					}
181
				}
182
				$artist['albums'] = $albums;
183
			}
184
		}
185
		return new JSONResponse($artists);
186
	}
187
188
	/**
189
	 * @NoAdminRequired
190
	 * @NoCSRFRequired
191
	 */
192 View Code Duplication
	public function artist() {
193
		$fulltree = filter_var($this->params('fulltree'), FILTER_VALIDATE_BOOLEAN);
194
		$artistId = $this->getIdFromSlug($this->params('artistIdOrSlug'));
195
		/** @var Artist $artist */
196
		$artist = $this->artistBusinessLayer->find($artistId, $this->userId);
197
		$artist = $artist->toAPI($this->urlGenerator, $this->l10n);
198
		if($fulltree) {
199
			$artistId = $artist['id'];
200
			$albums = $this->albumBusinessLayer->findAllByArtist($artistId, $this->userId);
201
			foreach($albums as &$album) {
202
				$album = $album->toAPI($this->urlGenerator, $this->l10n);
203
				$albumId = $album['id'];
204
				$tracks = $this->trackBusinessLayer->findAllByAlbum($albumId, $this->userId, $artistId);
205
				foreach($tracks as &$track) {
206
					$track = $track->toAPI($this->urlGenerator);
207
				}
208
				$album['tracks'] = $tracks;
209
			}
210
			$artist['albums'] = $albums;
211
		}
212
		return new JSONResponse($artist);
213
	}
214
215
	/**
216
	 * @NoAdminRequired
217
	 * @NoCSRFRequired
218
	 */
219
	public function albums() {
220
		$fulltree = filter_var($this->params('fulltree'), FILTER_VALIDATE_BOOLEAN);
221
		$albums = $this->albumBusinessLayer->findAll($this->userId);
222
		foreach($albums as &$album) {
223
			$artistIds = $album->getArtistIds();
224
			$album = $album->toAPI($this->urlGenerator, $this->l10n);
225
			if($fulltree) {
226
				$albumId = $album['id'];
227
				$tracks = $this->trackBusinessLayer->findAllByAlbum($albumId, $this->userId);
228
				foreach($tracks as &$track) {
229
					$track = $track->toAPI($this->urlGenerator);
230
				}
231
				$album['tracks'] = $tracks;
232
				$artists = $this->artistBusinessLayer->findMultipleById($artistIds, $this->userId);
233
				foreach($artists as &$artist) {
234
					$artist = $artist->toAPI($this->urlGenerator, $this->l10n);
235
				}
236
				$album['artists'] = $artists;
237
			}
238
		}
239
		return new JSONResponse($albums);
240
	}
241
242
	/**
243
	 * @NoAdminRequired
244
	 * @NoCSRFRequired
245
	 */
246 View Code Duplication
	public function album() {
247
		$fulltree = filter_var($this->params('fulltree'), FILTER_VALIDATE_BOOLEAN);
248
		$albumId = $this->getIdFromSlug($this->params('albumIdOrSlug'));
249
		$album = $this->albumBusinessLayer->find($albumId, $this->userId);
250
251
		$artistIds = $album->getArtistIds();
252
		$album = $album->toAPI($this->urlGenerator, $this->l10n);
253
		if($fulltree) {
254
			$albumId = $album['id'];
255
			$tracks = $this->trackBusinessLayer->findAllByAlbum($albumId, $this->userId);
256
			foreach($tracks as &$track) {
257
				$track = $track->toAPI($this->urlGenerator);
258
			}
259
			$album['tracks'] = $tracks;
260
			$artists = $this->artistBusinessLayer->findMultipleById($artistIds, $this->userId);
261
			foreach($artists as &$artist) {
262
				$artist = $artist->toAPI($this->urlGenerator, $this->l10n);
263
			}
264
			$album['artists'] = $artists;
265
		}
266
267
		return new JSONResponse($album);
268
	}
269
270
	/**
271
	 * @NoAdminRequired
272
	 * @NoCSRFRequired
273
	 */
274
	public function tracks() {
275
		$fulltree = filter_var($this->params('fulltree'), FILTER_VALIDATE_BOOLEAN);
276
		if($artistId = $this->params('artist')) {
277
			$tracks = $this->trackBusinessLayer->findAllByArtist($artistId, $this->userId);
278
		} elseif($albumId = $this->params('album')) {
279
			$tracks = $this->trackBusinessLayer->findAllByAlbum($albumId, $this->userId);
280
		} else {
281
			$tracks = $this->trackBusinessLayer->findAll($this->userId);
282
		}
283
		foreach($tracks as &$track) {
284
			$artistId = $track->getArtistId();
285
			$albumId = $track->getAlbumId();
286
			$track = $track->toAPI($this->urlGenerator);
287
			if($fulltree) {
288
				/** @var Artist $artist */
289
				$artist = $this->artistBusinessLayer->find($artistId, $this->userId);
290
				$track['artist'] = $artist->toAPI($this->urlGenerator, $this->l10n);
291
				$album = $this->albumBusinessLayer->find($albumId, $this->userId);
292
				$track['album'] = $album->toAPI($this->urlGenerator, $this->l10n);
293
			}
294
		}
295
		return new JSONResponse($tracks);
296
	}
297
298
	/**
299
	 * @NoAdminRequired
300
	 * @NoCSRFRequired
301
	 */
302
	public function track() {
303
		$trackId = $this->getIdFromSlug($this->params('trackIdOrSlug'));
304
		/** @var Track $track */
305
		$track = $this->trackBusinessLayer->find($trackId, $this->userId);
306
		return new JSONResponse($track->toAPI($this->urlGenerator));
307
	}
308
309
	/**
310
	 * @NoAdminRequired
311
	 * @NoCSRFRequired
312
	 */
313
	public function trackByFileId() {
314
		$fileId = $this->params('fileId');
315
		$track = $this->trackBusinessLayer->findByFileId($fileId, $this->userId);
316
		$track->setAlbum($this->albumBusinessLayer->find($track->getAlbumId(), $this->userId));
317
		$track->setArtist($this->artistBusinessLayer->find($track->getArtistId(), $this->userId));
318
		return new JSONResponse($track->toCollection($this->urlGenerator, $this->userFolder, $this->l10n));
319
	}
320
321
	/**
322
	 * @NoAdminRequired
323
	 */
324
	public function getScanState() {
325
		return new JSONResponse([
326
			'unscannedFiles' => $this->scanner->getUnscannedMusicFileIds($this->userId, $this->userFolder),
327
			'scannedCount' => count($this->scanner->getScannedFiles($this->userId))
328
		]);
329
	}
330
331
	/**
332
	 * @NoAdminRequired
333
	 */
334
	public function scan() {
335
		// extract the parameters
336
		$fileIds = array_map('intval', explode(',', $this->params('files')));
337
		$finalize = filter_var($this->params('finalize'), FILTER_VALIDATE_BOOLEAN);
338
339
		$filesScanned = $this->scanner->scanFiles($this->userId, $this->userFolder, $fileIds);
340
341
		$coversUpdated = false;
342
		if ($finalize) {
343
			$coversUpdated = $this->scanner->findCovers();
344
			$totalCount = count($this->scanner->getScannedFiles($this->userId));
345
			$this->logger->log("Scanning finished, user $this->userId has $totalCount scanned tracks in total", 'info');
346
		}
347
348
		return new JSONResponse([
349
			'filesScanned' => $filesScanned,
350
			'coversUpdated' => $coversUpdated
351
		]);
352
	}
353
354
	/**
355
	 * @NoAdminRequired
356
	 * @NoCSRFRequired
357
	 */
358
	public function download() {
359
		// we no longer need the session to be kept open
360
		session_write_close();
361
362
		$fileId = $this->params('fileId');
363
364
		try {
365
			$track = $this->trackBusinessLayer->findByFileId($fileId, $this->userId);
366
		} catch(DoesNotExistException $e) {
367
			$r = new Response();
368
			$r->setStatus(Http::STATUS_NOT_FOUND);
369
			return $r;
370
		}
371
372
		$nodes = $this->userFolder->getById($track->getFileId());
373
		if(count($nodes) > 0 ) {
374
			// get the first valid node
375
			$node = $nodes[0];
376
377
			$mime = $node->getMimeType();
378
			$content = $node->getContent();
379
			return new FileResponse(array('mimetype' => $mime, 'content' => $content));
380
		}
381
382
		$r = new Response();
383
		$r->setStatus(Http::STATUS_NOT_FOUND);
384
		return $r;
385
	}
386
387
	/**
388
	 * @NoAdminRequired
389
	 * @NoCSRFRequired
390
	 */
391
	public function cover() {
392
		// we no longer need the session to be kept open
393
		session_write_close();
394
395
		$albumId = $this->getIdFromSlug($this->params('albumIdOrSlug'));
396
		$album = $this->albumBusinessLayer->find($albumId, $this->userId);
397
398
		$nodes = $this->userFolder->getById($album->getCoverFileId());
399
		if(count($nodes) > 0 ) {
400
			// get the first valid node
401
			$node = $nodes[0];
402
			$mime = $node->getMimeType();
403
404
			if (0 === strpos($mime, 'audio')) { // embedded cover image
405
				$cover = $this->scanner->parseEmbeddedCoverArt($node);
406
407
				if($cover != null) {
408
					return new FileResponse(array(
409
							'mimetype' => $cover["image_mime"],
410
							'content' => $cover["data"]
411
					));
412
				}
413
			}
414
			else { // separate image file
415
				$content = $node->getContent();
416
				return new FileResponse(array('mimetype' => $mime, 'content' => $content));
417
			}
418
		}
419
420
		$r = new Response();
421
		$r->setStatus(Http::STATUS_NOT_FOUND);
422
		return $r;
423
	}
424
}
425