Passed
Push — master ( 16be14...3c693d )
by Roeland
16:02 queued 12s
created

ProviderFactory   B

Complexity

Total Complexity 46

Size/Duplication

Total Lines 306
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 157
dl 0
loc 306
rs 8.72
c 1
b 0
f 0
wmc 46

10 Methods

Rating   Name   Duplication   Size   Complexity  
B getProvider() 0 33 10
A getRoomShareProvider() 0 18 4
A getShareByCircleProvider() 0 25 5
A federatedShareProvider() 0 49 3
A __construct() 0 2 1
A defaultShareProvider() 0 16 2
A registerProvider() 0 2 1
B getProviderForType() 0 26 11
A getAllProviders() 0 27 6
A getShareByMailProvider() 0 30 3

How to fix   Complexity   

Complex Class

Complex classes like ProviderFactory often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use ProviderFactory, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * @copyright Copyright (c) 2016, ownCloud, Inc.
4
 *
5
 * @author Bjoern Schiessle <[email protected]>
6
 * @author Björn Schießle <[email protected]>
7
 * @author Christoph Wurst <[email protected]>
8
 * @author Daniel Calviño Sánchez <[email protected]>
9
 * @author Daniel Kesselberg <[email protected]>
10
 * @author Joas Schilling <[email protected]>
11
 * @author Lukas Reschke <[email protected]>
12
 * @author Maxence Lange <[email protected]>
13
 * @author Morris Jobke <[email protected]>
14
 * @author Robin Appelman <[email protected]>
15
 * @author Roeland Jago Douma <[email protected]>
16
 *
17
 * @license AGPL-3.0
18
 *
19
 * This code is free software: you can redistribute it and/or modify
20
 * it under the terms of the GNU Affero General Public License, version 3,
21
 * as published by the Free Software Foundation.
22
 *
23
 * This program is distributed in the hope that it will be useful,
24
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26
 * GNU Affero General Public License for more details.
27
 *
28
 * You should have received a copy of the GNU Affero General Public License, version 3,
29
 * along with this program. If not, see <http://www.gnu.org/licenses/>
30
 *
31
 */
32
33
namespace OC\Share20;
34
35
use OC\Share20\Exception\ProviderException;
36
use OCA\FederatedFileSharing\AddressHandler;
37
use OCA\FederatedFileSharing\FederatedShareProvider;
38
use OCA\FederatedFileSharing\Notifications;
39
use OCA\FederatedFileSharing\TokenHandler;
40
use OCA\ShareByMail\Settings\SettingsManager;
41
use OCA\ShareByMail\ShareByMailProvider;
42
use OCP\Defaults;
43
use OCP\EventDispatcher\IEventDispatcher;
44
use OCP\IServerContainer;
45
use OCP\Share\IProviderFactory;
46
use OCP\Share\IShare;
47
use OCP\Share\IShareProvider;
48
49
/**
50
 * Class ProviderFactory
51
 *
52
 * @package OC\Share20
53
 */
