Completed
Push — stable9 ( 3c64b7...7d6fa4 )
by Joas
9s
created

FilesHooks::shareFileOrFolderByLink()   B

Complexity

Conditions 5
Paths 6

Size

Total Lines 32
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 5.8054

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 32
ccs 15
cts 22
cp 0.6818
rs 8.439
cc 5
eloc 23
nc 6
nop 4
crap 5.8054
1
<?php
2
/**
3
 * @author Frank Karlitschek <[email protected]>
4
 * @author Joas Schilling <[email protected]>
5
 * @author Thomas Müller <[email protected]>
6
 *
7
 * @copyright Copyright (c) 2016, ownCloud, Inc.
8
 * @license AGPL-3.0
9
 *
10
 * This code is free software: you can redistribute it and/or modify
11
 * it under the terms of the GNU Affero General Public License, version 3,
12
 * as published by the Free Software Foundation.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
 * GNU Affero General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Affero General Public License, version 3,
20
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
21
 *
22
 */
23
24
namespace OCA\Activity;
25
26
use OC\Files\Filesystem;
27
use OC\Files\View;
28
use OCA\Activity\Extension\Files;
29
use OCA\Activity\Extension\Files_Sharing;
30
use OCP\Activity\IManager;
31
use OCP\Files\Mount\IMountPoint;
32
use OCP\Files\NotFoundException;
33
use OCP\IDBConnection;
34
use OCP\IGroup;
35
use OCP\IGroupManager;
36
use OCP\IUser;
37
use OCP\Share;
38
use OCP\Util;
39
40
/**
41
 * The class to handle the filesystem hooks
42
 */
