Passed
Push — master ( d3429f...53215a )
by Pauli
02:01
created

Library::latestUpdateTime()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 1
dl 0
loc 5
rs 10
c 0
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 Pauli Järvinen <[email protected]>
10
 * @copyright Pauli Järvinen 2018 - 2021
11
 */
12
13
namespace OCA\Music\BusinessLayer;
14
15
use \OCA\Music\AppFramework\Core\Logger;
16
use \OCA\Music\Utility\CoverHelper;
17
use \OCA\Music\Utility\Util;
18
19
use \OCP\IL10N;
20
use \OCP\IURLGenerator;
21
22
class Library {
23
	private $albumBusinessLayer;
24
	private $artistBusinessLayer;
25
	private $trackBusinessLayer;
26
	private $coverHelper;
27
	private $urlGenerator;
28
	private $l10n;
29
	private $logger;
30
31
	public function __construct(
32
			AlbumBusinessLayer $albumBusinessLayer,
33
			ArtistBusinessLayer $artistBusinessLayer,
34
			TrackBusinessLayer $trackBusinessLayer,
35
			CoverHelper $coverHelper,
36
			IURLGenerator $urlGenerator,
37
			IL10N $l10n,
38
			Logger $logger) {
39
		$this->albumBusinessLayer = $albumBusinessLayer;
40
		$this->artistBusinessLayer = $artistBusinessLayer;
41
		$this->trackBusinessLayer = $trackBusinessLayer;
42
		$this->coverHelper = $coverHelper;
43
		$this->urlGenerator = $urlGenerator;
44
		$this->l10n = $l10n;
45
		$this->logger = $logger;
46
	}
47
48
	public function getTracksAlbumsAndArtists($userId) {
49
		// Get all the entities from the DB first. The order of queries is important if we are in
50
		// the middle of a scanning process: we don't want to get tracks which do not yet have
51
		// an album entry or albums which do not yet have artist entry.
52
		$tracks = $this->trackBusinessLayer->findAll($userId);
53
		$albums = $this->albumBusinessLayer->findAll($userId);
54
		$artists = $this->artistBusinessLayer->findAll($userId);
55
56
		$artistsById = Util::createIdLookupTable($artists);
57
		$albumsById = Util::createIdLookupTable($albums);
58
59
		foreach ($tracks as $idx => $track) {
60
			$album = $albumsById[$track->getAlbumId()];
61
62
			if (empty($album)) {
63
				$this->logger->log("DB error on track {$track->id} '{$track->title}': ".
64
				"album with ID {$track->albumId} not found. Skipping the track.", 'warn');
65
				unset($tracks[$idx]);
66
			} else {
67
				$track->setAlbum($album);
68
			}
69
		}
70
71
		return [
72
			'tracks' => $tracks,
73
			'albums' => $albumsById,
74
			'artists' => $artistsById
75
		];
76
	}
77
78
	public function toCollection($userId) {
79
		$entities = $this->getTracksAlbumsAndArtists($userId);
80
		$coverHashes = $this->coverHelper->getAllCachedAlbumCoverHashes($userId);
81
82
		// Create a multi-level dictionary of tracks where each track can be found
83
		// by addressing like $trackDict[artistId][albumId][ordinal]. The tracks are
84
		// in the dictionary in the "toCollection" format.
85
		$trackDict = [];
86
		foreach ($entities['tracks'] as $track) {
87
			$trackDict[$track->getAlbum()->getAlbumArtistId()][$track->getAlbumId()][]
88
				= $track->toCollection($this->l10n);
89
		}
90
91
		// Then create the actual collection by iterating over the previusly created
92
		// dictionary and creating artists and albums in the "toCollection" format.
93
		$collection = [];
94
		foreach ($trackDict as $artistId => $artistTracksByAlbum) {
95
			$artistAlbums = [];
96
			foreach ($artistTracksByAlbum as $albumId => $albumTracks) {
97
				$coverHash = $coverHashes[$albumId] ?? null;
98
				$artistAlbums[] = $entities['albums'][$albumId]->toCollection(
99
						$this->urlGenerator, $this->l10n, $coverHash, $albumTracks);
100
			}
101
102
			$collection[] = $entities['artists'][$artistId]->toCollection($this->l10n, $artistAlbums);
103
		}
104
105
		return $collection;
106
	}
107
108
	/**
109
	 * Get the timestamp of the latest insert operation on the library
110
	 */
111
	public function latestInsertTime(string $userId) : \DateTime {
112
		return \max(
113
			$this->artistBusinessLayer->latestInsertTime($userId),
114
			$this->albumBusinessLayer->latestInsertTime($userId),
115
			$this->trackBusinessLayer->latestInsertTime($userId)
116
		);
117
	}
118
119
	/**
120
	 * Get the timestamp of the latest update operation on the library
121
	 */
122
	public function latestUpdateTime(string $userId) : \DateTime {
123
		return \max(
124
			$this->artistBusinessLayer->latestUpdateTime($userId),
125
			$this->albumBusinessLayer->latestUpdateTime($userId),
126
			$this->trackBusinessLayer->latestUpdateTime($userId)
127
		);
128
	}
129
}
130