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