43
class FilesHooks {
44
	const USER_BATCH_SIZE = 50;
45
46
	/** @var \OCP\Activity\IManager */
47
	protected $manager;
48
49
	/** @var \OCA\Activity\Data */
50
	protected $activityData;
51
52
	/** @var \OCA\Activity\UserSettings */
53
	protected $userSettings;
54
55
	/** @var \OCP\IGroupManager */
56
	protected $groupManager;
57
58
	/** @var \OCP\IDBConnection */
59
	protected $connection;
60
61
	/** @var \OC\Files\View */
62
	protected $view;
63
64
	/** @var string|false */
65
	protected $currentUser;
66
67
	/**
68
	 * Constructor
69
	 *
70
	 * @param IManager $manager
71
	 * @param Data $activityData
72
	 * @param UserSettings $userSettings
73
	 * @param IGroupManager $groupManager
74
	 * @param View $view
75
	 * @param IDBConnection $connection
76
	 * @param string|false $currentUser
77
	 */
78 47
	public function __construct(IManager $manager, Data $activityData, UserSettings $userSettings, IGroupManager $groupManager, View $view, IDBConnection $connection, $currentUser) {
79 47
		$this->manager = $manager;
80 47
		$this->activityData = $activityData;
81 47
		$this->userSettings = $userSettings;
82 47
		$this->groupManager = $groupManager;
83 47
		$this->view = $view;
84 47
		$this->connection = $connection;
85 47
		$this->currentUser = $currentUser;
86 47
	}
87
88
	/**
89
	 * @return string|false Current UserID if logged in, false otherwise
90
	 */
91 2
	protected function getCurrentUser() {
92 2
		return $this->currentUser;
93
	}
94
95
	/**
96
	 * Store the create hook events
97
	 * @param string $path Path of the file that has been created
98
	 */
99 2
	public function fileCreate($path) {
100 2
		if ($this->getCurrentUser() !== false) {
101 1
			$this->addNotificationsForFileAction($path, Files::TYPE_SHARE_CREATED, 'created_self', 'created_by');
102
		} else {
103 1
			$this->addNotificationsForFileAction($path, Files::TYPE_SHARE_CREATED, '', 'created_public');
104
		}
105 2
	}
106
107
	/**
108
	 * Store the update hook events
109
	 * @param string $path Path of the file that has been modified
110
	 */
111 1
	public function fileUpdate($path) {
112 1
		$this->addNotificationsForFileAction($path, Files::TYPE_SHARE_CHANGED, 'changed_self', 'changed_by');
113 1
	}
114
115
	/**
116
	 * Store the delete hook events
117
	 * @param string $path Path of the file that has been deleted
118
	 */
119 1
	public function fileDelete($path) {
120 1
		$this->addNotificationsForFileAction($path, Files::TYPE_SHARE_DELETED, 'deleted_self', 'deleted_by');
121 1
	}
122
123
	/**
124
	 * Store the restore hook events
125
	 * @param string $path Path of the file that has been restored
126
	 */
127 1
	public function fileRestore($path) {
128 1
		$this->addNotificationsForFileAction($path, Files::TYPE_SHARE_RESTORED, 'restored_self', 'restored_by');
129 1
	}
130
131
	/**
132
	 * Creates the entries for file actions on $file_path
133
	 *
134
	 * @param string $filePath         The file that is being changed
135
	 * @param int    $activityType     The activity type
136
	 * @param string $subject          The subject for the actor
137
	 * @param string $subjectBy        The subject for other users (with "by $actor")
138
	 */
139 3
	protected function addNotificationsForFileAction($filePath, $activityType, $subject, $subjectBy) {
140
		// Do not add activities for .part-files
141 3
		if (substr($filePath, -5) === '.part') {
142 1
			return;
143
		}
144
145 2
		if (Files::TYPE_SHARE_CREATED) {
146
			try {
147 2
				list($filePath, $uidOwner, $fileId) = $this->getSourcePathAndOwner($filePath);
148
			} catch (\OCP\Files\NotFoundException $e) {
0 ignored issues
show
Bug introduced by
The class OCP\Files\NotFoundException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
149
				// File not found? Sounds weird, but this happens before 9.1:
150
				// https://github.com/owncloud/core/issues/23212
151
				// Chunk assembling triggered the exact same hooks twice.
152
				// The first call however is before the file is in the database.
153
				// So when trying to get the owner, the file can not be found.
154
				// But since the second hook will come along, we simply ignore this.
155 2
				return;
156
			}
157
		} else {
158
			list($filePath, $uidOwner, $fileId) = $this->getSourcePathAndOwner($filePath);
159
		}
160 2
		$affectedUsers = $this->getUserPathsFromPath($filePath, $uidOwner);
161 2
		$filteredStreamUsers = $this->userSettings->filterUsersBySetting(array_keys($affectedUsers), 'stream', $activityType);
162 2
		$filteredEmailUsers = $this->userSettings->filterUsersBySetting(array_keys($affectedUsers), 'email', $activityType);
163
164 2
		foreach ($affectedUsers as $user => $path) {
165 2
			if (empty($filteredStreamUsers[$user]) && empty($filteredEmailUsers[$user])) {
166 2
				continue;
167
			}
168
169 2
			if ($user === $this->currentUser) {
170 1
				$userSubject = $subject;
171 1
				$userParams = [[$fileId => $path]];
172
			} else {
173 1
				$userSubject = $subjectBy;
174 1
				$userParams = [[$fileId => $path], $this->currentUser];
175
			}
176
177 2
			$this->addNotificationsForUser(
178
				$user, $userSubject, $userParams,
179 2
				$fileId, $path, true,
180 2
				!empty($filteredStreamUsers[$user]),
181 2
				!empty($filteredEmailUsers[$user]) ? $filteredEmailUsers[$user] : 0,
182
				$activityType
183
			);
184
		}
185 2
	}
186
187
	/**
188
	 * Returns a "username => path" map for all affected users
189
	 *
190
	 * @param string $path
191
	 * @param string $uidOwner
192
	 * @return array
193
	 */
194
	protected function getUserPathsFromPath($path, $uidOwner) {
195
		return Share::getUsersSharingFile($path, $uidOwner, true, true);
196
	}
197
198
	/**
199
	 * Return the source
200
	 *
201
	 * @param string $path
202
	 * @return array
203
	 */
204
	protected function getSourcePathAndOwner($path) {
205
		$uidOwner = Filesystem::getOwner($path);
206
		$fileId = 0;
207
208
		if ($uidOwner !== $this->currentUser) {
209
			Filesystem::initMountPoints($uidOwner);
210
		}
211
		$info = Filesystem::getFileInfo($path);
212
		if ($info !== false) {
213
			$ownerView = new View('/' . $uidOwner . '/files');
214
			$fileId = (int) $info['fileid'];
215
			$path = $ownerView->getPath($fileId);
216
		}
217
218
		return array($path, $uidOwner, $fileId);
219
	}
220
221
	/**
222
	 * Manage sharing events
223
	 * @param array $params The hook params
224
	 */
225 3 View Code Duplication
	public function share($params) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
226 3
		if ($params['itemType'] === 'file' || $params['itemType'] === 'folder') {
227 3
			if ((int) $params['shareType'] === Share::SHARE_TYPE_USER) {
228 1
				$this->shareFileOrFolderWithUser($params['shareWith'], (int) $params['fileSource'], $params['itemType'], $params['fileTarget'], true);
229 2
			} else if ((int) $params['shareType'] === Share::SHARE_TYPE_GROUP) {
230 1
				$this->shareFileOrFolderWithGroup($params['shareWith'], (int) $params['fileSource'], $params['itemType'], $params['fileTarget'], (int) $params['id'], true);
231 1
			} else if ((int) $params['shareType'] === Share::SHARE_TYPE_LINK) {
232 1
				$this->shareFileOrFolderByLink((int) $params['fileSource'], $params['itemType'], $params['uidOwner'], true);
233
			}
234
		}
235 3
	}
