CategoryController   F
last analyzed

Complexity

Total Complexity 83

Size/Duplication

Total Lines 533
Duplicated Lines 0 %

Importance

Changes 28
Bugs 1 Features 1
Metric Value
eloc 318
c 28
b 1
f 1
dl 0
loc 533
rs 2
wmc 83

8 Methods

Rating   Name   Duplication   Size   Complexity  
A getTrackCount() 0 20 2
B getCategoryItemCovers() 0 35 8
A getTracks() 0 15 4
F getTracksDetails() 0 122 28
C getCategoryItems() 0 106 15
A __construct() 0 21 1
A getListViewHeaders() 0 10 4
D StreamParser() 0 125 21

How to fix   Complexity   

Complex Class

Complex classes like CategoryController often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use CategoryController, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * Audio Player
4
 *
5
 * This file is licensed under the Affero General Public License version 3 or
6
 * later. See the LICENSE.md file.
7
 *
8
 * @author Marcel Scherello <[email protected]>
9
 * @copyright 2016-2020 Marcel Scherello
10
 */
11
12
namespace OCA\audioplayer\Controller;
13
14
use OCP\AppFramework\Controller;
15
use OCP\AppFramework\Http\JSONResponse;
16
use OCP\Files\InvalidPathException;
17
use OCP\IRequest;
18
use OCP\IL10N;
19
use OCP\IDbConnection;
20
use OCP\ITagManager;
21
use OCP\Files\IRootFolder;
22
use OCP\ILogger;
23
use \OCP\Files\NotFoundException;
24
25
/**
26
 * Controller class for main page.
27
 */
