Completed
Push — php-7.1 ( 77242e...1bf6d8 )
by Pauli
14:40
created

AlbumMapper   A

Complexity

Total Complexity 35

Size/Duplication

Total Lines 299
Duplicated Lines 3.68 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 35
lcom 1
cbo 1
dl 11
loc 299
rs 9
c 1
b 0
f 0

15 Methods

Rating   Name   Duplication   Size   Complexity  
A findAll() 0 5 1
A find() 0 5 1
A __construct() 0 3 1
A makeSelectQuery() 0 7 1
A getAlbumArtistsByAlbumId() 0 14 3
A findAllByArtist() 0 14 1
B findByNameAndYear() 0 16 5
B findAlbum() 0 43 5
A updateFolderCover() 0 12 1
A setCover() 0 7 1
A removeCover() 0 7 1
A getAlbumsWithoutCover() 0 13 2
D findAlbumCover() 0 32 9
A countByArtist() 0 12 1
A findAllByName() 11 11 2

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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\Db;
14
15
use OCP\AppFramework\Db\DoesNotExistException;
16
use OCP\IDBConnection;
17
18
class AlbumMapper extends BaseMapper {
19
20
	public function __construct(IDBConnection $db){
21
		parent::__construct($db, 'music_albums', '\OCA\Music\Db\Album');
22
	}
23
24
	/**
25
	 * @param string $condition
26
	 * @return string
27
	 */
28
	private function makeSelectQuery($condition=null){
29
		return 'SELECT `album`.`name`, `album`.`year`, `album`.`disk`, `album`.`id`, '.
30
			'`album`.`cover_file_id`, `album`.`mbid`, `album`.`disk`, '.
31
			'`album`.`mbid_group`, `album`.`mbid_group`, '.
32
			'`album`.`album_artist_id` FROM `*PREFIX*music_albums` `album`'.
33
			'WHERE `album`.`user_id` = ? ' . $condition;
34
	}
35
36
	/**
37
	 * returns all albums of a user
38
	 *
39
	 * @param string $userId the user ID
40
	 * @return Album[]
41
	 */
42
	public function findAll($userId){
43
		$sql = $this->makeSelectQuery('ORDER BY LOWER(`album`.`name`)');
44
		$params = array($userId);
45
		return $this->findEntities($sql, $params);
46
	}
47
48
	/**
49
	 * finds an album by ID
50
	 *
51
	 * @param integer $albumId ID of the album
52
	 * @param string $userId the user ID
53
	 * @return Album
54
	 */
55
	public function find($albumId, $userId){
56
		$sql = $this->makeSelectQuery('AND `album`.`id` = ?');
57
		$params = array($userId, $albumId);
58
		return $this->findEntity($sql, $params);
59
	}
60
61
	/**
62
	 * returns artist IDs mapped to album IDs
63
	 * does not include album_artist_id
64
	 *
65
	 * @param integer[] $albumIds IDs of the albums
66
	 * @return array the artist IDs of an album are accessible
67
	 * 				by the album ID inside of this array
68
	 */
69
	public function getAlbumArtistsByAlbumId($albumIds){
70
		$sql = 'SELECT DISTINCT `track`.`artist_id`, `track`.`album_id` '.
71
			'FROM `*PREFIX*music_tracks` `track`'.
72
			' WHERE `track`.`album_id` IN ' . $this->questionMarks(count($albumIds));
73
		$result = $this->execute($sql, $albumIds);
74
		$artists = array();
75
		while($row = $result->fetch()){
76
			if(!array_key_exists($row['album_id'], $artists)){
77
				$artists[$row['album_id']] = array();
78
			}
79
			$artists[$row['album_id']][] = $row['artist_id'];
80
		}
81
		return $artists;
82
	}
83
84
	/**
85
	 * returns albums of a specified artist
86
	 * The artist may be an album_artist or the artist of a track
87
	 *
88
	 * @param integer $artistId ID of the artist
89
	 * @param string $userId the user ID
90
	 * @return Album[]
91
	 */
92
	public function findAllByArtist($artistId, $userId){
93
		$sql = 'SELECT `album`.`name`, `album`.`year`, `album`.`id`, '.
94
			'`album`.`cover_file_id`, `album`.`mbid`, `album`.`disk`, '.
95
			'`album`.`mbid_group`, `album`.`mbid_group`, '.
96
			'`album`.`album_artist_id` '.
97
			'FROM `*PREFIX*music_albums` `album` '.
98
			'WHERE `album`.`id` IN (SELECT DISTINCT `album`.`id` FROM '.
99
			'`*PREFIX*music_albums` `album` WHERE `album`.`album_artist_id` = ? AND '.
100
			'`album`.`user_id` = ? UNION SELECT `track`.`album_id` '.
101
			'FROM `*PREFIX*music_tracks` `track` WHERE `track`.`artist_id` = ? AND '.
102
			'`track`.`user_id` = ?) ORDER BY LOWER(`album`.`name`)';
103
		$params = array($artistId, $userId, $artistId, $userId);
104
		return $this->findEntities($sql, $params);
105
	}
106
107
	/**
108
	 * returns album that matches a name and year
109
	 *
110
	 * @param string $albumName name of the album
111
	 * @param string|integer $albumYear year of the album release
112
	 * @param string $userId the user ID
113
	 * @return Album
114
	 */
115
	public function findByNameAndYear($albumName, $albumYear, $userId){
116
		if($albumName === null && $albumYear === null) {
117
			$params = array($userId);
118
			$sql = $this->makeSelectQuery('AND `album`.`name` IS NULL AND `album`.`year` IS NULL');
119
		} else if($albumYear === null) {
120
			$params = array($userId, $albumName);
121
			$sql = $this->makeSelectQuery('AND `album`.`name` = ? AND `album`.`year` IS NULL');
122
		} else if($albumName === null) {
123
			$params = array($userId, $albumYear);
124
			$sql = $this->makeSelectQuery('AND `album`.`name` IS NULL AND `album`.`year` = ?');
125
		} else {
126
			$params = array($userId, $albumName, $albumYear);
127
			$sql = $this->makeSelectQuery('AND `album`.`name` = ? AND `album`.`year` = ?');
128
		}
129
		return $this->findEntity($sql, $params);
130
	}
131
132
	/**
133
	 * returns album that matches a name, a year and an album artist ID
134
	 *
135
	 * @param string|null $albumName name of the album
136
	 * @param string|integer|null $albumYear year of the album release
137
	 * @param string|integer|null $discNumber disk number of this album's disk
138
	 * @param integer|null $albumArtistId ID of the album artist
139
	 * @param string $userId the user ID
140
	 * @return Album[]
141
	 */
142
	public function findAlbum($albumName, $albumYear, $discNumber, $albumArtistId, $userId) {
143
		$sql = 'SELECT `album`.`name`, `album`.`year`, `album`.`disk`, `album`.`id`, '.
144
			'`album`.`cover_file_id`, `album`.`mbid`, `album`.`disk`, '.
145
			'`album`.`mbid_group`, `album`.`mbid_group`, '.
146
			'`album`.`album_artist_id` '.
147
			'FROM `*PREFIX*music_albums` `album` '.
148
			'WHERE `album`.`user_id` = ? ';
149
		$params = array($userId);
150
151
		// add artist id check
152
		if ($albumArtistId === null) {
153
			$sql .= 'AND `album`.`album_artist_id` IS NULL ';
154
		} else {
155
			$sql .= 'AND `album`.`album_artist_id` = ? ';
156
			array_push($params, $albumArtistId);
157
		}
158
159
		// add album name check
160
		if ($albumName === null) {
161
			$sql .= 'AND `album`.`name` IS NULL ';
162
		} else {
163
			$sql .= 'AND `album`.`name` = ? ';
164
			array_push($params, $albumName);
165
		}
166
167
		// add album year check
168
		if ($albumYear === null) {
169
			$sql .= 'AND `album`.`year` IS NULL ';
170
		} else {
171
			$sql .= 'AND `album`.`year` = ? ';
172
			array_push($params, $albumYear);
173
		}
174
175
		// add disc number check
176
		if ($discNumber === null) {
177
			$sql .= 'AND `album`.`disk` IS NULL ';
178
		} else {
179
			$sql .= 'AND `album`.`disk` = ? ';
180
			array_push($params, $discNumber);
181
		}
182
183
		return $this->findEntity($sql, $params);
184
	}
185
186
	/**
187
	 * @param integer $coverFileId
188
	 * @param integer $folderId
189
	 */
190
	public function updateFolderCover($coverFileId, $folderId){
191
		$sql = 'UPDATE `*PREFIX*music_albums`
192
				SET `cover_file_id` = ?
193
				WHERE `cover_file_id` IS NULL AND `id` IN (
194
					SELECT DISTINCT `tracks`.`album_id`
195
					FROM `*PREFIX*music_tracks` `tracks`
196
					JOIN `*PREFIX*filecache` `files` ON `tracks`.`file_id` = `files`.`fileid`
197
					WHERE `files`.`parent` = ?
198
				)';
199
		$params = array($coverFileId, $folderId);
200
		$this->execute($sql, $params);
201
	}
202
203
	/**
204
	 * @param integer $coverFileId
205
	 * @param integer $albumId
206
	 */
207
	public function setCover($coverFileId, $albumId){
208
		$sql = 'UPDATE `*PREFIX*music_albums`
209
				SET `cover_file_id` = ?
210
				WHERE `id` = ?';
211
		$params = array($coverFileId, $albumId);
212
		$this->execute($sql, $params);
213
	}
214
215
	/**
216
	 * @param integer $coverFileId
217
	 */
218
	public function removeCover($coverFileId){
219
		$sql = 'UPDATE `*PREFIX*music_albums`
220
				SET `cover_file_id` = NULL
221
				WHERE `cover_file_id` = ?';
222
		$params = array($coverFileId);
223
		$this->execute($sql, $params);
224
	}
225
226
	/**
227
	 * @return array of [albumId, parentFolderId] pairs
228
	 */
229
	public function getAlbumsWithoutCover(){
230
		$sql = 'SELECT DISTINCT `albums`.`id`, `files`.`parent`
231
				FROM `*PREFIX*music_albums` `albums`
232
				JOIN `*PREFIX*music_tracks` `tracks` ON `albums`.`id` = `tracks`.`album_id`
233
				JOIN `*PREFIX*filecache` `files` ON `tracks`.`file_id` = `files`.`fileid`
234
				WHERE `albums`.`cover_file_id` IS NULL';
235
		$result = $this->execute($sql);
236
		$return = Array();
237
		while($row = $result->fetch()){
238
			array_push($return, Array('albumId' => $row['id'], 'parentFolderId' => $row['parent']));
239
		}
240
		return $return;
241
	}
242
243
	/**
244
	 * @param integer $albumId
245
	 * @param integer $parentFolderId
246
	 */
247
	public function findAlbumCover($albumId, $parentFolderId){
248
		$coverNames = array('cover', 'albumart', 'front', 'folder');
249
		$imagesSql = 'SELECT `fileid`, `name`
250
					FROM `*PREFIX*filecache`
251
					JOIN `*PREFIX*mimetypes` ON `*PREFIX*mimetypes`.`id` = `*PREFIX*filecache`.`mimetype`
252
					WHERE `parent` = ? AND `*PREFIX*mimetypes`.`mimetype` LIKE \'image%\'';
253
		$params = array($parentFolderId);
254
		$result = $this->execute($imagesSql, $params);
255
		$images = $result->fetchAll();
256
		if (count($images)) {
257
			usort($images, function ($imageA, $imageB) use ($coverNames) {
258
				$nameA = strtolower($imageA['name']);
259
				$nameB = strtolower($imageB['name']);
260
				$indexA = PHP_INT_MAX;
261
				$indexB = PHP_INT_MAX;
262
				foreach ($coverNames as $i => $coverName) {
263
					if ($indexA === PHP_INT_MAX && strpos($nameA, $coverName) === 0) {
264
						$indexA = $i;
265
					}
266
					if ($indexB === PHP_INT_MAX && strpos($nameB, $coverName) === 0) {
267
						$indexB = $i;
268
					}
269
					if ($indexA !== PHP_INT_MAX  && $indexB !== PHP_INT_MAX) {
270
						break;
271
					}
272
				}
273
				return $indexA > $indexB;
274
			});
275
			$imageId = $images[0]['fileid'];
276
			$this->setCover($imageId, $albumId);
277
		}
278
	}
279
280
	/**
281
	 * Returns the count of albums an Artist is featured in
282
	 * @param integer $artistId
283
	 * @param string $userId
284
	 * @return integer
285
	 */
286
	public function countByArtist($artistId, $userId){
287
		$sql = 'SELECT COUNT(*) AS count '.
288
			'FROM (SELECT DISTINCT `track`.`album_id` FROM '.
289
			'`*PREFIX*music_tracks` `track` WHERE `track`.`artist_id` = ? '.
290
			'AND `track`.`user_id` = ? UNION SELECT `album`.`id` FROM '.
291
			'`*PREFIX*music_albums` `album` WHERE `album`.`album_artist_id` = ? '.
292
			'AND `album`.`user_id` = ?) tmp';
293
		$params = array($artistId, $userId, $artistId, $userId);
294
		$result = $this->execute($sql, $params);
295
		$row = $result->fetch();
296
		return $row['count'];
297
	}
298
299
	/**
300
	 * @param string $name
301
	 * @param string $userId
302
	 * @param bool $fuzzy
303
	 * @return Album[]
304
	 */
305 View Code Duplication
	public function findAllByName($name, $userId, $fuzzy = false){
306
		if ($fuzzy) {
307
			$condition = 'AND LOWER(`album`.`name`) LIKE LOWER(?) ';
308
			$name = '%' . $name . '%';
309
		} else {
310
			$condition = 'AND `album`.`name` = ? ';
311
		}
312
		$sql = $this->makeSelectQuery($condition . 'ORDER BY LOWER(`album`.`name`)');
313
		$params = array($userId, $name);
314
		return $this->findEntities($sql, $params);
315
	}
316
}
317