236
237
	/**
238
	 * Manage sharing events
239
	 * @param array $params The hook params
240
	 */
241 View Code Duplication
	public function unShare($params) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
242
		if ($params['itemType'] === 'file' || $params['itemType'] === 'folder') {
243
			if ((int) $params['shareType'] === Share::SHARE_TYPE_USER) {
244
				$this->shareFileOrFolderWithUser($params['shareWith'], (int) $params['fileSource'], $params['itemType'], $params['fileTarget'], false);
245
			} else if ((int) $params['shareType'] === Share::SHARE_TYPE_GROUP) {
246
				$this->shareFileOrFolderWithGroup($params['shareWith'], (int) $params['fileSource'], $params['itemType'], $params['fileTarget'], (int) $params['id'], false);
247
			} else if ((int) $params['shareType'] === Share::SHARE_TYPE_LINK) {
248
				$this->shareFileOrFolderByLink((int) $params['fileSource'], $params['itemType'], $params['uidOwner'], false);
249
			}
250
		}
251
	}
252
253
	/**
254
	 * Sharing a file or folder with a user
255
	 *
256
	 * @param string $shareWith
257
	 * @param int $fileSource File ID that is being shared
258
	 * @param string $itemType File type that is being shared (file or folder)
259
	 * @param string $fileTarget File path
260
	 * @param bool $isSharing True if sharing, false if unsharing
261
	 */
262 2
	protected function shareFileOrFolderWithUser($shareWith, $fileSource, $itemType, $fileTarget, $isSharing) {
263 2
		if ($isSharing) {
264 2
			$actionSharer = 'shared_user_self';
265 2
			$actionOwner = 'reshared_user_by';
266 2
			$actionUser = 'shared_with_by';
267
		} else {
268
			$actionSharer = 'unshared_user_self';
269
			$actionOwner = 'unshared_user_by';
270
			$actionUser = 'unshared_by';
271
		}
272
273
		// User performing the share
274 2
		$this->shareNotificationForSharer($actionSharer, $shareWith, $fileSource, $itemType);
275 2
		$this->shareNotificationForOriginalOwners($this->currentUser, $actionOwner, $shareWith, $fileSource, $itemType);
0 ignored issues
show
Security Bug introduced by
It seems like $this->currentUser can also be of type false; however, OCA\Activity\FilesHooks:...tionForOriginalOwners() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
276
277
		// New shared user
278 2
		$this->addNotificationsForUser(
279 2
			$shareWith, $actionUser, [[$fileSource => $fileTarget], $this->currentUser],
280 2
			(int) $fileSource, $fileTarget, ($itemType === 'file'),
281 2
			$this->userSettings->getUserSetting($shareWith, 'stream', Files_Sharing::TYPE_SHARED),
282 2
			$this->userSettings->getUserSetting($shareWith, 'email', Files_Sharing::TYPE_SHARED) ? $this->userSettings->getUserSetting($shareWith, 'setting', 'batchtime') : 0
283
		);
284 2
	}
