Passed
Push — master ( acedf0...2adfe5 )
by Pauli
04:02
created

Playlist::getReadOnly()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 2
rs 10
c 1
b 0
f 0
1
<?php declare(strict_types=1);
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
 * @author Pauli Järvinen <[email protected]>
11
 * @copyright Morris Jobke 2014
12
 * @copyright Pauli Järvinen 2017 - 2024
13
 */
14
15
namespace OCA\Music\Db;
16
17
use OCA\Music\Utility\Util;
18
use OCP\IURLGenerator;
19
20
/**
21
 * @method string getName()
22
 * @method setName(string $name)
23
 * @method string getTrackIds()
24
 * @method setTrackIds(string $trackIds)
25
 * @method string getComment()
26
 * @method setComment(string $comment)
27
 * @method ?string getStarred()
28
 * @method void setStarred(?string $timestamp)
29
 * @method ?int getRating()
30
 * @method setRating(?int $rating)
31
 */
32
class Playlist extends Entity {
33
	public $name;
34
	public $trackIds;
35
	public $comment;
36
	public $starred;
37
	public $rating;
38
39
	// injected separately when needed
40
	private $duration;
41
	private $readOnly;
42
43
	public function __construct() {
44
		$this->addType('rating', 'int');
45
	}
46
47
	public function getDuration() : ?int {
48
		return $this->duration;
49
	}
50
51
	public function setDuration(?int $duration) : void {
52
		$this->duration = $duration;
53
	}
54
55
	public function getReadOnly() : bool {
56
		return $this->readOnly ?? false;
57
	}
58
59
	public function setReadOnly(bool $readOnly) : void {
60
		$this->readOnly = $readOnly;
61
	}
62
63
	public function getTrackCount() : int {
64
		return \count($this->getTrackIdsAsArray());
65
	}
66
67
	/**
68
	 * @return int[]
69
	 */
70
	public function getTrackIdsAsArray() : array {
71
		if ($this->isEmpty()) {
72
			return [];
73
		} else {
74
			$encoded = \substr($this->trackIds, 1, -1); // omit leading and trailing '|'
75
			return \array_map('intval', \explode('|', $encoded));
76
		}
77
	}
78
79
	/**
80
	 * @param int[] $trackIds
81
	 */
82
	public function setTrackIdsFromArray(array $trackIds) : void {
83
		// encode to format like "|123|45|667|"
84
		$this->setTrackIds('|' . \implode('|', $trackIds) . '|');
85
	}
86
87
	public function toAPI(IURLGenerator $urlGenerator) : array {
88
		return [
89
			'name' => $this->getName(),
90
			'trackIds' => $this->getTrackIdsAsArray(),
91
			'id' => $this->getId(),
92
			'created' => $this->getCreated(),
93
			'updated' => $this->getUpdated(),
94
			'comment' => $this->getComment(),
95
			'cover' => $this->getCoverUrl($urlGenerator)
96
		];
97
	}
98
99
	public function toAmpacheApi(callable $createImageUrl) : array {
100
		$result = [
101
			'id' => (string)$this->getId(),
102
			'name' => $this->getName(),
103
			'owner' => $this->getUserId(),
104
			'items' => $this->getTrackCount(),
105
			'art' => $createImageUrl($this),
106
			'flag' => !empty($this->getStarred()),
107
			'rating' => $this->getRating() ?? 0,
108
			'type' => 'Private',
109
			'has_access' => !$this->getReadOnly(),
110
			'has_collaborate' => !$this->getReadOnly(),
111
			'last_update' => \strtotime($this->getUpdated())
112
		];
113
		$result['has_art'] = !empty($result['art']);
114
		return $result;
115
	}
116
117
	public function toSubsonicApi() : array {
118
		return [
119
			'id' => $this->getId(),
120
			'name' => $this->getName(),
121
			'owner' => $this->userId,
122
			'public' => false,
123
			'songCount' => $this->getTrackCount(),
124
			'duration' => $this->getDuration(),
125
			'comment' => $this->getComment() ?: '',
126
			'created' => Util::formatZuluDateTime($this->getCreated()),
127
			'changed' => Util::formatZuluDateTime($this->getUpdated()),
128
			'coverArt' => 'pl-' . $this->getId() // work around: DSub always fetches the art using ID like "pl-NNN" even if we would use some other format here
129
		];
130
	}
131
132
	private function isEmpty() : bool {
133
		// the list is empty if there is nothing between the leading and trailing '|'
134
		return (!$this->trackIds || \strlen($this->trackIds) < 3);
135
	}
136
137
	private function getCoverUrl(IURLGenerator $urlGenerator) : ?string {
138
		// the list might not have an id in case it's a generated playlist
139
		if ($this->getId() && !$this->isEmpty()) {
140
			return $urlGenerator->linkToRoute('music.playlistApi.getCover', ['id' => $this->getId()]);
141
		} else {
142
			return null;
143
		}
144
	}
145
}
146