Passed
Push — master ( 23e8ae...e8872f )
by Robin
16:16 queued 12s
created

MountProviderCollection::clearProviders()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 0
dl 0
loc 4
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
namespace OC\Files\Config;
26
27
use OC\Hooks\Emitter;
28
use OC\Hooks\EmitterTrait;
29
use OCP\Files\Config\IHomeMountProvider;
30
use OCP\Files\Config\IMountProvider;
31
use OCP\Files\Config\IMountProviderCollection;
32
use OCP\Files\Config\IRootMountProvider;
33
use OCP\Files\Config\IUserMountCache;
34
use OCP\Files\Mount\IMountManager;
35
use OCP\Files\Mount\IMountPoint;
36
use OCP\Files\Storage\IStorageFactory;
37
use OCP\IUser;
38
39
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

39
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...
40
	use EmitterTrait;
0 ignored issues
show
Deprecated Code introduced by
The trait OC\Hooks\EmitterTrait 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
	use /** @scrutinizer ignore-deprecated */ EmitterTrait;

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

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

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

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