285
286
	/**
287
	 * Sharing a file or folder with a group
288
	 *
289
	 * @param string $shareWith
290
	 * @param int $fileSource File ID that is being shared
291
	 * @param string $itemType File type that is being shared (file or folder)
292
	 * @param string $fileTarget File path
293
	 * @param int $shareId The Share ID of this share
294
	 * @param bool $isSharing True if sharing, false if unsharing
295
	 */
296 6
	protected function shareFileOrFolderWithGroup($shareWith, $fileSource, $itemType, $fileTarget, $shareId, $isSharing) {
297 6
		if ($isSharing) {
298 6
			$actionSharer = 'shared_group_self';
299 6
			$actionOwner = 'reshared_group_by';
300 6
			$actionUser = 'shared_with_by';
301
		} else {
302
			$actionSharer = 'unshared_group_self';
303
			$actionOwner = 'unshared_group_by';
304
			$actionUser = 'unshared_by';
305
		}
306
307
		// Members of the new group
308 6
		$group = $this->groupManager->get($shareWith);
309 6
		if (!($group instanceof IGroup)) {
0 ignored issues
show
Bug introduced by
The class OCP\IGroup does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
310 1
			return;
311
		}
312
313
		// User performing the share
314 5
		$this->shareNotificationForSharer($actionSharer, $shareWith, $fileSource, $itemType);
315 5
		$this->shareNotificationForOriginalOwners($this->currentUser, $actionOwner, $shareWith, $fileSource, $itemType);
0 ignored issues
show
Security Bug introduced by
It seems like $this->currentUser can also be of type false; however, OCA\Activity\FilesHooks:...tionForOriginalOwners() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
316
317 5
		$offset = 0;
318 5
		$users = $group->searchUsers('', self::USER_BATCH_SIZE, $offset);
319 5
		while (!empty($users)) {
320 4
			$this->addNotificationsForGroupUsers($users, $actionUser, $fileSource, $itemType, $fileTarget, $shareId);
321 4
			$offset += self::USER_BATCH_SIZE;
322 4
			$users = $group->searchUsers('', self::USER_BATCH_SIZE, $offset);
323
		}
324 5
	}
325
326
	/**
327
	 * @param IUser[] $usersInGroup
328
	 * @param string $actionUser
329
	 * @param int $fileSource File ID that is being shared
330
	 * @param string $itemType File type that is being shared (file or folder)
331
	 * @param string $fileTarget File path
332
	 * @param int $shareId The Share ID of this share
333
	 */
