Passed
Push — master ( 6e9496...0e6475 )
by Pauli
04:14
created

ShareHooks::inject()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 3
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 Morris Jobke <[email protected]>
10
 * @author Pauli Järvinen <[email protected]>
11
 * @copyright Morris Jobke 2014
12
 * @copyright Pauli Järvinen 2017 - 2025
13
 */
14
15
namespace OCA\Music\Hooks;
16
17
use OCA\Music\AppInfo\Application;
18
use OCA\Music\Service\Scanner;
19
use OCP\Files\Folder;
20
use OCP\IGroupManager;
21
22
class ShareHooks {
23
	private static function removeSharedItem(
24
			string $itemType, int $nodeId, string $owner, array $removeFromUsers) : void {
25
		/** @var Scanner $scanner */
26
		$scanner = self::inject(Scanner::class);
27
28
		if ($itemType === 'folder') {
29
			$ownerHome = $scanner->resolveUserFolder($owner);
30
			$nodes = $ownerHome->getById($nodeId);
31
			$sharedFolder = $nodes[0] ?? null;
32
			if ($sharedFolder instanceof Folder) {
33
				$scanner->deleteFolder($sharedFolder, $removeFromUsers);
34
			}
35
		} elseif ($itemType === 'file') {
36
			$scanner->delete($nodeId, $removeFromUsers);
37
		}
38
	}
39
40
	/**
41
	 * Invoke auto update of music database after item gets unshared
42
	 * @param array $params contains the params of the removed share
43
	 */
44
	public static function itemUnshared(array $params) : void {
45
		$shareType = $params['shareType'];
46
47
		// react only on user and group shares
48
		if ($shareType == \OCP\Share::SHARE_TYPE_USER) {
49
			$receivingUserIds = [ $params['shareWith'] ];
50
		} elseif ($shareType == \OCP\Share::SHARE_TYPE_GROUP) {
51
			$groupManager = self::inject(IGroupManager::class);
52
			$groupMembers = $groupManager->displayNamesInGroup($params['shareWith']);
53
			$receivingUserIds = \array_keys($groupMembers);
54
			// remove the item owner from the list of targeted users if present
55
			$receivingUserIds = \array_diff($receivingUserIds, [ $params['uidOwner'] ]);
56
		}
57
58
		if (!empty($receivingUserIds)) {
59
			self::removeSharedItem($params['itemType'], $params['itemSource'], $params['uidOwner'], $receivingUserIds);
60
		}
61
	}
62
63
	/**
64
	 * Invoke auto update of music database after item gets unshared by the share recipient
65
	 * @param array $params contains the params of the removed share
66
	 */
67
	public static function itemUnsharedFromSelf(array $params) : void {
68
		// The share recipient may be an individual user or a group, but the item is always removed from
69
		// the current user alone.
70
		$removeFromUsers = [ self::inject('receivingUserId') ];
71
72
		self::removeSharedItem($params['itemType'], $params['itemSource'], $params['uidOwner'], $removeFromUsers);
73
	}
74
75
	/**
76
	 * Invoke auto update of music database after item gets shared
77
	 * @param array $params contains the params of the added share
78
	 */
79
	public static function itemShared(array $params) : void {
80
		// Do not auto-update database when a folder is shared. The folder might contain
81
		// thousands of audio files, and indexing them could take minutes or hours. The sharee
82
		// user will be prompted to update database the next time she opens the Music app.
83
		// Similarly, do not auto-update on group shares.
84
		if ($params['itemType'] === 'file' && $params['shareType'] == \OCP\Share::SHARE_TYPE_USER) {
85
			$scanner = self::inject(Scanner::class);
86
87
			$sharingUser = self::inject('userId');
88
			$sharingUserFolder = $scanner->resolveUserFolder($sharingUser);
89
			$file = $sharingUserFolder->getById($params['itemSource'])[0]; // file object with sharing user path
90
91
			$receivingUserId = $params['shareWith'];
92
			$receivingUserFolder = $scanner->resolveUserFolder($receivingUserId);
93
			$receivingUserFilePath = $receivingUserFolder->getPath() . $params['itemTarget'];
94
			$scanner->update($file, $receivingUserId, $receivingUserFilePath);
95
		}
96
	}
97
98
	/**
99
	 * Get the dependency identified by the given name
100
	 * @return mixed
101
	 */
102
	private static function inject(string $id) {
103
		$app = \OC::$server->query(Application::class);
104
		return $app->get($id);
105
	}
106
107
	public function register() : void {
108
		// FIXME: this is temporarily static because core emitters are not future
109
		// proof, therefore legacy code in here
110
		\OCP\Util::connectHook('OCP\Share', 'post_unshare', __CLASS__, 'itemUnshared');
111
		\OCP\Util::connectHook('OCP\Share', 'post_unshareFromSelf', __CLASS__, 'itemUnsharedFromSelf');
112
		\OCP\Util::connectHook('OCP\Share', 'post_shared', __CLASS__, 'itemShared');
113
	}
114
}
115