28
class CategoryController extends Controller
29
{
30
31
    private $userId;
32
    private $l10n;
33
    private $db;
34
    private $tagger;
35
    private $tagManager;
36
    private $rootFolder;
37
    private $logger;
38
    private $DBController;
39
40
    public function __construct(
41
        $appName,
42
        IRequest $request,
43
        $userId,
44
        IL10N $l10n,
45
        IDBConnection $db,
46
        ITagManager $tagManager,
47
        IRootFolder $rootFolder,
48
        ILogger $logger,
49
        DbController $DBController
50
    )
51
    {
52
        parent::__construct($appName, $request);
53
        $this->userId = $userId;
54
        $this->l10n = $l10n;
55
        $this->db = $db;
56
        $this->tagManager = $tagManager;
57
        $this->tagger = null;
58
        $this->rootFolder = $rootFolder;
59
        $this->logger = $logger;
60
        $this->DBController = $DBController;
61
    }
62
63
    /**
64
     * Get the items for the selected category
65
     *
66
     * @NoAdminRequired
67
     * @param $category
68
     * @return JSONResponse
69
     */
70
    public function getCategoryItems($category)
71
    {
72
        $SQL = null;
73
        $aPlaylists = array();
74
        if ($category === 'Artist') {
75
            $SQL = 'SELECT  DISTINCT(`AT`.`artist_id`) AS `id`, `AA`.`name`, LOWER(`AA`.`name`) AS `lower` 
76
						FROM `*PREFIX*audioplayer_tracks` `AT`
77
						JOIN `*PREFIX*audioplayer_artists` `AA`
78
						ON `AA`.`id` = `AT`.`artist_id`
79
			 			WHERE  `AT`.`user_id` = ?
80
			 			ORDER BY LOWER(`AA`.`name`) ASC
81
			 			';
82
        } elseif ($category === 'Genre') {
83
            $SQL = 'SELECT  `id`, `name`, LOWER(`name`) AS `lower` 
84
						FROM `*PREFIX*audioplayer_genre`
85
			 			WHERE  `user_id` = ?
86
			 			ORDER BY LOWER(`name`) ASC
87
			 			';
88
        } elseif ($category === 'Year') {
89
            $SQL = 'SELECT DISTINCT(`year`) AS `id` ,`year` AS `name`  
90
						FROM `*PREFIX*audioplayer_tracks`
91
			 			WHERE  `user_id` = ?
92
			 			ORDER BY `id` ASC
93
			 			';
94
        } elseif ($category === 'Title') {
95
            $SQL = "SELECT distinct('0') as `id` ,'" . $this->l10n->t('All Titles') . "' as `name`  
96
						FROM `*PREFIX*audioplayer_tracks`
97
			 			WHERE  `user_id` = ?
98
			 			";
99
        } elseif ($category === 'Playlist') {
100
            $aPlaylists[] = array('id' => 'X1', 'name' => $this->l10n->t('Favorites'));
101
            $aPlaylists[] = array('id' => 'X2', 'name' => $this->l10n->t('Recently Added'));
102
            $aPlaylists[] = array('id' => 'X3', 'name' => $this->l10n->t('Recently Played'));
103
            $aPlaylists[] = array('id' => 'X4', 'name' => $this->l10n->t('Most Played'));
104
            //https://github.com/Rello/audioplayer/issues/442
105
            $aPlaylists[] = array('id' => 'X5', 'name' => $this->l10n->t('50 Random Tracks'));
106
            $aPlaylists[] = array('id' => '', 'name' => '');
107
108
            // Stream files are shown directly
109
            $SQL = 'SELECT  `file_id` AS `id`, `title` AS `name`, LOWER(`title`) AS `lower` 
110
						FROM `*PREFIX*audioplayer_streams`
111
			 			WHERE  `user_id` = ?
112
			 			ORDER BY LOWER(`title`) ASC
113
			 			';
114
            $stmt = $this->db->prepare($SQL);
115
            $stmt->execute(array($this->userId));
116
            $results = $stmt->fetchAll();
117
            foreach ($results as $row) {
118
                array_splice($row, 2, 1);
119
                $row['id'] = 'S' . $row['id'];
120
                $aPlaylists[] = $row;
121
            }
122
            $aPlaylists[] = array('id' => '', 'name' => '');
123
124
            // regular playlists are selected
125
            $SQL = 'SELECT  `id`,`name`, LOWER(`name`) AS `lower` 
126
						FROM `*PREFIX*audioplayer_playlists`
127
			 			WHERE  `user_id` = ?
128
			 			ORDER BY LOWER(`name`) ASC
129
			 			';
130
131
        } elseif ($category === 'Folder') {
132
            $SQL = 'SELECT  DISTINCT(`FC`.`fileid`) AS `id`, `FC`.`name`, LOWER(`FC`.`name`) AS `lower` 
133
						FROM `*PREFIX*audioplayer_tracks` `AT`
134
						JOIN `*PREFIX*filecache` `FC`
135
						ON `FC`.`fileid` = `AT`.`folder_id`
136
			 			WHERE `AT`.`user_id` = ?
137
			 			ORDER BY LOWER(`FC`.`name`) ASC
138
			 			';
139
        } elseif ($category === 'Album') {
140
            $SQL = 'SELECT  `AB`.`id` , `AB`.`name`, LOWER(`AB`.`name`) AS `lower`
141
						FROM `*PREFIX*audioplayer_albums` `AB`
142
						LEFT JOIN `*PREFIX*audioplayer_artists` `AA` 
143
						ON `AB`.`artist_id` = `AA`.`id`
144
			 			WHERE `AB`.`user_id` = ?
145
			 			ORDER BY LOWER(`AB`.`name`) ASC
146
			 			';
147
        } elseif ($category === 'Album Artist') {
148
            $SQL = 'SELECT  DISTINCT(`AB`.`artist_id`) AS `id`, `AA`.`name`, LOWER(`AA`.`name`) AS `lower` 
149
						FROM `*PREFIX*audioplayer_albums` `AB`
150
						JOIN `*PREFIX*audioplayer_artists` `AA`
151
						ON `AB`.`artist_id` = `AA`.`id`
152
			 			WHERE `AB`.`user_id` = ?
153
			 			ORDER BY LOWER(`AA`.`name`) ASC
154
			 			';
155
        }
156
157
        if (isset($SQL)) {
158
            $stmt = $this->db->prepare($SQL);
159
            $stmt->execute(array($this->userId));
160
            $results = $stmt->fetchAll();
161
            foreach ($results as $row) {
162
                array_splice($row, 2, 1);
163
                if ($row['name'] === '0' OR $row['name'] === '') $row['name'] = $this->l10n->t('Unknown');
164
                $row['cnt'] = $this->getTrackCount($category, $row['id']);
165
                $aPlaylists[] = $row;
166
            }
167
        }
168
169
        $result = empty($aPlaylists) ? [
170
            'status' => 'nodata'
171
        ] : [
172
            'status' => 'success',
173
            'data' => $aPlaylists
174
        ];
175
        return new JSONResponse($result);
176
    }
177
178
    /**
179
     * Get the covers for the "Album Covers" view
180
     *
181
     * @NoAdminRequired
182
     * @param $category
183
     * @param $categoryId
184
     * @return JSONResponse
185
     */
186
    public function getCategoryItemCovers($category, $categoryId)
187
    {
188
        $whereMatching = array('Artist' => '`AT`.`artist_id`', 'Genre' => '`AT`.`genre_id`', 'Album' => '`AB`.`id`', 'Album Artist' => '`AB`.`artist_id`', 'Year' => '`AT`.`year`', 'Folder' => '`AT`.`folder_id`');
189
190
        $aPlaylists = array();
191
        $SQL = 'SELECT  `AB`.`id` , `AB`.`name`, LOWER(`AB`.`name`) AS `lower` , `AA`.`id` AS `art`, (CASE  WHEN `AB`.`cover` IS NOT NULL THEN `AB`.`id` ELSE NULL END) AS `cid`';
192
        $SQL .= ' FROM `*PREFIX*audioplayer_tracks` `AT`';
193
        $SQL .= ' LEFT JOIN `*PREFIX*audioplayer_albums` `AB` ON `AB`.`id` = `AT`.`album_id`';
194
        $SQL .= ' LEFT JOIN `*PREFIX*audioplayer_artists` `AA` ON `AA`.`id` = `AB`.`artist_id`';
195
        $SQL .= ' WHERE `AT`.`user_id` = ? ';
196
        if ($categoryId) $SQL .= 'AND ' . $whereMatching[$category] . '= ?';
197
        $SQL .= ' GROUP BY `AB`.`id`, `AA`.`id`, `AB`.`name` ORDER BY LOWER(`AB`.`name`) ASC';
198
199
        if (isset($SQL)) {
200
            $stmt = $this->db->prepare($SQL);
201
            if ($categoryId) {
202
                $stmt->execute(array($this->userId, $categoryId));
203
            } else {
204
                $stmt->execute(array($this->userId));
205
            }
206
            $results = $stmt->fetchAll();
207
            foreach ($results as $row) {
208
                $row['art'] = $this->DBController->loadArtistsToAlbum($row['id'], $row['art']);
209
                array_splice($row, 2, 1);
210
                if ($row['name'] === '0' OR $row['name'] === '') $row['name'] = $this->l10n->t('Unknown');
211
                $aPlaylists[] = $row;
212
            }
213
        }
214
        $result = empty($aPlaylists) ? [
215
            'status' => 'nodata'
216
        ] : [
217
            'status' => 'success',
218
            'data' => $aPlaylists
219
        ];
220
        return new JSONResponse($result);
221
    }
222
223
    /**
224
     * Get the number of tracks for a category item
225
     *
226
     * @param string $category
227
     * @param integer $categoryId
228
     * @return integer
229
     */
230
    private function getTrackCount($category, $categoryId)
231
    {
232
        $SQL = array();
233
        $SQL['Artist'] = 'SELECT COUNT(`AT`.`id`) AS `count` FROM `*PREFIX*audioplayer_tracks` `AT` LEFT JOIN `*PREFIX*audioplayer_artists` `AA` ON `AT`.`artist_id` = `AA`.`id` WHERE  `AT`.`artist_id` = ? AND `AT`.`user_id` = ?';
234
        $SQL['Genre'] = 'SELECT COUNT(`AT`.`id`) AS `count` FROM `*PREFIX*audioplayer_tracks` `AT` WHERE  `AT`.`genre_id` = ? AND `AT`.`user_id` = ?';
235
        $SQL['Year'] = 'SELECT COUNT(`AT`.`id`) AS `count` FROM `*PREFIX*audioplayer_tracks` `AT` WHERE  `AT`.`year` = ? AND `AT`.`user_id` = ?';
236
        $SQL['Title'] = 'SELECT COUNT(`AT`.`id`) AS `count` FROM `*PREFIX*audioplayer_tracks` `AT` WHERE  `AT`.`id` > ? AND `AT`.`user_id` = ?';
237
        $SQL['Playlist'] = 'SELECT COUNT(`AP`.`track_id`) AS `count` FROM `*PREFIX*audioplayer_playlist_tracks` `AP` WHERE  `AP`.`playlist_id` = ?';
238
        $SQL['Folder'] = 'SELECT COUNT(`AT`.`id`) AS `count` FROM `*PREFIX*audioplayer_tracks` `AT` WHERE  `AT`.`folder_id` = ? AND `AT`.`user_id` = ?';
239
        $SQL['Album'] = 'SELECT COUNT(`AT`.`id`) AS `count` FROM `*PREFIX*audioplayer_tracks` `AT` WHERE  `AT`.`album_id` = ? AND `AT`.`user_id` = ?';
240
        $SQL['Album Artist'] = 'SELECT COUNT(`AT`.`id`) AS `count` FROM `*PREFIX*audioplayer_albums` `AB` JOIN `*PREFIX*audioplayer_tracks` `AT` ON `AB`.`id` = `AT`.`album_id` WHERE  `AB`.`artist_id` = ? AND `AB`.`user_id` = ?';
241
242
        $stmt = $this->db->prepare($SQL[$category]);
243
        if ($category === 'Playlist') {
244
            $stmt->execute(array($categoryId));
245
        } else {
246
            $stmt->execute(array($categoryId, $this->userId));
247
        }
248
        $results = $stmt->fetch();
249
        return $results['count'];
250
    }
251
252
    /**
253
     * get the tracks for a selected category or album
254
     *
255
     * @NoAdminRequired
256
     * @param string $category
257
     * @param string $categoryId
258
     * @return JSONResponse
259
     * @throws InvalidPathException
260
     * @throws NotFoundException
261
     */
262
    public function getTracks($category, $categoryId)
263
    {
264
        if ($categoryId[0] === 'S') $category = 'Stream';
265
        if ($categoryId[0] === 'P') $category = 'Playlist';
266
        $items = $this->getTracksDetails($category, $categoryId);
267
        $headers = $this->getListViewHeaders($category);
268
269
        $result = !empty($items) ? [
270
            'status' => 'success',
271
            'data' => $items,
272
            'header' => $headers,
273
        ] : [
274
            'status' => 'nodata',
275
        ];
276
        return new JSONResponse($result);
277
    }
278
279
    /**
280
     * Get the tracks for a selected category or album
281
     *
282
     * @param string $category
283
     * @param string $categoryId
284
     * @return array
285
     * @throws InvalidPathException
286
     */
287
    private function getTracksDetails($category, $categoryId)
288
    {
289
        $SQL = null;
290
        $favorite = false;
291
        $aTracks = array();
292
        $SQL_select = 'SELECT  `AT`.`id`, `AT`.`title`  AS `cl1`, `AA`.`name` AS `cl2`, `AB`.`name` AS `cl3`, `AT`.`length` AS `len`, `AT`.`file_id` AS `fid`, `AT`.`mimetype` AS `mim`, (CASE  WHEN `AB`.`cover` IS NOT NULL THEN `AB`.`id` ELSE NULL END) AS `cid`, LOWER(`AB`.`name`) AS `lower`';
293
        $SQL_from = ' FROM `*PREFIX*audioplayer_tracks` `AT`
294
					LEFT JOIN `*PREFIX*audioplayer_artists` `AA` ON `AT`.`artist_id` = `AA`.`id`
295
					LEFT JOIN `*PREFIX*audioplayer_albums` `AB` ON `AT`.`album_id` = `AB`.`id`';
296
        $SQL_order = ' ORDER BY LOWER(`AB`.`name`) ASC, `AT`.`disc` ASC, `AT`.`number` ASC';
297
298
        if ($category === 'Artist') {
299
            $SQL_select = 'SELECT  `AT`.`id`, `AT`.`title`  AS `cl1`, `AB`.`name` AS `cl2`, `AT`.`year` AS `cl3`, `AT`.`length` AS `len`, `AT`.`file_id` AS `fid`, `AT`.`mimetype` AS `mim`, (CASE  WHEN `AB`.`cover` IS NOT NULL THEN `AB`.`id` ELSE NULL END) AS `cid`, LOWER(`AB`.`name`) AS `lower`';
300
            $SQL = $SQL_select . $SQL_from .
301
                'WHERE  `AT`.`artist_id` = ? AND `AT`.`user_id` = ?' .
302
                $SQL_order;
303
        } elseif ($category === 'Genre') {
304
            $SQL = $SQL_select . $SQL_from .
305
                'WHERE `AT`.`genre_id` = ? AND `AT`.`user_id` = ?' .
306
                $SQL_order;
307
        } elseif ($category === 'Year') {
308
            $SQL = $SQL_select . $SQL_from .
309
                'WHERE `AT`.`year` = ? AND `AT`.`user_id` = ?' .
310
                $SQL_order;
311
        } elseif ($category === 'Title') {
312
            $SQL = $SQL_select . $SQL_from .
313
                'WHERE `AT`.`id` > ? AND `AT`.`user_id` = ?' .
314
                $SQL_order;
315
        } elseif ($category === 'Playlist' AND $categoryId === 'X1') { // Favorites
316
            $SQL = 'SELECT  `AT`.`id` , `AT`.`title`  AS `cl1`,`AA`.`name` AS `cl2`, `AB`.`name` AS `cl3`,`AT`.`length` AS `len`, `AT`.`file_id` AS `fid`, `AT`.`mimetype` AS `mim`, (CASE  WHEN `AB`.`cover` IS NOT NULL THEN `AB`.`id` ELSE NULL END) AS `cid`, LOWER(`AT`.`title`) AS `lower`' .
317
                $SQL_from .
318
                'WHERE `AT`.`id` <> ? AND `AT`.`user_id` = ?' .
319
                ' ORDER BY LOWER(`AT`.`title`) ASC';
320
            $categoryId = 0; //overwrite to integer for PostgreSQL
321
            $favorite = true;
322
        } elseif ($category === 'Playlist' AND $categoryId === 'X2') { // Recently Added
323
            $SQL = $SQL_select . $SQL_from .
324
                'WHERE `AT`.`id` <> ? AND `AT`.`user_id` = ? 
325
			 		ORDER BY `AT`.`file_id` DESC
326
			 		Limit 100';
327
            $categoryId = 0;
328
        } elseif ($category === 'Playlist' AND $categoryId === 'X3') { // Recently Played
329
            $SQL = $SQL_select . $SQL_from .
330
                'LEFT JOIN `*PREFIX*audioplayer_stats` `AS` ON `AT`.`id` = `AS`.`track_id`
331
			 		WHERE `AS`.`id` <> ? AND `AT`.`user_id` = ? 
332
			 		ORDER BY `AS`.`playtime` DESC
333
			 		Limit 50';
334
            $categoryId = 0;
335
        } elseif ($category === 'Playlist' AND $categoryId === 'X4') { // Most Played
336
            $SQL = $SQL_select . $SQL_from .
337
                'LEFT JOIN `*PREFIX*audioplayer_stats` `AS` ON `AT`.`id` = `AS`.`track_id`
338
			 		WHERE `AS`.`id` <> ? AND `AT`.`user_id` = ? 
339
			 		ORDER BY `AS`.`playcount` DESC
340
			 		Limit 25';
341
            $categoryId = 0;
342
        } elseif ($category === 'Playlist' AND $categoryId === "X5") { // 50 Random Tracks
343
            if ($this->db->getDatabasePlatform() instanceof \Doctrine\DBAL\Platforms\PostgreSqlPlatform) {
0 ignored issues
show
Bug introduced by Rello
The type Doctrine\DBAL\Platforms\PostgreSqlPlatform was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
344
                $order = 'ORDER BY random() Limit 50';
345
            } else {
346
                $order = 'ORDER BY RAND() Limit 50';
347
            }
348
            $SQL = $SQL_select . $SQL_from .
349
                "WHERE `AT`.`id` <> ? AND `AT`.`user_id` = ? " . $order;
350
            $categoryId = 0;
351
        } elseif ($category === 'Playlist') {
352
            $SQL = $SQL_select . ' , `AP`.`sortorder`' .
353
                'FROM `*PREFIX*audioplayer_playlist_tracks` `AP` 
354
					LEFT JOIN `*PREFIX*audioplayer_tracks` `AT` ON `AP`.`track_id` = `AT`.`id`
355
					LEFT JOIN `*PREFIX*audioplayer_artists` `AA` ON `AT`.`artist_id` = `AA`.`id`
356
					LEFT JOIN `*PREFIX*audioplayer_albums` `AB` ON `AT`.`album_id` = `AB`.`id`
357
			 		WHERE  `AP`.`playlist_id` = ?
358
					AND `AT`.`user_id` = ? 
359
			 		ORDER BY `AP`.`sortorder` ASC';
360
        } elseif ($category === 'Stream') {
361
            $aTracks = $this->StreamParser(intval(substr($categoryId, 1)));
362
            return $aTracks;
363
        } elseif ($category === 'Folder') {
364
            $SQL = $SQL_select . $SQL_from .
365
                'WHERE `AT`.`folder_id` = ? AND `AT`.`user_id` = ?' .
366
                $SQL_order;
367
        } elseif ($category === 'Album') {
368
            $SQL_select = 'SELECT  `AT`.`id`, `AT`.`title` AS `cl1`, `AA`.`name` AS `cl2`, `AT`.`length` AS `len`, `AT`.`disc` AS `dsc`, `AT`.`file_id` AS `fid`, `AT`.`mimetype` AS `mim`, (CASE  WHEN `AB`.`cover` IS NOT NULL THEN `AB`.`id` ELSE NULL END) AS `cid`, LOWER(`AT`.`title`) AS `lower`,`AT`.`number`  AS `num`';
369
            $SQL = $SQL_select . $SQL_from .
370
                'WHERE `AB`.`id` = ? AND `AB`.`user_id` = ?' .
371
                ' ORDER BY `AT`.`disc` ASC, `AT`.`number` ASC';
372
        } elseif ($category === 'Album Artist') {
373
            $SQL = $SQL_select . $SQL_from .
374
                'WHERE  `AB`.`artist_id` = ? AND `AT`.`user_id` = ?' .
375
                $SQL_order;
376
        }
377
378
        $this->tagger = $this->tagManager->load('files');
379
        $favorites = $this->tagger->getFavorites();
380
381
        $stmt = $this->db->prepare($SQL);
382
        $stmt->execute(array($categoryId, $this->userId));
383
        $results = $stmt->fetchAll();
384
        foreach ($results as $row) {
385
            if ($category === 'Album') {
386
                $row['cl3'] = $row['dsc'] . '-' . $row['num'];
387
            }
388
            array_splice($row, 8, 1);
389
            //$nodes = $this->rootFolder->getUserFolder($this->userId)->getById($row['fid']);
390
            //$file = array_shift($nodes);
391
            //if ($file === null) {
392
            //    $this->logger->debug('removed/unshared file found => remove '.$row['fid'], array('app' => 'audioplayer'));
393
            //    $this->DBController->deleteFromDB($row['fid'], $this->userId);
394
            //    continue;
395
            //}
396
            if (is_array($favorites) AND in_array($row['fid'], $favorites)) {
397
                $row['fav'] = 't';
398
            }
399
400
            if ($favorite AND is_array($favorites) AND !in_array($row['fid'], $favorites)) {
401
                //special handling for Favorites smart playlist;
402
                //do not display anything that is NOT a fav
403
            } else {
404
                array_splice($row, 5, 1);
405
                $aTracks[] = $row;
406
            }
407
        }
408
        return $aTracks;
409
    }
410
411
    /**
412
     * Extract steam urls from playlist files
413
     *
414
     * @param integer $fileId
415
     * @return array
416
     * @throws InvalidPathException
417
     */
418
    private function StreamParser($fileId)
419
    {
420
        $tracks = array();
421
        $x = 0;
422
        $title = null;
423
        $userView = $this->rootFolder->getUserFolder($this->userId);
424
        //$this->logger->debug('removed/unshared file found => remove '.$row['fid'], array('app' => 'audioplayer'));
425
426
        $streamfile = $userView->getById($fileId);
427
        $file_type = $streamfile[0]->getMimetype();
428
        $file_content = $streamfile[0]->getContent();
0 ignored issues
show
Bug introduced by Rello
The method getContent() does not exist on OCP\Files\Node. It seems like you code against a sub-type of OCP\Files\Node such as OCP\Files\File. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

428
        /** @scrutinizer ignore-call */ 
429
        $file_content = $streamfile[0]->getContent();
Loading history...
429
430
        if ($file_type === 'audio/x-scpls') {
431
            $stream_data = parse_ini_string($file_content, true, INI_SCANNER_RAW);
432
            $stream_rows = isset($stream_data['playlist']['NumberOfEntries']) ? $stream_data['playlist']['NumberOfEntries'] : $stream_data['playlist']['numberofentries'];
433
            for ($i = 1; $i <= $stream_rows; $i++) {
434
                $title = $stream_data['playlist']['Title' . $i];
435
                $file = $stream_data['playlist']['File' . $i];
436
                preg_match_all('#\bhttps?://[^,\s()<>]+(?:\([\w\d]+\)|([^,[:punct:]\s]|/))#', $file, $matches);
437
438
                if ($matches[0]) {
439
                    $row = array();
440
                    $row['id'] = $fileId . $i;
441
                    $row['cl1'] = $matches[0][0];
442
                    $row['cl2'] = '';
443
                    $row['cl3'] = '';
444
                    $row['len'] = '';
445
                    $row['mim'] = $file_type;
446
                    $row['cid'] = '';
447
                    $row['lin'] = $matches[0][0];
448
                    if ($title) $row['cl1'] = $title;
449
                    $tracks[] = $row;
450
                }
451
            }
452
        } else {
453
            // get the path of the playlist file as reference
454
            $playlistFilePath = explode('/', ltrim($streamfile[0]->getPath(), '/'));
455
            // remove leading username
456
            array_shift($playlistFilePath);
457
            // remove leading "files/"
458
            array_shift($playlistFilePath);
459
            // remove the filename itself
460
            array_pop($playlistFilePath);
461
462
            // read each line of the playlist
463
            foreach (preg_split("/((\r?\n)|(\r\n?))/", $file_content) as $line) {
464
                $title = null;
465
                $artist = null;
466
                if (empty($line) || $line === '#EXTM3U') continue;
467
                if (substr($line, 0, 8) === '#EXTINF:') {
468
                    $extinf = explode(',', substr($line, 8));
469
                    $extNoDuration = $extinf[1];
470
                    $extinf = explode(' - ', $extNoDuration);
471
                    $title = $extinf[1];
472
                    $artist = $extinf[0];
473
                    $line = $extinf[2];
474
                }
475
476
                preg_match_all('#\bhttps?://[^,\s()<>]+(?:\([\w\d]+\)|([^,[:punct:]\s]|/))#', $line, $matches);
477
                if ($matches[0]) {
478
                    // playlist item is a web stream url
479
                    $x++;
480
                    $row = array();
481
                    $row['id'] = $fileId . $x;
482
                    $row['cl1'] = $matches[0][0];
483
                    $row['cl2'] = '';
484
                    $row['cl3'] = '';
485
                    $row['len'] = '';
486
                    $row['mim'] = $file_type;
487
                    $row['cid'] = '';
488
                    $row['lin'] = $matches[0][0];
489
                    if ($title) $row['cl1'] = $title;
490
                    if ($artist) $row['cl2'] = $artist;
491
                    $tracks[] = $row;
492
                } elseif (preg_match('/^[^"<>|:]*$/',$line)) {
493
                    // playlist item is an internal file
494
                    if ($line[0] === '/') {
495
                        // Absolut path
496
                        $path = $line;
497
                    } elseif (substr($line, 0, 3) === '../') {
498
                        // relative one level up => remove the parent folder of the playlist file
499
                        $path = $playlistFilePath;
500
                        do {
501
                            $line = substr($line, 3);
502
                            array_pop($path);
503
                        } while (substr($line, 0, 3) === '../');
504
505
                        array_push($path, $line);
506
                        $path = implode('/', $path);
507
                    } else {
508
                        // normal relative path
509
                        $path = $playlistFilePath;
510
511
                        array_push($path, $line);
512
                        $path = implode('/', $path);
513
                    }
514
                    $x++;
515
                    $this->logger->debug('Final path of playlist track: '.$path);
516
517
                    try {
518
                        $fileId = $this->rootFolder->getUserFolder($this->userId)->get($path)->getId();
519
                        $track = $this->DBController->getTrackInfo(null,$fileId);
520
                        if (!isset($track['id'])) continue;
521
522
                        $row = array();
523
                        $row['id'] = $track['id'];
524
                        $row['cl1'] = $track['Title'];
525
                        $row['cl2'] = $track['Artist'];
526
                        $row['cl3'] = $track['Album'];
527
                        $row['len'] = $track['Length'];
528
                        $row['mim'] = $track['MIME type'];
529
                        $row['cid'] = '';
530
                        $row['lin'] = $track['id'];
531
                        $row['fav'] = $track['fav'];
532
                        if ($title) $row['cl1'] = $title;
533
                        if ($artist) $row['cl2'] = $artist;
534
                        $tracks[] = $row;
535
                    } catch (NotFoundException $e) {
536
                        $this->logger->debug('Path is not a valid file: '.$path);
537
                        // File is not known in the filecache and will be ignored;
538
                    }
539
                }
540
            }
541
        }
542
        return $tracks;
543
    }
544
545
    /**
546
     * Get selection dependend headers for the list view
547
     *
548
     * @param string $category
549
     * @return array
550
     */
551
    private function getListViewHeaders($category)
552
    {
553
        if ($category === 'Artist') {
554
            return ['col1' => $this->l10n->t('Title'), 'col2' => $this->l10n->t('Album'), 'col3' => $this->l10n->t('Year'), 'col4' => $this->l10n->t('Length')];
555
        } elseif ($category === 'Album') {
556
            return ['col1' => $this->l10n->t('Title'), 'col2' => $this->l10n->t('Artist'), 'col3' => $this->l10n->t('Disc') . '-' . $this->l10n->t('Track'), 'col4' => $this->l10n->t('Length')];
557
        } elseif ($category === 'x_Stream') { //temporary disabled; need to separate streams and playlists
558
            return ['col1' => $this->l10n->t('URL'), 'col2' => $this->l10n->t(''), 'col3' => $this->l10n->t(''), 'col4' => $this->l10n->t('')];
559
        } else {
560
            return ['col1' => $this->l10n->t('Title'), 'col2' => $this->l10n->t('Artist'), 'col3' => $this->l10n->t('Album'), 'col4' => $this->l10n->t('Length')];
561
        }
562
    }
563
}
564