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 \OCP\AppFramework\Controller; |
16
|
|
|
use \OCP\AppFramework\Http; |
17
|
|
|
use \OCP\AppFramework\Http\JSONResponse; |
18
|
|
|
use \OCP\AppFramework\Db\DoesNotExistException; |
19
|
|
|
|
20
|
|
|
use \OCP\IRequest; |
21
|
|
|
use \OCP\IURLGenerator; |
22
|
|
|
use \OCP\Files\Folder; |
23
|
|
|
|
24
|
|
|
use \OCA\Music\BusinessLayer\AlbumBusinessLayer; |
25
|
|
|
use \OCA\Music\BusinessLayer\ArtistBusinessLayer; |
26
|
|
|
use \OCA\Music\BusinessLayer\PlaylistBusinessLayer; |
27
|
|
|
use \OCA\Music\BusinessLayer\TrackBusinessLayer; |
28
|
|
|
use \OCA\Music\Db\Playlist; |
29
|
|
|
use \OCA\Music\Utility\APISerializer; |
30
|
|
|
|
31
|
|
|
class PlaylistApiController extends Controller { |
32
|
|
|
|
33
|
|
|
private $playlistBusinessLayer; |
34
|
|
|
private $userId; |
35
|
|
|
private $userFolder; |
36
|
|
|
private $artistBusinessLayer; |
37
|
|
|
private $albumBusinessLayer; |
38
|
|
|
private $trackBusinessLayer; |
39
|
|
|
private $urlGenerator; |
40
|
|
|
private $l10n; |
41
|
|
|
|
42
|
|
View Code Duplication |
public function __construct($appname, |
|
|
|
|
43
|
|
|
IRequest $request, |
44
|
|
|
IURLGenerator $urlGenerator, |
45
|
|
|
PlaylistBusinessLayer $playlistBusinessLayer, |
46
|
|
|
ArtistBusinessLayer $artistBusinessLayer, |
47
|
|
|
AlbumBusinessLayer $albumBusinessLayer, |
48
|
|
|
TrackBusinessLayer $trackBusinessLayer, |
49
|
|
|
Folder $userFolder, |
50
|
|
|
$userId, |
51
|
|
|
$l10n){ |
52
|
|
|
parent::__construct($appname, $request); |
53
|
|
|
$this->userId = $userId; |
54
|
|
|
$this->userFolder = $userFolder; |
55
|
|
|
$this->urlGenerator = $urlGenerator; |
56
|
|
|
$this->playlistBusinessLayer = $playlistBusinessLayer; |
57
|
|
|
$this->artistBusinessLayer = $artistBusinessLayer; |
58
|
|
|
$this->albumBusinessLayer = $albumBusinessLayer; |
59
|
|
|
$this->trackBusinessLayer = $trackBusinessLayer; |
60
|
|
|
$this->l10n = $l10n; |
61
|
|
|
} |
62
|
|
|
|
63
|
|
|
/** |
64
|
|
|
* lists all playlists |
65
|
|
|
* |
66
|
|
|
* @NoAdminRequired |
67
|
|
|
* @NoCSRFRequired |
68
|
|
|
*/ |
69
|
|
|
public function getAll() { |
70
|
|
|
$playlists = $this->playlistBusinessLayer->findAll($this->userId); |
71
|
|
|
$serializer = new APISerializer(); |
72
|
|
|
|
73
|
|
|
return $serializer->serialize($playlists); |
74
|
|
|
} |
75
|
|
|
|
76
|
|
|
/** |
77
|
|
|
* creates a playlist |
78
|
|
|
* |
79
|
|
|
* @NoAdminRequired |
80
|
|
|
* @NoCSRFRequired |
81
|
|
|
*/ |
82
|
|
|
public function create() { |
83
|
|
|
$playlist = $this->playlistBusinessLayer->create($this->params('name'), $this->userId); |
84
|
|
|
|
85
|
|
|
// add trackIds to the newly created playlist if provided |
86
|
|
|
if (!empty($this->params('trackIds'))){ |
87
|
|
|
$playlist = $this->playlistBusinessLayer->addTracks( |
88
|
|
|
$this->paramArray('trackIds'), $playlist->getId(), $this->userId); |
89
|
|
|
} |
90
|
|
|
|
91
|
|
|
return $playlist->toAPI(); |
92
|
|
|
} |
93
|
|
|
|
94
|
|
|
/** |
95
|
|
|
* deletes a playlist |
96
|
|
|
* @param int $id playlist ID |
97
|
|
|
* |
98
|
|
|
* @NoAdminRequired |
99
|
|
|
* @NoCSRFRequired |
100
|
|
|
*/ |
101
|
|
|
public function delete($id) { |
102
|
|
|
$this->playlistBusinessLayer->delete($id, $this->userId); |
103
|
|
|
return array(); |
104
|
|
|
} |
105
|
|
|
|
106
|
|
|
/** |
107
|
|
|
* lists a single playlist |
108
|
|
|
* @param int $id playlist ID |
109
|
|
|
* |
110
|
|
|
* @NoAdminRequired |
111
|
|
|
* @NoCSRFRequired |
112
|
|
|
*/ |
113
|
|
|
public function get($id) { |
114
|
|
|
try { |
115
|
|
|
$playlist = $this->playlistBusinessLayer->find($id, $this->userId); |
116
|
|
|
|
117
|
|
|
$fulltree = filter_var($this->params('fulltree'), FILTER_VALIDATE_BOOLEAN); |
118
|
|
|
if ($fulltree) { |
119
|
|
|
return $this->toFullTree($playlist); |
120
|
|
|
} else { |
121
|
|
|
return $playlist->toAPI(); |
122
|
|
|
} |
123
|
|
|
|
124
|
|
|
} catch(DoesNotExistException $ex) { |
|
|
|
|
125
|
|
|
return new JSONResponse(array('message' => $ex->getMessage()), |
126
|
|
|
Http::STATUS_NOT_FOUND); |
127
|
|
|
} |
128
|
|
|
} |
129
|
|
|
|
130
|
|
|
private function toFullTree($playlist) { |
131
|
|
|
$songs = []; |
132
|
|
|
|
133
|
|
|
// Get all track information for all the tracks of the playlist |
134
|
|
|
foreach($playlist->getTrackIdsAsArray() as $trackId) { |
135
|
|
|
$song = $this->trackBusinessLayer->find($trackId, $this->userId); |
136
|
|
|
$song->setAlbum($this->albumBusinessLayer->find($song->getAlbumId(), $this->userId)); |
137
|
|
|
$song->setArtist($this->artistBusinessLayer->find($song->getArtistId(), $this->userId)); |
138
|
|
|
$songs[] = $song->toCollection($this->urlGenerator, $this->userFolder, $this->l10n); |
139
|
|
|
} |
140
|
|
|
|
141
|
|
|
return array( |
142
|
|
|
'name' => $playlist->getName(), |
143
|
|
|
'tracks' => $songs, |
144
|
|
|
'id' => $playlist->getId(), |
145
|
|
|
); |
146
|
|
|
} |
147
|
|
|
|
148
|
|
|
/** |
149
|
|
|
* update a playlist |
150
|
|
|
* @param int $id playlist ID |
151
|
|
|
* |
152
|
|
|
* @NoAdminRequired |
153
|
|
|
* @NoCSRFRequired |
154
|
|
|
*/ |
155
|
|
|
public function update($id) { |
156
|
|
|
return $this->modifyPlaylist('rename', [$this->params('name'), $id, $this->userId]); |
157
|
|
|
} |
158
|
|
|
|
159
|
|
|
/** |
160
|
|
|
* add tracks to a playlist |
161
|
|
|
* @param int $id playlist ID |
162
|
|
|
* |
163
|
|
|
* @NoAdminRequired |
164
|
|
|
* @NoCSRFRequired |
165
|
|
|
*/ |
166
|
|
|
public function addTracks($id) { |
167
|
|
|
return $this->modifyPlaylist('addTracks', [$this->paramArray('trackIds'), $id, $this->userId]); |
168
|
|
|
} |
169
|
|
|
|
170
|
|
|
/** |
171
|
|
|
* removes tracks from a playlist |
172
|
|
|
* @param int $id playlist ID |
173
|
|
|
* |
174
|
|
|
* @NoAdminRequired |
175
|
|
|
* @NoCSRFRequired |
176
|
|
|
*/ |
177
|
|
|
public function removeTracks($id) { |
178
|
|
|
return $this->modifyPlaylist('removeTracks', [$this->paramArray('indices'), $id, $this->userId]); |
179
|
|
|
} |
180
|
|
|
|
181
|
|
|
/** |
182
|
|
|
* moves single track on playlist to a new position |
183
|
|
|
* @param int $id playlist ID |
184
|
|
|
* |
185
|
|
|
* @NoAdminRequired |
186
|
|
|
* @NoCSRFRequired |
187
|
|
|
*/ |
188
|
|
|
public function reorder($id) { |
189
|
|
|
return $this->modifyPlaylist('moveTrack', |
190
|
|
|
[$this->params('fromIndex'), $this->params('toIndex'), $id, $this->userId]); |
191
|
|
|
} |
192
|
|
|
|
193
|
|
|
/** |
194
|
|
|
* Modify playlist by calling a supplied method from PlaylistBusinessLayer |
195
|
|
|
* @param string funcName Name of a function to call from PlaylistBusinessLayer |
196
|
|
|
* @param array $funcParams Parameters to pass to the function 'funcName' |
197
|
|
|
* @return \OCP\AppFramework\Http\JSONResponse JSON representation of the modified playlist |
198
|
|
|
*/ |
199
|
|
|
private function modifyPlaylist($funcName, $funcParams) { |
200
|
|
|
try { |
201
|
|
|
$playlist = call_user_func_array([$this->playlistBusinessLayer, $funcName], $funcParams); |
202
|
|
|
return $playlist->toAPI(); |
203
|
|
|
} catch(DoesNotExistException $ex) { |
|
|
|
|
204
|
|
|
return new JSONResponse(array('message' => $ex->getMessage()), |
205
|
|
|
Http::STATUS_NOT_FOUND); |
206
|
|
|
} |
207
|
|
|
} |
208
|
|
|
|
209
|
|
|
/** |
210
|
|
|
* Get integer array passed as parameter to the Playlist API |
211
|
|
|
* @param string $name Name of the parameter |
212
|
|
|
* @return int[] |
213
|
|
|
*/ |
214
|
|
|
private function paramArray($name) { |
215
|
|
|
$array = array(); |
216
|
|
|
foreach (explode(',', $this->params($name)) as $item) { |
217
|
|
|
$array[] = (int) $item; |
218
|
|
|
} |
219
|
|
|
return $array; |
220
|
|
|
} |
221
|
|
|
} |
222
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.