1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* @copyright Copyright (c) 2016, ownCloud, Inc. |
4
|
|
|
* |
5
|
|
|
* @author Frank Karlitschek <[email protected]> |
6
|
|
|
* @author Joas Schilling <[email protected]> |
7
|
|
|
* @author Thomas Müller <[email protected]> |
8
|
|
|
* |
9
|
|
|
* @license AGPL-3.0 |
10
|
|
|
* |
11
|
|
|
* This code is free software: you can redistribute it and/or modify |
12
|
|
|
* it under the terms of the GNU Affero General Public License, version 3, |
13
|
|
|
* as published by the Free Software Foundation. |
14
|
|
|
* |
15
|
|
|
* This program is distributed in the hope that it will be useful, |
16
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
17
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
18
|
|
|
* GNU Affero General Public License for more details. |
19
|
|
|
* |
20
|
|
|
* You should have received a copy of the GNU Affero General Public License, version 3, |
21
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/> |
22
|
|
|
* |
23
|
|
|
*/ |
24
|
|
|
|
25
|
|
|
namespace OCA\Activity; |
26
|
|
|
|
27
|
|
|
use OC\Files\Filesystem; |
28
|
|
|
use OC\Files\View; |
29
|
|
|
use OCA\Activity\Extension\Files; |
30
|
|
|
use OCA\Activity\Extension\Files_Sharing; |
31
|
|
|
use OCP\Activity\IManager; |
32
|
|
|
use OCP\Files\Mount\IMountPoint; |
33
|
|
|
use OCP\Files\NotFoundException; |
34
|
|
|
use OCP\IDBConnection; |
35
|
|
|
use OCP\IGroup; |
36
|
|
|
use OCP\IGroupManager; |
37
|
|
|
use OCP\IURLGenerator; |
38
|
|
|
use OCP\IUser; |
39
|
|
|
use OCP\Share; |
40
|
|
|
|
41
|
|
|
/** |
42
|
|
|
* The class to handle the filesystem hooks |
43
|
|
|
*/ |
44
|
|
|
class FilesHooks { |
45
|
|
|
const USER_BATCH_SIZE = 50; |
46
|
|
|
|
47
|
|
|
/** @var \OCP\Activity\IManager */ |
48
|
|
|
protected $manager; |
49
|
|
|
|
50
|
|
|
/** @var \OCA\Activity\Data */ |
51
|
|
|
protected $activityData; |
52
|
|
|
|
53
|
|
|
/** @var \OCA\Activity\UserSettings */ |
54
|
|
|
protected $userSettings; |
55
|
|
|
|
56
|
|
|
/** @var \OCP\IGroupManager */ |
57
|
|
|
protected $groupManager; |
58
|
|
|
|
59
|
|
|
/** @var \OCP\IDBConnection */ |
60
|
|
|
protected $connection; |
61
|
|
|
|
62
|
|
|
/** @var \OC\Files\View */ |
63
|
|
|
protected $view; |
64
|
|
|
|
65
|
|
|
/** @var IURLGenerator */ |
66
|
|
|
protected $urlGenerator; |
67
|
|
|
|
68
|
|
|
/** @var string|false */ |
69
|
|
|
protected $currentUser; |
70
|
|
|
|
71
|
|
|
/** |
72
|
|
|
* Constructor |
73
|
|
|
* |
74
|
|
|
* @param IManager $manager |
75
|
|
|
* @param Data $activityData |
76
|
|
|
* @param UserSettings $userSettings |
77
|
|
|
* @param IGroupManager $groupManager |
78
|
|
|
* @param View $view |
79
|
|
|
* @param IDBConnection $connection |
80
|
|
|
* @param IURLGenerator $urlGenerator |
81
|
|
|
* @param string|false $currentUser |
82
|
|
|
*/ |
83
|
49 |
|
public function __construct(IManager $manager, Data $activityData, UserSettings $userSettings, IGroupManager $groupManager, View $view, IDBConnection $connection, IURLGenerator $urlGenerator, $currentUser) { |
84
|
49 |
|
$this->manager = $manager; |
85
|
49 |
|
$this->activityData = $activityData; |
86
|
49 |
|
$this->userSettings = $userSettings; |
87
|
49 |
|
$this->groupManager = $groupManager; |
88
|
49 |
|
$this->view = $view; |
89
|
49 |
|
$this->connection = $connection; |
90
|
49 |
|
$this->urlGenerator = $urlGenerator; |
91
|
49 |
|
$this->currentUser = $currentUser; |
92
|
49 |
|
} |
93
|
|
|
|
94
|
|
|
/** |
95
|
|
|
* @return string|false Current UserID if logged in, false otherwise |
96
|
|
|
*/ |
97
|
2 |
|
protected function getCurrentUser() { |
98
|
2 |
|
return $this->currentUser; |
99
|
|
|
} |
100
|
|
|
|
101
|
|
|
/** |
102
|
|
|
* Store the create hook events |
103
|
|
|
* @param string $path Path of the file that has been created |
104
|
|
|
*/ |
105
|
2 |
|
public function fileCreate($path) { |
106
|
2 |
|
if ($this->getCurrentUser() !== false) { |
107
|
1 |
|
$this->addNotificationsForFileAction($path, Files::TYPE_SHARE_CREATED, 'created_self', 'created_by'); |
108
|
|
|
} else { |
109
|
1 |
|
$this->addNotificationsForFileAction($path, Files::TYPE_SHARE_CREATED, '', 'created_public'); |
110
|
|
|
} |
111
|
2 |
|
} |
112
|
|
|
|
113
|
|
|
/** |
114
|
|
|
* Store the update hook events |
115
|
|
|
* @param string $path Path of the file that has been modified |
116
|
|
|
*/ |
117
|
1 |
|
public function fileUpdate($path) { |
118
|
1 |
|
$this->addNotificationsForFileAction($path, Files::TYPE_SHARE_CHANGED, 'changed_self', 'changed_by'); |
119
|
1 |
|
} |
120
|
|
|
|
121
|
|
|
/** |
122
|
|
|
* Store the delete hook events |
123
|
|
|
* @param string $path Path of the file that has been deleted |
124
|
|
|
*/ |
125
|
1 |
|
public function fileDelete($path) { |
126
|
1 |
|
$this->addNotificationsForFileAction($path, Files::TYPE_SHARE_DELETED, 'deleted_self', 'deleted_by'); |
127
|
1 |
|
} |
128
|
|
|
|
129
|
|
|
/** |
130
|
|
|
* Store the restore hook events |
131
|
|
|
* @param string $path Path of the file that has been restored |
132
|
|
|
*/ |
133
|
1 |
|
public function fileRestore($path) { |
134
|
1 |
|
$this->addNotificationsForFileAction($path, Files::TYPE_SHARE_RESTORED, 'restored_self', 'restored_by'); |
135
|
1 |
|
} |
136
|
|
|
|
137
|
|
|
/** |
138
|
|
|
* Creates the entries for file actions on $file_path |
139
|
|
|
* |
140
|
|
|
* @param string $filePath The file that is being changed |
141
|
|
|
* @param int $activityType The activity type |
142
|
|
|
* @param string $subject The subject for the actor |
143
|
|
|
* @param string $subjectBy The subject for other users (with "by $actor") |
144
|
|
|
*/ |
145
|
3 |
|
protected function addNotificationsForFileAction($filePath, $activityType, $subject, $subjectBy) { |
146
|
|
|
// Do not add activities for .part-files |
147
|
3 |
|
if (substr($filePath, -5) === '.part') { |
148
|
1 |
|
return; |
149
|
|
|
} |
150
|
|
|
|
151
|
2 |
|
if (Files::TYPE_SHARE_CREATED) { |
152
|
|
|
try { |
153
|
2 |
|
list($filePath, $uidOwner, $fileId) = $this->getSourcePathAndOwner($filePath); |
154
|
|
|
} catch (\OCP\Files\NotFoundException $e) { |
|
|
|
|
155
|
|
|
// File not found? Sounds weird, but this happens before 9.1: |
156
|
|
|
// https://github.com/owncloud/core/issues/23212 |
157
|
|
|
// Chunk assembling triggered the exact same hooks twice. |
158
|
|
|
// The first call however is before the file is in the database. |
159
|
|
|
// So when trying to get the owner, the file can not be found. |
160
|
|
|
// But since the second hook will come along, we simply ignore this. |
161
|
2 |
|
return; |
162
|
|
|
} |
163
|
|
|
} else { |
164
|
|
|
list($filePath, $uidOwner, $fileId) = $this->getSourcePathAndOwner($filePath); |
165
|
|
|
} |
166
|
|
|
|
167
|
2 |
|
if ($fileId === 0) { |
168
|
|
|
// Could not find the file for the owner ... |
169
|
|
|
return; |
170
|
|
|
} |
171
|
|
|
|
172
|
2 |
|
$affectedUsers = $this->getUserPathsFromPath($filePath, $uidOwner); |
173
|
2 |
|
$filteredStreamUsers = $this->userSettings->filterUsersBySetting(array_keys($affectedUsers), 'stream', $activityType); |
174
|
2 |
|
$filteredEmailUsers = $this->userSettings->filterUsersBySetting(array_keys($affectedUsers), 'email', $activityType); |
175
|
|
|
|
176
|
2 |
|
foreach ($affectedUsers as $user => $path) { |
177
|
2 |
|
if (empty($filteredStreamUsers[$user]) && empty($filteredEmailUsers[$user])) { |
178
|
2 |
|
continue; |
179
|
|
|
} |
180
|
|
|
|
181
|
2 |
|
if ($user === $this->currentUser) { |
182
|
1 |
|
$userSubject = $subject; |
183
|
1 |
|
$userParams = [[$fileId => $path]]; |
184
|
|
|
} else { |
185
|
1 |
|
$userSubject = $subjectBy; |
186
|
1 |
|
$userParams = [[$fileId => $path], $this->currentUser]; |
187
|
|
|
} |
188
|
|
|
|
189
|
2 |
|
$this->addNotificationsForUser( |
190
|
|
|
$user, $userSubject, $userParams, |
191
|
2 |
|
$fileId, $path, true, |
192
|
2 |
|
!empty($filteredStreamUsers[$user]), |
193
|
2 |
|
!empty($filteredEmailUsers[$user]) ? $filteredEmailUsers[$user] : 0, |
194
|
|
|
$activityType |
195
|
|
|
); |
196
|
|
|
} |
197
|
2 |
|
} |
198
|
|
|
|
199
|
|
|
/** |
200
|
|
|
* Returns a "username => path" map for all affected users |
201
|
|
|
* |
202
|
|
|
* @param string $path |
203
|
|
|
* @param string $uidOwner |
204
|
|
|
* @return array |
205
|
|
|
*/ |
206
|
|
|
protected function getUserPathsFromPath($path, $uidOwner) { |
207
|
|
|
return Share::getUsersSharingFile($path, $uidOwner, true, true); |
208
|
|
|
} |
209
|
|
|
|
210
|
|
|
/** |
211
|
|
|
* Return the source |
212
|
|
|
* |
213
|
|
|
* @param string $path |
214
|
|
|
* @return array |
215
|
|
|
*/ |
216
|
|
|
protected function getSourcePathAndOwner($path) { |
217
|
|
|
$view = Filesystem::getView(); |
218
|
|
|
$uidOwner = $view->getOwner($path); |
219
|
|
|
$fileId = 0; |
220
|
|
|
|
221
|
|
|
if ($uidOwner !== $this->currentUser) { |
222
|
|
|
/** @var \OCP\Files\Storage\IStorage $storage */ |
223
|
|
|
list($storage,) = $view->resolvePath($path); |
224
|
|
|
if (!$storage->instanceOfStorage('OCA\Files_Sharing\External\Storage')) { |
225
|
|
|
Filesystem::initMountPoints($uidOwner); |
226
|
|
|
} else { |
227
|
|
|
// Probably a remote user, let's try to at least generate activities |
228
|
|
|
// for the current user |
229
|
|
|
$uidOwner = $this->currentUser; |
230
|
|
|
} |
231
|
|
|
} |
232
|
|
|
|
233
|
|
|
$info = Filesystem::getFileInfo($path); |
234
|
|
|
if ($info !== false) { |
235
|
|
|
$ownerView = new View('/' . $uidOwner . '/files'); |
236
|
|
|
$fileId = (int) $info['fileid']; |
237
|
|
|
$path = $ownerView->getPath($fileId); |
238
|
|
|
} |
239
|
|
|
|
240
|
|
|
return array($path, $uidOwner, $fileId); |
241
|
|
|
} |
242
|
|
|
|
243
|
|
|
/** |
244
|
|
|
* Manage sharing events |
245
|
|
|
* @param array $params The hook params |
246
|
|
|
*/ |
247
|
3 |
View Code Duplication |
public function share($params) { |
|
|
|
|
248
|
3 |
|
if ($params['itemType'] === 'file' || $params['itemType'] === 'folder') { |
249
|
3 |
|
if ((int) $params['shareType'] === Share::SHARE_TYPE_USER) { |
250
|
1 |
|
$this->shareFileOrFolderWithUser($params['shareWith'], (int) $params['fileSource'], $params['itemType'], $params['fileTarget'], true); |
251
|
2 |
|
} else if ((int) $params['shareType'] === Share::SHARE_TYPE_GROUP) { |
252
|
1 |
|
$this->shareFileOrFolderWithGroup($params['shareWith'], (int) $params['fileSource'], $params['itemType'], $params['fileTarget'], (int) $params['id'], true); |
253
|
1 |
|
} else if ((int) $params['shareType'] === Share::SHARE_TYPE_LINK) { |
254
|
1 |
|
$this->shareFileOrFolderByLink((int) $params['fileSource'], $params['itemType'], $params['uidOwner'], true); |
255
|
|
|
} |
256
|
|
|
} |
257
|
3 |
|
} |
258
|
|
|
|
259
|
|
|
/** |
260
|
|
|
* Manage sharing events |
261
|
|
|
* @param array $params The hook params |
262
|
|
|
*/ |
263
|
|
View Code Duplication |
public function unShare($params) { |
|
|
|
|
264
|
|
|
if ($params['itemType'] === 'file' || $params['itemType'] === 'folder') { |
265
|
|
|
if ((int) $params['shareType'] === Share::SHARE_TYPE_USER) { |
266
|
|
|
$this->shareFileOrFolderWithUser($params['shareWith'], (int) $params['fileSource'], $params['itemType'], $params['fileTarget'], false); |
267
|
|
|
} else if ((int) $params['shareType'] === Share::SHARE_TYPE_GROUP) { |
268
|
|
|
$this->shareFileOrFolderWithGroup($params['shareWith'], (int) $params['fileSource'], $params['itemType'], $params['fileTarget'], (int) $params['id'], false); |
269
|
|
|
} else if ((int) $params['shareType'] === Share::SHARE_TYPE_LINK) { |
270
|
|
|
$this->shareFileOrFolderByLink((int) $params['fileSource'], $params['itemType'], $params['uidOwner'], false); |
271
|
|
|
} |
272
|
|
|
} |
273
|
|
|
} |
274
|
|
|
|
275
|
|
|
/** |
276
|
|
|
* Sharing a file or folder with a user |
277
|
|
|
* |
278
|
|
|
* @param string $shareWith |
279
|
|
|
* @param int $fileSource File ID that is being shared |
280
|
|
|
* @param string $itemType File type that is being shared (file or folder) |
281
|
|
|
* @param string $fileTarget File path |
282
|
|
|
* @param bool $isSharing True if sharing, false if unsharing |
283
|
|
|
*/ |
284
|
2 |
|
protected function shareFileOrFolderWithUser($shareWith, $fileSource, $itemType, $fileTarget, $isSharing) { |
285
|
2 |
|
if ($isSharing) { |
286
|
2 |
|
$actionSharer = 'shared_user_self'; |
287
|
2 |
|
$actionOwner = 'reshared_user_by'; |
288
|
2 |
|
$actionUser = 'shared_with_by'; |
289
|
|
|
} else { |
290
|
|
|
$actionSharer = 'unshared_user_self'; |
291
|
|
|
$actionOwner = 'unshared_user_by'; |
292
|
|
|
$actionUser = 'unshared_by'; |
293
|
|
|
} |
294
|
|
|
|
295
|
|
|
// User performing the share |
296
|
2 |
|
$this->shareNotificationForSharer($actionSharer, $shareWith, $fileSource, $itemType); |
297
|
2 |
|
$this->shareNotificationForOriginalOwners($this->currentUser, $actionOwner, $shareWith, $fileSource, $itemType); |
|
|
|
|
298
|
|
|
|
299
|
|
|
// New shared user |
300
|
2 |
|
$this->addNotificationsForUser( |
301
|
2 |
|
$shareWith, $actionUser, [[$fileSource => $fileTarget], $this->currentUser], |
302
|
2 |
|
(int) $fileSource, $fileTarget, ($itemType === 'file'), |
303
|
2 |
|
$this->userSettings->getUserSetting($shareWith, 'stream', Files_Sharing::TYPE_SHARED), |
|
|
|
|
304
|
2 |
|
$this->userSettings->getUserSetting($shareWith, 'email', Files_Sharing::TYPE_SHARED) ? $this->userSettings->getUserSetting($shareWith, 'setting', 'batchtime') : 0 |
|
|
|
|
305
|
|
|
); |
306
|
2 |
|
} |
307
|
|
|
|
308
|
|
|
/** |
309
|
|
|
* Sharing a file or folder with a group |
310
|
|
|
* |
311
|
|
|
* @param string $shareWith |
312
|
|
|
* @param int $fileSource File ID that is being shared |
313
|
|
|
* @param string $itemType File type that is being shared (file or folder) |
314
|
|
|
* @param string $fileTarget File path |
315
|
|
|
* @param int $shareId The Share ID of this share |
316
|
|
|
* @param bool $isSharing True if sharing, false if unsharing |
317
|
|
|
*/ |
318
|
6 |
|
protected function shareFileOrFolderWithGroup($shareWith, $fileSource, $itemType, $fileTarget, $shareId, $isSharing) { |
319
|
6 |
|
if ($isSharing) { |
320
|
6 |
|
$actionSharer = 'shared_group_self'; |
321
|
6 |
|
$actionOwner = 'reshared_group_by'; |
322
|
6 |
|
$actionUser = 'shared_with_by'; |
323
|
|
|
} else { |
324
|
|
|
$actionSharer = 'unshared_group_self'; |
325
|
|
|
$actionOwner = 'unshared_group_by'; |
326
|
|
|
$actionUser = 'unshared_by'; |
327
|
|
|
} |
328
|
|
|
|
329
|
|
|
// Members of the new group |
330
|
6 |
|
$group = $this->groupManager->get($shareWith); |
331
|
6 |
|
if (!($group instanceof IGroup)) { |
|
|
|
|
332
|
1 |
|
return; |
333
|
|
|
} |
334
|
|
|
|
335
|
|
|
// User performing the share |
336
|
5 |
|
$this->shareNotificationForSharer($actionSharer, $shareWith, $fileSource, $itemType); |
337
|
5 |
|
$this->shareNotificationForOriginalOwners($this->currentUser, $actionOwner, $shareWith, $fileSource, $itemType); |
|
|
|
|
338
|
|
|
|
339
|
5 |
|
$offset = 0; |
340
|
5 |
|
$users = $group->searchUsers('', self::USER_BATCH_SIZE, $offset); |
341
|
5 |
|
while (!empty($users)) { |
342
|
4 |
|
$this->addNotificationsForGroupUsers($users, $actionUser, $fileSource, $itemType, $fileTarget, $shareId); |
343
|
4 |
|
$offset += self::USER_BATCH_SIZE; |
344
|
4 |
|
$users = $group->searchUsers('', self::USER_BATCH_SIZE, $offset); |
345
|
|
|
} |
346
|
5 |
|
} |
347
|
|
|
|
348
|
|
|
/** |
349
|
|
|
* @param IUser[] $usersInGroup |
350
|
|
|
* @param string $actionUser |
351
|
|
|
* @param int $fileSource File ID that is being shared |
352
|
|
|
* @param string $itemType File type that is being shared (file or folder) |
353
|
|
|
* @param string $fileTarget File path |
354
|
|
|
* @param int $shareId The Share ID of this share |
355
|
|
|
*/ |
356
|
4 |
|
protected function addNotificationsForGroupUsers(array $usersInGroup, $actionUser, $fileSource, $itemType, $fileTarget, $shareId) { |
357
|
4 |
|
$affectedUsers = []; |
358
|
|
|
|
359
|
4 |
|
foreach ($usersInGroup as $user) { |
360
|
4 |
|
$affectedUsers[$user->getUID()] = $fileTarget; |
361
|
|
|
} |
362
|
|
|
|
363
|
|
|
// Remove the triggering user, we already managed his notifications |
364
|
4 |
|
unset($affectedUsers[$this->currentUser]); |
365
|
|
|
|
366
|
4 |
|
if (empty($affectedUsers)) { |
367
|
1 |
|
return; |
368
|
|
|
} |
369
|
|
|
|
370
|
3 |
|
$userIds = array_keys($affectedUsers); |
371
|
3 |
|
$filteredStreamUsersInGroup = $this->userSettings->filterUsersBySetting($userIds, 'stream', Files_Sharing::TYPE_SHARED); |
372
|
3 |
|
$filteredEmailUsersInGroup = $this->userSettings->filterUsersBySetting($userIds, 'email', Files_Sharing::TYPE_SHARED); |
373
|
|
|
|
374
|
3 |
|
$affectedUsers = $this->fixPathsForShareExceptions($affectedUsers, $shareId); |
375
|
3 |
|
foreach ($affectedUsers as $user => $path) { |
376
|
3 |
|
if (empty($filteredStreamUsersInGroup[$user]) && empty($filteredEmailUsersInGroup[$user])) { |
377
|
2 |
|
continue; |
378
|
|
|
} |
379
|
|
|
|
380
|
1 |
|
$this->addNotificationsForUser( |
381
|
1 |
|
$user, $actionUser, [[$fileSource => $path], $this->currentUser], |
382
|
1 |
|
$fileSource, $path, ($itemType === 'file'), |
383
|
1 |
|
!empty($filteredStreamUsersInGroup[$user]), |
384
|
1 |
|
!empty($filteredEmailUsersInGroup[$user]) ? $filteredEmailUsersInGroup[$user] : 0 |
385
|
|
|
); |
386
|
|
|
} |
387
|
3 |
|
} |
388
|
|
|
|
389
|
|
|
/** |
390
|
|
|
* Check when there was a naming conflict and the target is different |
391
|
|
|
* for some of the users |
392
|
|
|
* |
393
|
|
|
* @param array $affectedUsers |
394
|
|
|
* @param int $shareId |
395
|
|
|
* @return mixed |
396
|
|
|
*/ |
397
|
|
|
protected function fixPathsForShareExceptions(array $affectedUsers, $shareId) { |
398
|
|
|
$queryBuilder = $this->connection->getQueryBuilder(); |
399
|
|
|
$queryBuilder->select(['share_with', 'file_target']) |
400
|
|
|
->from('share') |
401
|
|
|
->where($queryBuilder->expr()->eq('parent', $queryBuilder->createParameter('parent'))) |
402
|
|
|
->setParameter('parent', (int) $shareId); |
403
|
|
|
$query = $queryBuilder->execute(); |
404
|
|
|
|
405
|
|
|
while ($row = $query->fetch()) { |
406
|
|
|
$affectedUsers[$row['share_with']] = $row['file_target']; |
407
|
|
|
} |
408
|
|
|
|
409
|
|
|
return $affectedUsers; |
410
|
|
|
} |
411
|
|
|
|
412
|
|
|
/** |
413
|
|
|
* Sharing a file or folder via link/public |
414
|
|
|
* |
415
|
|
|
* @param int $fileSource File ID that is being shared |
416
|
|
|
* @param string $itemType File type that is being shared (file or folder) |
417
|
|
|
* @param string $linkOwner |
418
|
|
|
* @param bool $isSharing True if sharing, false if unsharing |
419
|
|
|
*/ |
420
|
2 |
|
protected function shareFileOrFolderByLink($fileSource, $itemType, $linkOwner, $isSharing) { |
421
|
2 |
|
if ($isSharing) { |
422
|
2 |
|
$actionSharer = 'shared_link_self'; |
423
|
2 |
|
$actionOwner = 'reshared_link_by'; |
424
|
|
|
} else if ($this->currentUser !== $linkOwner) { |
425
|
|
|
// Link expired |
426
|
|
|
$actionSharer = 'link_expired'; |
427
|
|
|
$actionOwner = 'link_by_expired'; |
428
|
|
|
$this->currentUser = $linkOwner; |
429
|
|
|
\OC::$server->getUserFolder($linkOwner); |
430
|
|
|
} else { |
431
|
|
|
$actionSharer = 'unshared_link_self'; |
432
|
|
|
$actionOwner = 'unshared_link_by'; |
433
|
|
|
} |
434
|
|
|
|
435
|
2 |
|
$this->view->chroot('/' . $this->currentUser . '/files'); |
436
|
|
|
|
437
|
|
|
try { |
438
|
2 |
|
$path = $this->view->getPath($fileSource); |
439
|
1 |
|
} catch (NotFoundException $e) { |
|
|
|
|
440
|
1 |
|
return; |
441
|
|
|
} |
442
|
|
|
|
443
|
1 |
|
$this->shareNotificationForOriginalOwners($this->currentUser, $actionOwner, '', $fileSource, $itemType); |
|
|
|
|
444
|
|
|
|
445
|
1 |
|
$this->addNotificationsForUser( |
446
|
1 |
|
$this->currentUser, $actionSharer, [[$fileSource => $path]], |
|
|
|
|
447
|
1 |
|
(int) $fileSource, $path, ($itemType === 'file'), |
448
|
1 |
|
$this->userSettings->getUserSetting($this->currentUser, 'stream', Files_Sharing::TYPE_SHARED), |
|
|
|
|
449
|
1 |
|
$this->userSettings->getUserSetting($this->currentUser, 'email', Files_Sharing::TYPE_SHARED) ? $this->userSettings->getUserSetting($this->currentUser, 'setting', 'batchtime') : 0 |
|
|
|
|
450
|
|
|
); |
451
|
1 |
|
} |
452
|
|
|
|
453
|
|
|
/** |
454
|
|
|
* Add notifications for the user that shares a file/folder |
455
|
|
|
* |
456
|
|
|
* @param string $subject |
457
|
|
|
* @param string $shareWith |
458
|
|
|
* @param int $fileSource |
459
|
|
|
* @param string $itemType |
460
|
|
|
*/ |
461
|
2 |
|
protected function shareNotificationForSharer($subject, $shareWith, $fileSource, $itemType) { |
462
|
2 |
|
$this->view->chroot('/' . $this->currentUser . '/files'); |
463
|
|
|
|
464
|
|
|
try { |
465
|
2 |
|
$path = $this->view->getPath($fileSource); |
466
|
1 |
|
} catch (NotFoundException $e) { |
|
|
|
|
467
|
1 |
|
return; |
468
|
|
|
} |
469
|
|
|
|
470
|
1 |
|
$this->addNotificationsForUser( |
471
|
1 |
|
$this->currentUser, $subject, [[$fileSource => $path], $shareWith], |
|
|
|
|
472
|
1 |
|
$fileSource, $path, ($itemType === 'file'), |
473
|
1 |
|
$this->userSettings->getUserSetting($this->currentUser, 'stream', Files_Sharing::TYPE_SHARED), |
|
|
|
|
474
|
1 |
|
$this->userSettings->getUserSetting($this->currentUser, 'email', Files_Sharing::TYPE_SHARED) ? $this->userSettings->getUserSetting($this->currentUser, 'setting', 'batchtime') : 0 |
|
|
|
|
475
|
|
|
); |
476
|
1 |
|
} |
477
|
|
|
|
478
|
|
|
/** |
479
|
|
|
* Add notifications for the user that shares a file/folder |
480
|
|
|
* |
481
|
|
|
* @param string $owner |
482
|
|
|
* @param string $subject |
483
|
|
|
* @param string $shareWith |
484
|
|
|
* @param int $fileSource |
485
|
|
|
* @param string $itemType |
486
|
|
|
*/ |
487
|
2 |
|
protected function reshareNotificationForSharer($owner, $subject, $shareWith, $fileSource, $itemType) { |
488
|
2 |
|
$this->view->chroot('/' . $owner . '/files'); |
489
|
|
|
|
490
|
|
|
try { |
491
|
2 |
|
$path = $this->view->getPath($fileSource); |
492
|
1 |
|
} catch (NotFoundException $e) { |
|
|
|
|
493
|
1 |
|
return; |
494
|
|
|
} |
495
|
|
|
|
496
|
1 |
|
$this->addNotificationsForUser( |
497
|
1 |
|
$owner, $subject, [[$fileSource => $path], $this->currentUser, $shareWith], |
498
|
1 |
|
$fileSource, $path, ($itemType === 'file'), |
499
|
1 |
|
$this->userSettings->getUserSetting($owner, 'stream', Files_Sharing::TYPE_SHARED), |
|
|
|
|
500
|
1 |
|
$this->userSettings->getUserSetting($owner, 'email', Files_Sharing::TYPE_SHARED) ? $this->userSettings->getUserSetting($owner, 'setting', 'batchtime') : 0 |
|
|
|
|
501
|
|
|
); |
502
|
1 |
|
} |
503
|
|
|
|
504
|
|
|
/** |
505
|
|
|
* Add notifications for the owners whose files have been reshared |
506
|
|
|
* |
507
|
|
|
* @param string $currentOwner |
508
|
|
|
* @param string $subject |
509
|
|
|
* @param string $shareWith |
510
|
|
|
* @param int $fileSource |
511
|
|
|
* @param string $itemType |
512
|
|
|
*/ |
513
|
10 |
|
protected function shareNotificationForOriginalOwners($currentOwner, $subject, $shareWith, $fileSource, $itemType) { |
514
|
|
|
// Get the full path of the current user |
515
|
10 |
|
$this->view->chroot('/' . $currentOwner . '/files'); |
516
|
|
|
|
517
|
|
|
try { |
518
|
10 |
|
$path = $this->view->getPath($fileSource); |
519
|
1 |
|
} catch (NotFoundException $e) { |
|
|
|
|
520
|
1 |
|
return; |
521
|
|
|
} |
522
|
|
|
|
523
|
|
|
/** |
524
|
|
|
* Get the original owner and his path |
525
|
|
|
*/ |
526
|
9 |
|
$owner = $this->view->getOwner($path); |
527
|
9 |
|
if ($owner !== $currentOwner) { |
528
|
7 |
|
$this->reshareNotificationForSharer($owner, $subject, $shareWith, $fileSource, $itemType); |
529
|
|
|
} |
530
|
|
|
|
531
|
|
|
/** |
532
|
|
|
* Get the sharee who shared the item with the currentUser |
533
|
|
|
*/ |
534
|
9 |
|
$this->view->chroot('/' . $currentOwner . '/files'); |
535
|
9 |
|
$mount = $this->view->getMount($path); |
536
|
9 |
|
if (!($mount instanceof IMountPoint)) { |
|
|
|
|
537
|
1 |
|
return; |
538
|
|
|
} |
539
|
|
|
|
540
|
8 |
|
$storage = $mount->getStorage(); |
541
|
8 |
|
if (!$storage->instanceOfStorage('OC\Files\Storage\Shared')) { |
542
|
1 |
|
return; |
543
|
|
|
} |
544
|
|
|
|
545
|
|
|
/** @var \OC\Files\Storage\Shared $storage */ |
546
|
7 |
|
$shareOwner = $storage->getSharedFrom(); |
547
|
7 |
|
if ($shareOwner === '' || $shareOwner === null || $shareOwner === $owner || $shareOwner === $currentOwner) { |
548
|
5 |
|
return; |
549
|
|
|
} |
550
|
|
|
|
551
|
2 |
|
$this->reshareNotificationForSharer($shareOwner, $subject, $shareWith, $fileSource, $itemType); |
552
|
2 |
|
} |
553
|
|
|
|
554
|
|
|
/** |
555
|
|
|
* Adds the activity and email for a user when the settings require it |
556
|
|
|
* |
557
|
|
|
* @param string $user |
558
|
|
|
* @param string $subject |
559
|
|
|
* @param array $subjectParams |
560
|
|
|
* @param int $fileId |
561
|
|
|
* @param string $path |
562
|
|
|
* @param bool $isFile If the item is a file, we link to the parent directory |
563
|
|
|
* @param bool $streamSetting |
564
|
|
|
* @param int $emailSetting |
565
|
|
|
* @param string $type |
566
|
|
|
*/ |
567
|
11 |
|
protected function addNotificationsForUser($user, $subject, $subjectParams, $fileId, $path, $isFile, $streamSetting, $emailSetting, $type = Files_Sharing::TYPE_SHARED) { |
568
|
11 |
|
if (!$streamSetting && !$emailSetting) { |
569
|
1 |
|
return; |
570
|
|
|
} |
571
|
|
|
|
572
|
10 |
|
$selfAction = $user === $this->currentUser; |
573
|
10 |
|
$app = $type === Files_Sharing::TYPE_SHARED ? 'files_sharing' : 'files'; |
574
|
10 |
|
$link = $this->urlGenerator->linkToRouteAbsolute('files.view.index', array( |
575
|
10 |
|
'dir' => ($isFile) ? dirname($path) : $path, |
576
|
|
|
)); |
577
|
|
|
|
578
|
10 |
|
$objectType = ($fileId) ? 'files' : ''; |
579
|
|
|
|
580
|
10 |
|
$event = $this->manager->generateEvent(); |
581
|
10 |
|
$event->setApp($app) |
582
|
10 |
|
->setType($type) |
583
|
10 |
|
->setAffectedUser($user) |
584
|
10 |
|
->setAuthor($this->currentUser) |
585
|
10 |
|
->setTimestamp(time()) |
586
|
10 |
|
->setSubject($subject, $subjectParams) |
587
|
10 |
|
->setObject($objectType, $fileId, $path) |
588
|
10 |
|
->setLink($link); |
589
|
|
|
|
590
|
|
|
// Add activity to stream |
591
|
10 |
|
if ($streamSetting && (!$selfAction || $this->userSettings->getUserSetting($this->currentUser, 'setting', 'self'))) { |
592
|
3 |
|
$this->activityData->send($event); |
593
|
|
|
} |
594
|
|
|
|
595
|
|
|
// Add activity to mail queue |
596
|
10 |
|
if ($emailSetting && (!$selfAction || $this->userSettings->getUserSetting($this->currentUser, 'setting', 'selfemail'))) { |
597
|
5 |
|
$latestSend = time() + $emailSetting; |
598
|
5 |
|
$this->activityData->storeMail($event, $latestSend); |
599
|
|
|
} |
600
|
10 |
|
} |
601
|
|
|
} |
602
|
|
|
|
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.