334 4
	protected function addNotificationsForGroupUsers(array $usersInGroup, $actionUser, $fileSource, $itemType, $fileTarget, $shareId) {
335 4
		$affectedUsers = [];
336
337 4
		foreach ($usersInGroup as $user) {
338 4
			$affectedUsers[$user->getUID()] = $fileTarget;
339
		}
340
341
		// Remove the triggering user, we already managed his notifications
342 4
		unset($affectedUsers[$this->currentUser]);
343
344 4
		if (empty($affectedUsers)) {
345 1
			return;
346
		}
347
348 3
		$userIds = array_keys($affectedUsers);
349 3
		$filteredStreamUsersInGroup = $this->userSettings->filterUsersBySetting($userIds, 'stream', Files_Sharing::TYPE_SHARED);
350 3
		$filteredEmailUsersInGroup = $this->userSettings->filterUsersBySetting($userIds, 'email', Files_Sharing::TYPE_SHARED);
351
352 3
		$affectedUsers = $this->fixPathsForShareExceptions($affectedUsers, $shareId);
353 3
		foreach ($affectedUsers as $user => $path) {
354 3
			if (empty($filteredStreamUsersInGroup[$user]) && empty($filteredEmailUsersInGroup[$user])) {
355 2
				continue;
356
			}
357
358 1
			$this->addNotificationsForUser(
359 1
				$user, $actionUser, [[$fileSource => $path], $this->currentUser],
360 1
				$fileSource, $path, ($itemType === 'file'),
361 1
				!empty($filteredStreamUsersInGroup[$user]),
362 1
				!empty($filteredEmailUsersInGroup[$user]) ? $filteredEmailUsersInGroup[$user] : 0
363
			);
364
		}
365 3
	}
366
367
	/**
368
	 * Check when there was a naming conflict and the target is different
369
	 * for some of the users
370
	 *
371
	 * @param array $affectedUsers
372
	 * @param int $shareId
373
	 * @return mixed
374
	 */
375
	protected function fixPathsForShareExceptions(array $affectedUsers, $shareId) {
376
		$queryBuilder = $this->connection->getQueryBuilder();
377
		$queryBuilder->select(['share_with', 'file_target'])
378
			->from('share')
379
			->where($queryBuilder->expr()->eq('parent', $queryBuilder->createParameter('parent')))
380
			->setParameter('parent', (int) $shareId);
381
		$query = $queryBuilder->execute();
382
383
		while ($row = $query->fetch()) {
384
			$affectedUsers[$row['share_with']] = $row['file_target'];
385
		}
386
387
		return $affectedUsers;
388
	}
389
390
	/**
391
	 * Sharing a file or folder via link/public
392
	 *
393
	 * @param int $fileSource File ID that is being shared
394
	 * @param string $itemType File type that is being shared (file or folder)
395
	 * @param string $linkOwner
396
	 * @param bool $isSharing True if sharing, false if unsharing
397
	 */
398 2
	protected function shareFileOrFolderByLink($fileSource, $itemType, $linkOwner, $isSharing) {
399 2
		if ($isSharing) {
400 2
			$actionSharer = 'shared_link_self';
401 2
			$actionOwner = 'reshared_link_by';
402
		} else if ($this->currentUser !== $linkOwner) {
403
			// Link expired
404
			$actionSharer = 'link_expired';
405
			$actionOwner = 'link_by_expired';
406
			$this->currentUser = $linkOwner;
407
			\OC::$server->getUserFolder($linkOwner);
408
		} else {
409
			$actionSharer = 'unshared_link_self';
410
			$actionOwner = 'unshared_link_by';
411
		}
412
413 2
		$this->view->chroot('/' . $this->currentUser . '/files');
414
415
		try {
416 2
			$path = $this->view->getPath($fileSource);
417 1
		} catch (NotFoundException $e) {
0 ignored issues
show
Bug introduced by
The class OCP\Files\NotFoundException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
418 1
			return;
419
		}
420
421 1
		$this->shareNotificationForOriginalOwners($this->currentUser, $actionOwner, '', $fileSource, $itemType);
0 ignored issues
show
Security Bug introduced by
It seems like $this->currentUser can also be of type false; however, OCA\Activity\FilesHooks:...tionForOriginalOwners() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
422
423 1
		$this->addNotificationsForUser(
424 1
			$this->currentUser, $actionSharer, [[$fileSource => $path]],
0 ignored issues
show
Security Bug introduced by
It seems like $this->currentUser can also be of type false; however, OCA\Activity\FilesHooks::addNotificationsForUser() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
425 1
			(int) $fileSource, $path, ($itemType === 'file'),
426 1
			$this->userSettings->getUserSetting($this->currentUser, 'stream', Files_Sharing::TYPE_SHARED),
0 ignored issues
show
Security Bug introduced by
It seems like $this->currentUser can also be of type false; however, OCA\Activity\UserSettings::getUserSetting() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
427 1
			$this->userSettings->getUserSetting($this->currentUser, 'email', Files_Sharing::TYPE_SHARED) ? $this->userSettings->getUserSetting($this->currentUser, 'setting', 'batchtime') : 0
0 ignored issues
show
Security Bug introduced by
It seems like $this->currentUser can also be of type false; however, OCA\Activity\UserSettings::getUserSetting() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
428
		);
429 1
	}
