Passed
Push — master ( 1df567...eb2b1b )
by Morris
14:23 queued 12s
created

MountProviderCollection::registerMounts()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 2
dl 0
loc 2
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * @copyright Copyright (c) 2016, ownCloud, Inc.
4
 *
5
 * @author Christoph Wurst <[email protected]>
6
 * @author Morris Jobke <[email protected]>
7
 * @author Robin Appelman <[email protected]>
8
 * @author Roeland Jago Douma <[email protected]>
9
 *
10
 * @license AGPL-3.0
11
 *
12
 * This code is free software: you can redistribute it and/or modify
13
 * it under the terms of the GNU Affero General Public License, version 3,
14
 * as published by the Free Software Foundation.
15
 *
16
 * This program is distributed in the hope that it will be useful,
17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
 * GNU Affero General Public License for more details.
20
 *
21
 * You should have received a copy of the GNU Affero General Public License, version 3,
22
 * along with this program. If not, see <http://www.gnu.org/licenses/>
23
 *
24
 */
25
26
namespace OC\Files\Config;
27
28
use OC\Hooks\Emitter;
29
use OC\Hooks\EmitterTrait;
30
use OCP\Files\Config\IHomeMountProvider;
31
use OCP\Files\Config\IMountProvider;
32
use OCP\Files\Config\IMountProviderCollection;
33
use OCP\Files\Config\IRootMountProvider;
34
use OCP\Files\Config\IUserMountCache;
35
use OCP\Files\Mount\IMountManager;
36
use OCP\Files\Mount\IMountPoint;
37
use OCP\Files\Storage\IStorageFactory;
38
use OCP\IUser;
39
40
class MountProviderCollection implements IMountProviderCollection, Emitter {
0 ignored issues
show
Deprecated Code introduced by
The interface OC\Hooks\Emitter has been deprecated: 18.0.0 use events and the \OCP\EventDispatcher\IEventDispatcher service ( Ignorable by Annotation )

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

40
class MountProviderCollection implements IMountProviderCollection, /** @scrutinizer ignore-deprecated */ Emitter {

This interface has been deprecated. The supplier of the interface has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the interface will be removed and what other interface to use instead.

Loading history...
41
	use EmitterTrait;
42
43
	/**
44
	 * @var \OCP\Files\Config\IHomeMountProvider[]
45
	 */
46
	private $homeProviders = [];
47
48
	/**
49
	 * @var \OCP\Files\Config\IMountProvider[]
50
	 */
51
	private $providers = [];
52
53
	/** @var \OCP\Files\Config\IRootMountProvider[] */
54
	private $rootProviders = [];
55
56
	/**
57
	 * @var \OCP\Files\Storage\IStorageFactory
58
	 */
59
	private $loader;
60
61
	/**
62
	 * @var \OCP\Files\Config\IUserMountCache
63
	 */
64
	private $mountCache;
65
66
	/** @var callable[] */
67
	private $mountFilters = [];
68
69
	/**
70
	 * @param \OCP\Files\Storage\IStorageFactory $loader
71
	 * @param IUserMountCache $mountCache
72
	 */
73
	public function __construct(IStorageFactory $loader, IUserMountCache $mountCache) {
74
		$this->loader = $loader;
75
		$this->mountCache = $mountCache;
76
	}
77
78
	/**
79
	 * Get all configured mount points for the user
80
	 *
81
	 * @param \OCP\IUser $user
82
	 * @return \OCP\Files\Mount\IMountPoint[]
83
	 */
84
	public function getMountsForUser(IUser $user) {
85
		$loader = $this->loader;
86
		$mounts = array_map(function (IMountProvider $provider) use ($user, $loader) {
87
			return $provider->getMountsForUser($user, $loader);
88
		}, $this->providers);
89
		$mounts = array_filter($mounts, function ($result) {
90
			return is_array($result);
91
		});
92
		$mounts = array_reduce($mounts, function (array $mounts, array $providerMounts) {
93
			return array_merge($mounts, $providerMounts);
94
		}, []);
95
		return $this->filterMounts($user, $mounts);
96
	}
97
98
	public function addMountForUser(IUser $user, IMountManager $mountManager) {
99
		// shared mount provider gets to go last since it needs to know existing files
100
		// to check for name collisions
101
		$firstMounts = [];
102
		$firstProviders = array_filter($this->providers, function (IMountProvider $provider) {
103
			return (get_class($provider) !== 'OCA\Files_Sharing\MountProvider');
104
		});
105
		$lastProviders = array_filter($this->providers, function (IMountProvider $provider) {
106
			return (get_class($provider) === 'OCA\Files_Sharing\MountProvider');
107
		});
108
		foreach ($firstProviders as $provider) {
109
			$mounts = $provider->getMountsForUser($user, $this->loader);
110
			if (is_array($mounts)) {
111
				$firstMounts = array_merge($firstMounts, $mounts);
112
			}
113
		}
114
		$firstMounts = $this->filterMounts($user, $firstMounts);
115
		array_walk($firstMounts, [$mountManager, 'addMount']);
116
117
		$lateMounts = [];
118
		foreach ($lastProviders as $provider) {
119
			$mounts = $provider->getMountsForUser($user, $this->loader);
120
			if (is_array($mounts)) {
121
				$lateMounts = array_merge($lateMounts, $mounts);
122
			}
123
		}
124
125
		$lateMounts = $this->filterMounts($user, $lateMounts);
126
		array_walk($lateMounts, [$mountManager, 'addMount']);
127
128
		return array_merge($lateMounts, $firstMounts);
129
	}
130
131
	/**
132
	 * Get the configured home mount for this user
133
	 *
134
	 * @param \OCP\IUser $user
135
	 * @return \OCP\Files\Mount\IMountPoint
136
	 * @since 9.1.0
137
	 */
138
	public function getHomeMountForUser(IUser $user) {
139
		/** @var \OCP\Files\Config\IHomeMountProvider[] $providers */
140
		$providers = array_reverse($this->homeProviders); // call the latest registered provider first to give apps an opportunity to overwrite builtin
141
		foreach ($providers as $homeProvider) {
142
			if ($mount = $homeProvider->getHomeMountForUser($user, $this->loader)) {
143
				$mount->setMountPoint('/' . $user->getUID()); //make sure the mountpoint is what we expect
144
				return $mount;
145
			}
146
		}
147
		throw new \Exception('No home storage configured for user ' . $user);
0 ignored issues
show
Bug introduced by
Are you sure $user of type OCP\IUser can be used in concatenation? Consider adding a __toString()-method. ( Ignorable by Annotation )

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

147
		throw new \Exception('No home storage configured for user ' . /** @scrutinizer ignore-type */ $user);
Loading history...
148
	}
149
150
	/**
151
	 * Add a provider for mount points
152
	 *
153
	 * @param \OCP\Files\Config\IMountProvider $provider
154
	 */
155
	public function registerProvider(IMountProvider $provider) {
156
		$this->providers[] = $provider;
157
158
		$this->emit('\OC\Files\Config', 'registerMountProvider', [$provider]);
159
	}
160
161
	public function registerMountFilter(callable $filter) {
162
		$this->mountFilters[] = $filter;
163
	}
164
165
	private function filterMounts(IUser $user, array $mountPoints) {
166
		return array_filter($mountPoints, function (IMountPoint $mountPoint) use ($user) {
167
			foreach ($this->mountFilters as $filter) {
168
				if ($filter($mountPoint, $user) === false) {
169
					return false;
170
				}
171
			}
172
			return true;
173
		});
174
	}
175
176
	/**
177
	 * Add a provider for home mount points
178
	 *
179
	 * @param \OCP\Files\Config\IHomeMountProvider $provider
180
	 * @since 9.1.0
181
	 */
182
	public function registerHomeProvider(IHomeMountProvider $provider) {
183
		$this->homeProviders[] = $provider;
184
		$this->emit('\OC\Files\Config', 'registerHomeMountProvider', [$provider]);
185
	}
186
187
	/**
188
	 * Cache mounts for user
189
	 *
190
	 * @param IUser $user
191
	 * @param IMountPoint[] $mountPoints
192
	 */
193
	public function registerMounts(IUser $user, array $mountPoints) {
194
		$this->mountCache->registerMounts($user, $mountPoints);
195
	}
196
197
	/**
198
	 * Get the mount cache which can be used to search for mounts without setting up the filesystem
199
	 *
200
	 * @return IUserMountCache
201
	 */
202
	public function getMountCache() {
203
		return $this->mountCache;
204
	}
205
206
	public function registerRootProvider(IRootMountProvider $provider) {
207
		$this->rootProviders[] = $provider;
208
	}
209
210
	public function getRootMounts(): array {
211
		$loader = $this->loader;
212
		$mounts = array_map(function (IRootMountProvider $provider) use ($loader) {
213
			return $provider->getRootMounts($loader);
214
		}, $this->rootProviders);
215
		$mounts = array_reduce($mounts, function (array $mounts, array $providerMounts) {
216
			return array_merge($mounts, $providerMounts);
217
		}, []);
218
		return $mounts;
219
	}
220
}
221