54
class ProviderFactory implements IProviderFactory {
55
56
	/** @var IServerContainer */
57
	private $serverContainer;
58
	/** @var DefaultShareProvider */
59
	private $defaultProvider = null;
60
	/** @var FederatedShareProvider */
61
	private $federatedProvider = null;
62
	/** @var  ShareByMailProvider */
63
	private $shareByMailProvider;
64
	/** @var  \OCA\Circles\ShareByCircleProvider */
0 ignored issues
show
Bug introduced by
The type OCA\Circles\ShareByCircleProvider was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
65
	private $shareByCircleProvider = null;
66
	/** @var bool */
67
	private $circlesAreNotAvailable = false;
68
	/** @var \OCA\Talk\Share\RoomShareProvider */
0 ignored issues
show
Bug introduced by
The type OCA\Talk\Share\RoomShareProvider was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
69
	private $roomShareProvider = null;
70
71
	private $registeredShareProviders = [];
72
73
	private $shareProviders = [];
74
75
	/**
76
	 * IProviderFactory constructor.
77
	 *
78
	 * @param IServerContainer $serverContainer
79
	 */
80
	public function __construct(IServerContainer $serverContainer) {
81
		$this->serverContainer = $serverContainer;
82
	}
83
84
	public function registerProvider(string $shareProviderClass): void {
85
		$this->registeredShareProviders[] = $shareProviderClass;
86
	}
87
88
	/**
89
	 * Create the default share provider.
90
	 *
91
	 * @return DefaultShareProvider
92
	 */
93
	protected function defaultShareProvider() {
94
		if ($this->defaultProvider === null) {
95
			$this->defaultProvider = new DefaultShareProvider(
96
				$this->serverContainer->getDatabaseConnection(),
97
				$this->serverContainer->getUserManager(),
98
				$this->serverContainer->getGroupManager(),
99
				$this->serverContainer->getLazyRootFolder(),
0 ignored issues
show
Bug introduced by
The method getLazyRootFolder() does not exist on OCP\IServerContainer. Did you maybe mean getRootFolder()? ( Ignorable by Annotation )

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

99
				$this->serverContainer->/** @scrutinizer ignore-call */ 
100
                            getLazyRootFolder(),

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
100
				$this->serverContainer->getMailer(),
101
				$this->serverContainer->query(Defaults::class),
102
				$this->serverContainer->getL10NFactory(),
103
				$this->serverContainer->getURLGenerator(),
104
				$this->serverContainer->getConfig()
105
			);
106
		}
107
108
		return $this->defaultProvider;
109
	}
110
111
	/**
112
	 * Create the federated share provider
113
	 *
114
	 * @return FederatedShareProvider
115
	 */
116
	protected function federatedShareProvider() {
117
		if ($this->federatedProvider === null) {
118
			/*
119
			 * Check if the app is enabled
120
			 */
121
			$appManager = $this->serverContainer->getAppManager();
122
			if (!$appManager->isEnabledForUser('federatedfilesharing')) {
123
				return null;
124
			}
125
126
			/*
127
			 * TODO: add factory to federated sharing app
128
			 */
129
			$l = $this->serverContainer->getL10N('federatedfilesharing');
130
			$addressHandler = new AddressHandler(
131
				$this->serverContainer->getURLGenerator(),
132
				$l,
133
				$this->serverContainer->getCloudIdManager()
134
			);
135
			$notifications = new Notifications(
136
				$addressHandler,
137
				$this->serverContainer->getHTTPClientService(),
138
				$this->serverContainer->query(\OCP\OCS\IDiscoveryService::class),
139
				$this->serverContainer->getJobList(),
140
				\OC::$server->getCloudFederationProviderManager(),
141
				\OC::$server->getCloudFederationFactory(),
142
				$this->serverContainer->query(IEventDispatcher::class)
143
			);
144
			$tokenHandler = new TokenHandler(
145
				$this->serverContainer->getSecureRandom()
146
			);
147
148
			$this->federatedProvider = new FederatedShareProvider(
149
				$this->serverContainer->getDatabaseConnection(),
150
				$addressHandler,
151
				$notifications,
152
				$tokenHandler,
153
				$l,
154
				$this->serverContainer->getLogger(),
155
				$this->serverContainer->getLazyRootFolder(),
156
				$this->serverContainer->getConfig(),
157
				$this->serverContainer->getUserManager(),
158
				$this->serverContainer->getCloudIdManager(),
159
				$this->serverContainer->getGlobalScaleConfig(),
160
				$this->serverContainer->getCloudFederationProviderManager()
161
			);
162
		}
163
164
		return $this->federatedProvider;
165
	}
166
167
	/**
168
	 * Create the federated share provider
169
	 *
170
	 * @return ShareByMailProvider
171
	 */
172
	protected function getShareByMailProvider() {
173
		if ($this->shareByMailProvider === null) {
174
			/*
175
			 * Check if the app is enabled
176
			 */
177
			$appManager = $this->serverContainer->getAppManager();
178
			if (!$appManager->isEnabledForUser('sharebymail')) {
179
				return null;
180
			}
181
182
			$settingsManager = new SettingsManager($this->serverContainer->getConfig());
183
184
			$this->shareByMailProvider = new ShareByMailProvider(
185
				$this->serverContainer->getDatabaseConnection(),
186
				$this->serverContainer->getSecureRandom(),
187
				$this->serverContainer->getUserManager(),
188
				$this->serverContainer->getLazyRootFolder(),
189
				$this->serverContainer->getL10N('sharebymail'),
190
				$this->serverContainer->getLogger(),
191
				$this->serverContainer->getMailer(),
192
				$this->serverContainer->getURLGenerator(),
193
				$this->serverContainer->getActivityManager(),
194
				$settingsManager,
195
				$this->serverContainer->query(Defaults::class),
196
				$this->serverContainer->getHasher(),
197
				$this->serverContainer->get(IEventDispatcher::class)
198
			);
199
		}
200
201
		return $this->shareByMailProvider;
202
	}
203
204
205
	/**
206
	 * Create the circle share provider
207
	 *
208
	 * @return FederatedShareProvider
209
	 *
210
	 * @suppress PhanUndeclaredClassMethod
211
	 */
212
	protected function getShareByCircleProvider() {
213
		if ($this->circlesAreNotAvailable) {
214
			return null;
215
		}
216
217
		if (!$this->serverContainer->getAppManager()->isEnabledForUser('circles') ||
218
			!class_exists('\OCA\Circles\ShareByCircleProvider')
219
		) {
220
			$this->circlesAreNotAvailable = true;
221
			return null;
222
		}
223
224
		if ($this->shareByCircleProvider === null) {
225
			$this->shareByCircleProvider = new \OCA\Circles\ShareByCircleProvider(
226
				$this->serverContainer->getDatabaseConnection(),
227
				$this->serverContainer->getSecureRandom(),
228
				$this->serverContainer->getUserManager(),
229
				$this->serverContainer->getLazyRootFolder(),
230
				$this->serverContainer->getL10N('circles'),
231
				$this->serverContainer->getLogger(),
232
				$this->serverContainer->getURLGenerator()
233
			);
234
		}
235
236
		return $this->shareByCircleProvider;
237
	}
238
239
	/**
240
	 * Create the room share provider
241
	 *
242
	 * @return RoomShareProvider
0 ignored issues
show
Bug introduced by
The type OC\Share20\RoomShareProvider was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
243
	 */
244
	protected function getRoomShareProvider() {
245
		if ($this->roomShareProvider === null) {
246
			/*
247
			 * Check if the app is enabled
248
			 */
249
			$appManager = $this->serverContainer->getAppManager();
250
			if (!$appManager->isEnabledForUser('spreed')) {
251
				return null;
252
			}
253
254
			try {
255
				$this->roomShareProvider = $this->serverContainer->query('\OCA\Talk\Share\RoomShareProvider');
256
			} catch (\OCP\AppFramework\QueryException $e) {
257
				return null;
258
			}
259
		}
260
261
		return $this->roomShareProvider;
262
	}
263
264
	/**
265
	 * @inheritdoc
266
	 */
267
	public function getProvider($id) {
268
		$provider = null;
269
		if (isset($this->shareProviders[$id])) {
270
			return $this->shareProviders[$id];
271
		}
272
273
		if ($id === 'ocinternal') {
274
			$provider = $this->defaultShareProvider();
275
		} elseif ($id === 'ocFederatedSharing') {
276
			$provider = $this->federatedShareProvider();
277
		} elseif ($id === 'ocMailShare') {
278
			$provider = $this->getShareByMailProvider();
279
		} elseif ($id === 'ocCircleShare') {
280
			$provider = $this->getShareByCircleProvider();
281
		} elseif ($id === 'ocRoomShare') {
282
			$provider = $this->getRoomShareProvider();
283
		}
284
285
		foreach ($this->registeredShareProviders as $shareProvider) {
286
			/** @var IShareProvider $instance */
287
			$instance = $this->serverContainer->get($shareProvider);
288
			$this->shareProviders[$instance->identifier()] = $instance;
289
		}
290
291
		if (isset($this->shareProviders[$id])) {
292
			$provider = $this->shareProviders[$id];
293
		}
294
295
		if ($provider === null) {
296
			throw new ProviderException('No provider with id .' . $id . ' found.');
297
		}
298
299
		return $provider;
300
	}
301
302
	/**
303
	 * @inheritdoc
304
	 */
305
	public function getProviderForType($shareType) {
306
		$provider = null;
307
308
		if ($shareType === IShare::TYPE_USER ||
309
			$shareType === IShare::TYPE_GROUP ||
310
			$shareType === IShare::TYPE_LINK
311
		) {
312
			$provider = $this->defaultShareProvider();
313
		} elseif ($shareType === IShare::TYPE_REMOTE || $shareType === IShare::TYPE_REMOTE_GROUP) {
314
			$provider = $this->federatedShareProvider();
315
		} elseif ($shareType === IShare::TYPE_EMAIL) {
316
			$provider = $this->getShareByMailProvider();
317
		} elseif ($shareType === IShare::TYPE_CIRCLE) {
318
			$provider = $this->getShareByCircleProvider();
319
		} elseif ($shareType === IShare::TYPE_ROOM) {
320
			$provider = $this->getRoomShareProvider();
321
		} elseif ($shareType === IShare::TYPE_DECK) {
322
			$provider = $this->getProvider('deck');
323
		}
324
325
326
		if ($provider === null) {
327
			throw new ProviderException('No share provider for share type ' . $shareType);
328
		}
329
330
		return $provider;
331
	}
332
333
	public function getAllProviders() {
334
		$shares = [$this->defaultShareProvider(), $this->federatedShareProvider()];
335
		$shareByMail = $this->getShareByMailProvider();
336
		if ($shareByMail !== null) {
337
			$shares[] = $shareByMail;
338
		}
339
		$shareByCircle = $this->getShareByCircleProvider();
340
		if ($shareByCircle !== null) {
341
			$shares[] = $shareByCircle;
342
		}
343
		$roomShare = $this->getRoomShareProvider();
344
		if ($roomShare !== null) {
345
			$shares[] = $roomShare;
346
		}
347
348
		foreach ($this->registeredShareProviders as $shareProvider) {
349
			/** @var IShareProvider $instance */
350
			$instance = $this->serverContainer->get($shareProvider);
351
			if (!isset($this->shareProviders[$instance->identifier()])) {
352
				$this->shareProviders[$instance->identifier()] = $instance;
353
			}
354
			$shares[] = $this->shareProviders[$instance->identifier()];
355
		}
356
357
358
359
		return $shares;
360
	}
361
}
362