430
431
	/**
432
	 * Add notifications for the user that shares a file/folder
433
	 *
434
	 * @param string $subject
435
	 * @param string $shareWith
436
	 * @param int $fileSource
437
	 * @param string $itemType
438
	 */
439 2
	protected function shareNotificationForSharer($subject, $shareWith, $fileSource, $itemType) {
440 2
		$this->view->chroot('/' . $this->currentUser . '/files');
441
442
		try {
443 2
			$path = $this->view->getPath($fileSource);
444 1
		} catch (NotFoundException $e) {
0 ignored issues
show
Bug introduced by
The class OCP\Files\NotFoundException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
445 1
			return;
446
		}
447
448 1
		$this->addNotificationsForUser(
449 1
			$this->currentUser, $subject, [[$fileSource => $path], $shareWith],
0 ignored issues
show
Security Bug introduced by
It seems like $this->currentUser can also be of type false; however, OCA\Activity\FilesHooks::addNotificationsForUser() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
450 1
			$fileSource, $path, ($itemType === 'file'),
451 1
			$this->userSettings->getUserSetting($this->currentUser, 'stream', Files_Sharing::TYPE_SHARED),
0 ignored issues
show
Security Bug introduced by
It seems like $this->currentUser can also be of type false; however, OCA\Activity\UserSettings::getUserSetting() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
452 1
			$this->userSettings->getUserSetting($this->currentUser, 'email', Files_Sharing::TYPE_SHARED) ? $this->userSettings->getUserSetting($this->currentUser, 'setting', 'batchtime') : 0
0 ignored issues
show
Security Bug introduced by
It seems like $this->currentUser can also be of type false; however, OCA\Activity\UserSettings::getUserSetting() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
453
		);
454 1
	}
455
456
	/**
457
	 * Add notifications for the user that shares a file/folder
458
	 *
459
	 * @param string $owner
460
	 * @param string $subject
461
	 * @param string $shareWith
462
	 * @param int $fileSource
463
	 * @param string $itemType
464
	 */
465 2
	protected function reshareNotificationForSharer($owner, $subject, $shareWith, $fileSource, $itemType) {
466 2
		$this->view->chroot('/' . $owner . '/files');
467
468
		try {
469 2
			$path = $this->view->getPath($fileSource);
470 1
		} catch (NotFoundException $e) {
0 ignored issues
show
Bug introduced by
The class OCP\Files\NotFoundException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
471 1
			return;
472
		}
473
474 1
		$this->addNotificationsForUser(
475 1
			$owner, $subject, [[$fileSource => $path], $this->currentUser, $shareWith],
476 1
			$fileSource, $path, ($itemType === 'file'),
477 1
			$this->userSettings->getUserSetting($owner, 'stream', Files_Sharing::TYPE_SHARED),
478 1
			$this->userSettings->getUserSetting($owner, 'email', Files_Sharing::TYPE_SHARED) ? $this->userSettings->getUserSetting($owner, 'setting', 'batchtime') : 0
479
		);
480 1
	}
481
482
	/**
483
	 * Add notifications for the owners whose files have been reshared
484
	 *
485
	 * @param string $currentOwner
486
	 * @param string $subject
487
	 * @param string $shareWith
488
	 * @param int $fileSource
489
	 * @param string $itemType
490
	 */
491 10
	protected function shareNotificationForOriginalOwners($currentOwner, $subject, $shareWith, $fileSource, $itemType) {
492
		// Get the full path of the current user
493 10
		$this->view->chroot('/' . $currentOwner . '/files');
494
495
		try {
496 10
			$path = $this->view->getPath($fileSource);
497 1
		} catch (NotFoundException $e) {
0 ignored issues
show
Bug introduced by
The class OCP\Files\NotFoundException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
498 1
			return;
499
		}
500
501
		/**
502
		 * Get the original owner and his path
503
		 */
504 9
		$owner = $this->view->getOwner($path);
505 9
		if ($owner !== $currentOwner) {
506 7
			$this->reshareNotificationForSharer($owner, $subject, $shareWith, $fileSource, $itemType);
507
		}
508
509
		/**
510
		 * Get the sharee who shared the item with the currentUser
511
		 */
512 9
		$this->view->chroot('/' . $currentOwner . '/files');
513 9
		$mount = $this->view->getMount($path);
514 9
		if (!($mount instanceof IMountPoint)) {
0 ignored issues
show
Bug introduced by
The class OCP\Files\Mount\IMountPoint does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
515 1
			return;
516
		}
517
518 8
		$storage = $mount->getStorage();
519 8
		if (!$storage->instanceOfStorage('OC\Files\Storage\Shared')) {
520 1
			return;
521
		}
522
523
		/** @var \OC\Files\Storage\Shared $storage */
524 7
		$shareOwner = $storage->getSharedFrom();
525 7
		if ($shareOwner === '' || $shareOwner === null || $shareOwner === $owner || $shareOwner === $currentOwner) {
526 5
			return;
527
		}
528
529 2
		$this->reshareNotificationForSharer($shareOwner, $subject, $shareWith, $fileSource, $itemType);
530 2
	}
531
532
	/**
533
	 * Adds the activity and email for a user when the settings require it
534
	 *
535
	 * @param string $user
536
	 * @param string $subject
537
	 * @param array $subjectParams
538
	 * @param int $fileId
539
	 * @param string $path
540
	 * @param bool $isFile If the item is a file, we link to the parent directory
541
	 * @param bool $streamSetting
542
	 * @param int $emailSetting
543
	 * @param string $type
544
	 */
545 9
	protected function addNotificationsForUser($user, $subject, $subjectParams, $fileId, $path, $isFile, $streamSetting, $emailSetting, $type = Files_Sharing::TYPE_SHARED) {
546 9
		if (!$streamSetting && !$emailSetting) {
547 1
			return;
548
		}
549
550 8
		$selfAction = $user === $this->currentUser;
551 8
		$app = $type === Files_Sharing::TYPE_SHARED ? 'files_sharing' : 'files';
552 8
		$link = Util::linkToAbsolute('files', 'index.php', array(
553 8
			'dir' => ($isFile) ? dirname($path) : $path,
554
		));
555
556 8
		$objectType = ($fileId) ? 'files' : '';
557
558 8
		$event = $this->manager->generateEvent();
559 8
		$event->setApp($app)
560 8
			->setType($type)
561 8
			->setAffectedUser($user)
562 8
			->setAuthor($this->currentUser)
563 8
			->setTimestamp(time())
564 8
			->setSubject($subject, $subjectParams)
565 8
			->setObject($objectType, $fileId, $path)
566 8
			->setLink($link);
567
568
		// Add activity to stream
569 8
		if ($streamSetting && (!$selfAction || $this->userSettings->getUserSetting($this->currentUser, 'setting', 'self'))) {
570 3
			$this->activityData->send($event);
571
		}
572
573
		// Add activity to mail queue
574 8
		if ($emailSetting && (!$selfAction || $this->userSettings->getUserSetting($this->currentUser, 'setting', 'selfemail'))) {
575 3
			$latestSend = time() + $emailSetting;
576 3
			$this->activityData->storeMail($event, $latestSend);
577
		}
578 8
	}
579
}
580