Completed
Pull Request — master (#8298)
by Joas
14:10
created
apps/files/lib/Activity/Provider.php 4 patches
Doc Comments   +6 added lines patch added patch discarded remove patch
@@ -112,6 +112,9 @@  discard block
 block discarded – undo
112 112
 		return $this->parseLongVersion($event, $previousEvent);
113 113
 	}
114 114
 
115
+	/**
116
+	 * @param string $icon
117
+	 */
115 118
 	protected function setIcon(IEvent $event, $icon) {
116 119
 		if ($this->activityManager->getRequirePNG()) {
117 120
 			$event->setIcon($this->url->getAbsoluteURL($this->url->imagePath('files', $icon . '.png')));
@@ -252,6 +255,9 @@  discard block
 block discarded – undo
252 255
 		return $event;
253 256
 	}
254 257
 
258
+	/**
259
+	 * @param string $subject
260
+	 */
255 261
 	protected function setSubjects(IEvent $event, $subject, array $parameters) {
256 262
 		$placeholders = $replacements = [];
257 263
 		foreach ($parameters as $placeholder => $parameter) {
Please login to merge, or discard this patch.
Unused Use Statements   -1 removed lines patch added patch discarded remove patch
@@ -31,7 +31,6 @@
 block discarded – undo
31 31
 use OCP\Files\Folder;
32 32
 use OCP\Files\IRootFolder;
33 33
 use OCP\Files\Node;
34
-use OCP\Files\NotFoundException;
35 34
 use OCP\IL10N;
36 35
 use OCP\IURLGenerator;
37 36
 use OCP\IUser;
Please login to merge, or discard this patch.
Indentation   +409 added lines, -409 removed lines patch added patch discarded remove patch
@@ -40,413 +40,413 @@
 block discarded – undo
40 40
 
41 41
 class Provider implements IProvider {
42 42
 
43
-	/** @var IFactory */
44
-	protected $languageFactory;
45
-
46
-	/** @var IL10N */
47
-	protected $l;
48
-	/** @var IL10N */
49
-	protected $activityLang;
50
-
51
-	/** @var IURLGenerator */
52
-	protected $url;
53
-
54
-	/** @var IManager */
55
-	protected $activityManager;
56
-
57
-	/** @var IUserManager */
58
-	protected $userManager;
59
-
60
-	/** @var IRootFolder */
61
-	protected $rootFolder;
62
-
63
-	/** @var IEventMerger */
64
-	protected $eventMerger;
65
-
66
-	/** @var string[] cached displayNames - key is the UID and value the displayname */
67
-	protected $displayNames = [];
68
-
69
-	protected $fileIsEncrypted = false;
70
-
71
-	/**
72
-	 * @param IFactory $languageFactory
73
-	 * @param IURLGenerator $url
74
-	 * @param IManager $activityManager
75
-	 * @param IUserManager $userManager
76
-	 * @param IRootFolder $rootFolder
77
-	 * @param IEventMerger $eventMerger
78
-	 */
79
-	public function __construct(IFactory $languageFactory, IURLGenerator $url, IManager $activityManager, IUserManager $userManager, IRootFolder $rootFolder, IEventMerger $eventMerger) {
80
-		$this->languageFactory = $languageFactory;
81
-		$this->url = $url;
82
-		$this->activityManager = $activityManager;
83
-		$this->userManager = $userManager;
84
-		$this->rootFolder = $rootFolder;
85
-		$this->eventMerger = $eventMerger;
86
-	}
87
-
88
-	/**
89
-	 * @param string $language
90
-	 * @param IEvent $event
91
-	 * @param IEvent|null $previousEvent
92
-	 * @return IEvent
93
-	 * @throws \InvalidArgumentException
94
-	 * @since 11.0.0
95
-	 */
96
-	public function parse($language, IEvent $event, IEvent $previousEvent = null) {
97
-		if ($event->getApp() !== 'files') {
98
-			throw new \InvalidArgumentException();
99
-		}
100
-
101
-		$this->l = $this->languageFactory->get('files', $language);
102
-		$this->activityLang = $this->languageFactory->get('activity', $language);
103
-
104
-		if ($this->activityManager->isFormattingFilteredObject()) {
105
-			try {
106
-				return $this->parseShortVersion($event, $previousEvent);
107
-			} catch (\InvalidArgumentException $e) {
108
-				// Ignore and simply use the long version...
109
-			}
110
-		}
111
-
112
-		return $this->parseLongVersion($event, $previousEvent);
113
-	}
114
-
115
-	protected function setIcon(IEvent $event, $icon) {
116
-		if ($this->activityManager->getRequirePNG()) {
117
-			$event->setIcon($this->url->getAbsoluteURL($this->url->imagePath('files', $icon . '.png')));
118
-		} else {
119
-			$event->setIcon($this->url->getAbsoluteURL($this->url->imagePath('files', $icon . '.svg')));
120
-		}
121
-	}
122
-
123
-	/**
124
-	 * @param IEvent $event
125
-	 * @param IEvent|null $previousEvent
126
-	 * @return IEvent
127
-	 * @throws \InvalidArgumentException
128
-	 * @since 11.0.0
129
-	 */
130
-	public function parseShortVersion(IEvent $event, IEvent $previousEvent = null) {
131
-		$parsedParameters = $this->getParameters($event);
132
-
133
-		if ($event->getSubject() === 'created_by') {
134
-			$subject = $this->l->t('Created by {user}');
135
-			$this->setIcon($event, 'add-color');
136
-		} else if ($event->getSubject() === 'changed_by') {
137
-			$subject = $this->l->t('Changed by {user}');
138
-			$this->setIcon($event, 'change');
139
-		} else if ($event->getSubject() === 'deleted_by') {
140
-			$subject = $this->l->t('Deleted by {user}');
141
-			$this->setIcon($event, 'delete-color');
142
-		} else if ($event->getSubject() === 'restored_by') {
143
-			$subject = $this->l->t('Restored by {user}');
144
-		} else if ($event->getSubject() === 'renamed_by') {
145
-			$subject = $this->l->t('Renamed by {user}');
146
-			$this->setIcon($event, 'change');
147
-		} else if ($event->getSubject() === 'moved_by') {
148
-			$subject = $this->l->t('Moved by {user}');
149
-			$this->setIcon($event, 'change');
150
-		} else {
151
-			throw new \InvalidArgumentException();
152
-		}
153
-
154
-		if (!isset($parsedParameters['user'])) {
155
-			// External user via public link share
156
-			$subject = str_replace('{user}', $this->activityLang->t('"remote user"'), $subject);
157
-		}
158
-
159
-		$this->setSubjects($event, $subject, $parsedParameters);
160
-
161
-		return $this->eventMerger->mergeEvents('user', $event, $previousEvent);
162
-	}
163
-
164
-	/**
165
-	 * @param IEvent $event
166
-	 * @param IEvent|null $previousEvent
167
-	 * @return IEvent
168
-	 * @throws \InvalidArgumentException
169
-	 * @since 11.0.0
170
-	 */
171
-	public function parseLongVersion(IEvent $event, IEvent $previousEvent = null) {
172
-		$this->fileIsEncrypted = false;
173
-		$parsedParameters = $this->getParameters($event);
174
-
175
-		if ($event->getSubject() === 'created_self') {
176
-			$subject = $this->l->t('You created {file}');
177
-			if ($this->fileIsEncrypted) {
178
-				$subject = $this->l->t('You created an encrypted file in {file}');
179
-			}
180
-			$this->setIcon($event, 'add-color');
181
-		} else if ($event->getSubject() === 'created_by') {
182
-			$subject = $this->l->t('{user} created {file}');
183
-			if ($this->fileIsEncrypted) {
184
-				$subject = $this->l->t('{user} created an encrypted file in {file}');
185
-			}
186
-			$this->setIcon($event, 'add-color');
187
-		} else if ($event->getSubject() === 'created_public') {
188
-			$subject = $this->l->t('{file} was created in a public folder');
189
-			$this->setIcon($event, 'add-color');
190
-		} else if ($event->getSubject() === 'changed_self') {
191
-			$subject = $this->l->t('You changed {file}');
192
-			if ($this->fileIsEncrypted) {
193
-				$subject = $this->l->t('You changed an encrypted file in {file}');
194
-			}
195
-			$this->setIcon($event, 'change');
196
-		} else if ($event->getSubject() === 'changed_by') {
197
-			$subject = $this->l->t('{user} changed {file}');
198
-			if ($this->fileIsEncrypted) {
199
-				$subject = $this->l->t('{user} changed an encrypted file in {file}');
200
-			}
201
-			$this->setIcon($event, 'change');
202
-		} else if ($event->getSubject() === 'deleted_self') {
203
-			$subject = $this->l->t('You deleted {file}');
204
-			if ($this->fileIsEncrypted) {
205
-				$subject = $this->l->t('You deleted an encrypted file in {file}');
206
-			}
207
-			$this->setIcon($event, 'delete-color');
208
-		} else if ($event->getSubject() === 'deleted_by') {
209
-			$subject = $this->l->t('{user} deleted {file}');
210
-			if ($this->fileIsEncrypted) {
211
-				$subject = $this->l->t('{user} deleted an encrypted file in {file}');
212
-			}
213
-			$this->setIcon($event, 'delete-color');
214
-		} else if ($event->getSubject() === 'restored_self') {
215
-			$subject = $this->l->t('You restored {file}');
216
-		} else if ($event->getSubject() === 'restored_by') {
217
-			$subject = $this->l->t('{user} restored {file}');
218
-		} else if ($event->getSubject() === 'renamed_self') {
219
-			$subject = $this->l->t('You renamed {oldfile} to {newfile}');
220
-			$this->setIcon($event, 'change');
221
-		} else if ($event->getSubject() === 'renamed_by') {
222
-			$subject = $this->l->t('{user} renamed {oldfile} to {newfile}');
223
-			$this->setIcon($event, 'change');
224
-		} else if ($event->getSubject() === 'moved_self') {
225
-			$subject = $this->l->t('You moved {oldfile} to {newfile}');
226
-			$this->setIcon($event, 'change');
227
-		} else if ($event->getSubject() === 'moved_by') {
228
-			$subject = $this->l->t('{user} moved {oldfile} to {newfile}');
229
-			$this->setIcon($event, 'change');
230
-		} else {
231
-			throw new \InvalidArgumentException();
232
-		}
233
-
234
-		if ($this->fileIsEncrypted) {
235
-			$event->setSubject($event->getSubject() . '_enc', $event->getSubjectParameters());
236
-		}
237
-
238
-		if (!isset($parsedParameters['user'])) {
239
-			// External user via public link share
240
-			$subject = str_replace('{user}', $this->activityLang->t('"remote user"'), $subject);
241
-		}
242
-
243
-		$this->setSubjects($event, $subject, $parsedParameters);
244
-
245
-		$event = $this->eventMerger->mergeEvents('file', $event, $previousEvent);
246
-
247
-		if ($event->getChildEvent() === null) {
248
-			// Couldn't group by file, maybe we can group by user
249
-			$event = $this->eventMerger->mergeEvents('user', $event, $previousEvent);
250
-		}
251
-
252
-		return $event;
253
-	}
254
-
255
-	protected function setSubjects(IEvent $event, $subject, array $parameters) {
256
-		$placeholders = $replacements = [];
257
-		foreach ($parameters as $placeholder => $parameter) {
258
-			$placeholders[] = '{' . $placeholder . '}';
259
-			if ($parameter['type'] === 'file') {
260
-				$replacements[] = $parameter['path'];
261
-			} else {
262
-				$replacements[] = $parameter['name'];
263
-			}
264
-		}
265
-
266
-		$event->setParsedSubject(str_replace($placeholders, $replacements, $subject))
267
-			->setRichSubject($subject, $parameters);
268
-	}
269
-
270
-	/**
271
-	 * @param IEvent $event
272
-	 * @return array
273
-	 * @throws \InvalidArgumentException
274
-	 */
275
-	protected function getParameters(IEvent $event) {
276
-		$parameters = $event->getSubjectParameters();
277
-		switch ($event->getSubject()) {
278
-			case 'created_self':
279
-			case 'created_public':
280
-			case 'changed_self':
281
-			case 'deleted_self':
282
-			case 'restored_self':
283
-				return [
284
-					'file' => $this->getFile($parameters[0], $event),
285
-				];
286
-			case 'created_by':
287
-			case 'changed_by':
288
-			case 'deleted_by':
289
-			case 'restored_by':
290
-				if ($parameters[1] === '') {
291
-					// External user via public link share
292
-					return [
293
-						'file' => $this->getFile($parameters[0], $event),
294
-					];
295
-				}
296
-				return [
297
-					'file' => $this->getFile($parameters[0], $event),
298
-					'user' => $this->getUser($parameters[1]),
299
-				];
300
-			case 'renamed_self':
301
-			case 'moved_self':
302
-				return [
303
-					'newfile' => $this->getFile($parameters[0]),
304
-					'oldfile' => $this->getFile($parameters[1]),
305
-				];
306
-			case 'renamed_by':
307
-			case 'moved_by':
308
-				if ($parameters[1] === '') {
309
-					// External user via public link share
310
-					return [
311
-						'newfile' => $this->getFile($parameters[0]),
312
-						'oldfile' => $this->getFile($parameters[2]),
313
-					];
314
-				}
315
-				return [
316
-					'newfile' => $this->getFile($parameters[0]),
317
-					'user' => $this->getUser($parameters[1]),
318
-					'oldfile' => $this->getFile($parameters[2]),
319
-				];
320
-		}
321
-		return [];
322
-	}
323
-
324
-	/**
325
-	 * @param array|string $parameter
326
-	 * @param IEvent|null $event
327
-	 * @return array
328
-	 * @throws \InvalidArgumentException
329
-	 */
330
-	protected function getFile($parameter, IEvent $event = null) {
331
-		if (is_array($parameter)) {
332
-			$path = reset($parameter);
333
-			$id = (string) key($parameter);
334
-		} else if ($event !== null) {
335
-			// Legacy from before ownCloud 8.2
336
-			$path = $parameter;
337
-			$id = $event->getObjectId();
338
-		} else {
339
-			throw new \InvalidArgumentException('Could not generate file parameter');
340
-		}
341
-
342
-		$encryptionContainer = $this->getEndToEndEncryptionContainer($id, basename($path));
343
-		if ($encryptionContainer instanceof Folder) {
344
-			$this->fileIsEncrypted = true;
345
-			return [
346
-				'type' => 'file',
347
-				'id' => $encryptionContainer->getId(),
348
-				'name' => $encryptionContainer->getName(),
349
-				'path' => trim($encryptionContainer->getPath(), '/'), // FIXME remove /user/files/...
350
-				'link' => $this->url->linkToRouteAbsolute('files.viewcontroller.showFile', ['fileid' => $encryptionContainer->getId()]),
351
-			];
352
-		}
353
-
354
-		return [
355
-			'type' => 'file',
356
-			'id' => $id,
357
-			'name' => basename($path),
358
-			'path' => trim($path, '/'),
359
-			'link' => $this->url->linkToRouteAbsolute('files.viewcontroller.showFile', ['fileid' => $id]),
360
-		];
361
-	}
362
-
363
-	protected $fileEncrypted = [];
364
-
365
-	/**
366
-	 * Check if a file is end2end encrypted
367
-	 * @param int $fileId
368
-	 * @param string $fileName
369
-	 * @return bool
370
-	 */
371
-	protected function getEndToEndEncryptionContainer($fileId, $fileName) {
372
-		if (isset($this->fileEncrypted[$fileId])) {
373
-			return $this->fileEncrypted[$fileId];
374
-		}
375
-
376
-		if (!preg_match('/^[0-9a-fA-F]{32}$/', $fileName)) {
377
-			$this->fileEncrypted[$fileId] = false;
378
-			return $this->fileEncrypted[$fileId];
379
-		}
380
-
381
-		$userFolder = $this->rootFolder->getUserFolder($this->activityManager->getCurrentUserId());
382
-		$files = $userFolder->getById($fileId);
383
-		if (empty($files)) {
384
-			return null;
385
-		}
386
-
387
-		$file = array_shift($files);
388
-		if ($file instanceof Folder && $file->isEncrypted()) {
389
-			// If the folder is encrypted, it is the Container,
390
-			// but can be the name is just fine.
391
-			$this->fileEncrypted[$fileId] = true;
392
-			return null;
393
-		}
394
-
395
-		$this->fileEncrypted[$fileId] = $this->getParentEndToEndEncryptionContainer($userFolder, $file);
396
-		return $this->fileEncrypted[$fileId];
397
-	}
398
-
399
-	/**
400
-	 * Check all parents until the user's root folder if one is encrypted
401
-	 *
402
-	 * @param Folder $userFolder
403
-	 * @param Node $file
404
-	 * @return Node|null
405
-	 */
406
-	protected function getParentEndToEndEncryptionContainer(Folder $userFolder, Node $file) {
407
-		try {
408
-			$parent = $file->getParent();
409
-
410
-			if ($userFolder->getId() === $parent->getId()) {
411
-				return null;
412
-			}
413
-		} catch (\Exception $e) {
414
-			return null;
415
-		}
416
-
417
-		if ($parent->isEncrypted()) {
418
-			return $parent;
419
-		}
420
-
421
-		return $this->getParentEndToEndEncryptionContainer($userFolder, $file);
422
-	}
423
-
424
-	/**
425
-	 * @param string $uid
426
-	 * @return array
427
-	 */
428
-	protected function getUser($uid) {
429
-		if (!isset($this->displayNames[$uid])) {
430
-			$this->displayNames[$uid] = $this->getDisplayName($uid);
431
-		}
432
-
433
-		return [
434
-			'type' => 'user',
435
-			'id' => $uid,
436
-			'name' => $this->displayNames[$uid],
437
-		];
438
-	}
439
-
440
-	/**
441
-	 * @param string $uid
442
-	 * @return string
443
-	 */
444
-	protected function getDisplayName($uid) {
445
-		$user = $this->userManager->get($uid);
446
-		if ($user instanceof IUser) {
447
-			return $user->getDisplayName();
448
-		} else {
449
-			return $uid;
450
-		}
451
-	}
43
+    /** @var IFactory */
44
+    protected $languageFactory;
45
+
46
+    /** @var IL10N */
47
+    protected $l;
48
+    /** @var IL10N */
49
+    protected $activityLang;
50
+
51
+    /** @var IURLGenerator */
52
+    protected $url;
53
+
54
+    /** @var IManager */
55
+    protected $activityManager;
56
+
57
+    /** @var IUserManager */
58
+    protected $userManager;
59
+
60
+    /** @var IRootFolder */
61
+    protected $rootFolder;
62
+
63
+    /** @var IEventMerger */
64
+    protected $eventMerger;
65
+
66
+    /** @var string[] cached displayNames - key is the UID and value the displayname */
67
+    protected $displayNames = [];
68
+
69
+    protected $fileIsEncrypted = false;
70
+
71
+    /**
72
+     * @param IFactory $languageFactory
73
+     * @param IURLGenerator $url
74
+     * @param IManager $activityManager
75
+     * @param IUserManager $userManager
76
+     * @param IRootFolder $rootFolder
77
+     * @param IEventMerger $eventMerger
78
+     */
79
+    public function __construct(IFactory $languageFactory, IURLGenerator $url, IManager $activityManager, IUserManager $userManager, IRootFolder $rootFolder, IEventMerger $eventMerger) {
80
+        $this->languageFactory = $languageFactory;
81
+        $this->url = $url;
82
+        $this->activityManager = $activityManager;
83
+        $this->userManager = $userManager;
84
+        $this->rootFolder = $rootFolder;
85
+        $this->eventMerger = $eventMerger;
86
+    }
87
+
88
+    /**
89
+     * @param string $language
90
+     * @param IEvent $event
91
+     * @param IEvent|null $previousEvent
92
+     * @return IEvent
93
+     * @throws \InvalidArgumentException
94
+     * @since 11.0.0
95
+     */
96
+    public function parse($language, IEvent $event, IEvent $previousEvent = null) {
97
+        if ($event->getApp() !== 'files') {
98
+            throw new \InvalidArgumentException();
99
+        }
100
+
101
+        $this->l = $this->languageFactory->get('files', $language);
102
+        $this->activityLang = $this->languageFactory->get('activity', $language);
103
+
104
+        if ($this->activityManager->isFormattingFilteredObject()) {
105
+            try {
106
+                return $this->parseShortVersion($event, $previousEvent);
107
+            } catch (\InvalidArgumentException $e) {
108
+                // Ignore and simply use the long version...
109
+            }
110
+        }
111
+
112
+        return $this->parseLongVersion($event, $previousEvent);
113
+    }
114
+
115
+    protected function setIcon(IEvent $event, $icon) {
116
+        if ($this->activityManager->getRequirePNG()) {
117
+            $event->setIcon($this->url->getAbsoluteURL($this->url->imagePath('files', $icon . '.png')));
118
+        } else {
119
+            $event->setIcon($this->url->getAbsoluteURL($this->url->imagePath('files', $icon . '.svg')));
120
+        }
121
+    }
122
+
123
+    /**
124
+     * @param IEvent $event
125
+     * @param IEvent|null $previousEvent
126
+     * @return IEvent
127
+     * @throws \InvalidArgumentException
128
+     * @since 11.0.0
129
+     */
130
+    public function parseShortVersion(IEvent $event, IEvent $previousEvent = null) {
131
+        $parsedParameters = $this->getParameters($event);
132
+
133
+        if ($event->getSubject() === 'created_by') {
134
+            $subject = $this->l->t('Created by {user}');
135
+            $this->setIcon($event, 'add-color');
136
+        } else if ($event->getSubject() === 'changed_by') {
137
+            $subject = $this->l->t('Changed by {user}');
138
+            $this->setIcon($event, 'change');
139
+        } else if ($event->getSubject() === 'deleted_by') {
140
+            $subject = $this->l->t('Deleted by {user}');
141
+            $this->setIcon($event, 'delete-color');
142
+        } else if ($event->getSubject() === 'restored_by') {
143
+            $subject = $this->l->t('Restored by {user}');
144
+        } else if ($event->getSubject() === 'renamed_by') {
145
+            $subject = $this->l->t('Renamed by {user}');
146
+            $this->setIcon($event, 'change');
147
+        } else if ($event->getSubject() === 'moved_by') {
148
+            $subject = $this->l->t('Moved by {user}');
149
+            $this->setIcon($event, 'change');
150
+        } else {
151
+            throw new \InvalidArgumentException();
152
+        }
153
+
154
+        if (!isset($parsedParameters['user'])) {
155
+            // External user via public link share
156
+            $subject = str_replace('{user}', $this->activityLang->t('"remote user"'), $subject);
157
+        }
158
+
159
+        $this->setSubjects($event, $subject, $parsedParameters);
160
+
161
+        return $this->eventMerger->mergeEvents('user', $event, $previousEvent);
162
+    }
163
+
164
+    /**
165
+     * @param IEvent $event
166
+     * @param IEvent|null $previousEvent
167
+     * @return IEvent
168
+     * @throws \InvalidArgumentException
169
+     * @since 11.0.0
170
+     */
171
+    public function parseLongVersion(IEvent $event, IEvent $previousEvent = null) {
172
+        $this->fileIsEncrypted = false;
173
+        $parsedParameters = $this->getParameters($event);
174
+
175
+        if ($event->getSubject() === 'created_self') {
176
+            $subject = $this->l->t('You created {file}');
177
+            if ($this->fileIsEncrypted) {
178
+                $subject = $this->l->t('You created an encrypted file in {file}');
179
+            }
180
+            $this->setIcon($event, 'add-color');
181
+        } else if ($event->getSubject() === 'created_by') {
182
+            $subject = $this->l->t('{user} created {file}');
183
+            if ($this->fileIsEncrypted) {
184
+                $subject = $this->l->t('{user} created an encrypted file in {file}');
185
+            }
186
+            $this->setIcon($event, 'add-color');
187
+        } else if ($event->getSubject() === 'created_public') {
188
+            $subject = $this->l->t('{file} was created in a public folder');
189
+            $this->setIcon($event, 'add-color');
190
+        } else if ($event->getSubject() === 'changed_self') {
191
+            $subject = $this->l->t('You changed {file}');
192
+            if ($this->fileIsEncrypted) {
193
+                $subject = $this->l->t('You changed an encrypted file in {file}');
194
+            }
195
+            $this->setIcon($event, 'change');
196
+        } else if ($event->getSubject() === 'changed_by') {
197
+            $subject = $this->l->t('{user} changed {file}');
198
+            if ($this->fileIsEncrypted) {
199
+                $subject = $this->l->t('{user} changed an encrypted file in {file}');
200
+            }
201
+            $this->setIcon($event, 'change');
202
+        } else if ($event->getSubject() === 'deleted_self') {
203
+            $subject = $this->l->t('You deleted {file}');
204
+            if ($this->fileIsEncrypted) {
205
+                $subject = $this->l->t('You deleted an encrypted file in {file}');
206
+            }
207
+            $this->setIcon($event, 'delete-color');
208
+        } else if ($event->getSubject() === 'deleted_by') {
209
+            $subject = $this->l->t('{user} deleted {file}');
210
+            if ($this->fileIsEncrypted) {
211
+                $subject = $this->l->t('{user} deleted an encrypted file in {file}');
212
+            }
213
+            $this->setIcon($event, 'delete-color');
214
+        } else if ($event->getSubject() === 'restored_self') {
215
+            $subject = $this->l->t('You restored {file}');
216
+        } else if ($event->getSubject() === 'restored_by') {
217
+            $subject = $this->l->t('{user} restored {file}');
218
+        } else if ($event->getSubject() === 'renamed_self') {
219
+            $subject = $this->l->t('You renamed {oldfile} to {newfile}');
220
+            $this->setIcon($event, 'change');
221
+        } else if ($event->getSubject() === 'renamed_by') {
222
+            $subject = $this->l->t('{user} renamed {oldfile} to {newfile}');
223
+            $this->setIcon($event, 'change');
224
+        } else if ($event->getSubject() === 'moved_self') {
225
+            $subject = $this->l->t('You moved {oldfile} to {newfile}');
226
+            $this->setIcon($event, 'change');
227
+        } else if ($event->getSubject() === 'moved_by') {
228
+            $subject = $this->l->t('{user} moved {oldfile} to {newfile}');
229
+            $this->setIcon($event, 'change');
230
+        } else {
231
+            throw new \InvalidArgumentException();
232
+        }
233
+
234
+        if ($this->fileIsEncrypted) {
235
+            $event->setSubject($event->getSubject() . '_enc', $event->getSubjectParameters());
236
+        }
237
+
238
+        if (!isset($parsedParameters['user'])) {
239
+            // External user via public link share
240
+            $subject = str_replace('{user}', $this->activityLang->t('"remote user"'), $subject);
241
+        }
242
+
243
+        $this->setSubjects($event, $subject, $parsedParameters);
244
+
245
+        $event = $this->eventMerger->mergeEvents('file', $event, $previousEvent);
246
+
247
+        if ($event->getChildEvent() === null) {
248
+            // Couldn't group by file, maybe we can group by user
249
+            $event = $this->eventMerger->mergeEvents('user', $event, $previousEvent);
250
+        }
251
+
252
+        return $event;
253
+    }
254
+
255
+    protected function setSubjects(IEvent $event, $subject, array $parameters) {
256
+        $placeholders = $replacements = [];
257
+        foreach ($parameters as $placeholder => $parameter) {
258
+            $placeholders[] = '{' . $placeholder . '}';
259
+            if ($parameter['type'] === 'file') {
260
+                $replacements[] = $parameter['path'];
261
+            } else {
262
+                $replacements[] = $parameter['name'];
263
+            }
264
+        }
265
+
266
+        $event->setParsedSubject(str_replace($placeholders, $replacements, $subject))
267
+            ->setRichSubject($subject, $parameters);
268
+    }
269
+
270
+    /**
271
+     * @param IEvent $event
272
+     * @return array
273
+     * @throws \InvalidArgumentException
274
+     */
275
+    protected function getParameters(IEvent $event) {
276
+        $parameters = $event->getSubjectParameters();
277
+        switch ($event->getSubject()) {
278
+            case 'created_self':
279
+            case 'created_public':
280
+            case 'changed_self':
281
+            case 'deleted_self':
282
+            case 'restored_self':
283
+                return [
284
+                    'file' => $this->getFile($parameters[0], $event),
285
+                ];
286
+            case 'created_by':
287
+            case 'changed_by':
288
+            case 'deleted_by':
289
+            case 'restored_by':
290
+                if ($parameters[1] === '') {
291
+                    // External user via public link share
292
+                    return [
293
+                        'file' => $this->getFile($parameters[0], $event),
294
+                    ];
295
+                }
296
+                return [
297
+                    'file' => $this->getFile($parameters[0], $event),
298
+                    'user' => $this->getUser($parameters[1]),
299
+                ];
300
+            case 'renamed_self':
301
+            case 'moved_self':
302
+                return [
303
+                    'newfile' => $this->getFile($parameters[0]),
304
+                    'oldfile' => $this->getFile($parameters[1]),
305
+                ];
306
+            case 'renamed_by':
307
+            case 'moved_by':
308
+                if ($parameters[1] === '') {
309
+                    // External user via public link share
310
+                    return [
311
+                        'newfile' => $this->getFile($parameters[0]),
312
+                        'oldfile' => $this->getFile($parameters[2]),
313
+                    ];
314
+                }
315
+                return [
316
+                    'newfile' => $this->getFile($parameters[0]),
317
+                    'user' => $this->getUser($parameters[1]),
318
+                    'oldfile' => $this->getFile($parameters[2]),
319
+                ];
320
+        }
321
+        return [];
322
+    }
323
+
324
+    /**
325
+     * @param array|string $parameter
326
+     * @param IEvent|null $event
327
+     * @return array
328
+     * @throws \InvalidArgumentException
329
+     */
330
+    protected function getFile($parameter, IEvent $event = null) {
331
+        if (is_array($parameter)) {
332
+            $path = reset($parameter);
333
+            $id = (string) key($parameter);
334
+        } else if ($event !== null) {
335
+            // Legacy from before ownCloud 8.2
336
+            $path = $parameter;
337
+            $id = $event->getObjectId();
338
+        } else {
339
+            throw new \InvalidArgumentException('Could not generate file parameter');
340
+        }
341
+
342
+        $encryptionContainer = $this->getEndToEndEncryptionContainer($id, basename($path));
343
+        if ($encryptionContainer instanceof Folder) {
344
+            $this->fileIsEncrypted = true;
345
+            return [
346
+                'type' => 'file',
347
+                'id' => $encryptionContainer->getId(),
348
+                'name' => $encryptionContainer->getName(),
349
+                'path' => trim($encryptionContainer->getPath(), '/'), // FIXME remove /user/files/...
350
+                'link' => $this->url->linkToRouteAbsolute('files.viewcontroller.showFile', ['fileid' => $encryptionContainer->getId()]),
351
+            ];
352
+        }
353
+
354
+        return [
355
+            'type' => 'file',
356
+            'id' => $id,
357
+            'name' => basename($path),
358
+            'path' => trim($path, '/'),
359
+            'link' => $this->url->linkToRouteAbsolute('files.viewcontroller.showFile', ['fileid' => $id]),
360
+        ];
361
+    }
362
+
363
+    protected $fileEncrypted = [];
364
+
365
+    /**
366
+     * Check if a file is end2end encrypted
367
+     * @param int $fileId
368
+     * @param string $fileName
369
+     * @return bool
370
+     */
371
+    protected function getEndToEndEncryptionContainer($fileId, $fileName) {
372
+        if (isset($this->fileEncrypted[$fileId])) {
373
+            return $this->fileEncrypted[$fileId];
374
+        }
375
+
376
+        if (!preg_match('/^[0-9a-fA-F]{32}$/', $fileName)) {
377
+            $this->fileEncrypted[$fileId] = false;
378
+            return $this->fileEncrypted[$fileId];
379
+        }
380
+
381
+        $userFolder = $this->rootFolder->getUserFolder($this->activityManager->getCurrentUserId());
382
+        $files = $userFolder->getById($fileId);
383
+        if (empty($files)) {
384
+            return null;
385
+        }
386
+
387
+        $file = array_shift($files);
388
+        if ($file instanceof Folder && $file->isEncrypted()) {
389
+            // If the folder is encrypted, it is the Container,
390
+            // but can be the name is just fine.
391
+            $this->fileEncrypted[$fileId] = true;
392
+            return null;
393
+        }
394
+
395
+        $this->fileEncrypted[$fileId] = $this->getParentEndToEndEncryptionContainer($userFolder, $file);
396
+        return $this->fileEncrypted[$fileId];
397
+    }
398
+
399
+    /**
400
+     * Check all parents until the user's root folder if one is encrypted
401
+     *
402
+     * @param Folder $userFolder
403
+     * @param Node $file
404
+     * @return Node|null
405
+     */
406
+    protected function getParentEndToEndEncryptionContainer(Folder $userFolder, Node $file) {
407
+        try {
408
+            $parent = $file->getParent();
409
+
410
+            if ($userFolder->getId() === $parent->getId()) {
411
+                return null;
412
+            }
413
+        } catch (\Exception $e) {
414
+            return null;
415
+        }
416
+
417
+        if ($parent->isEncrypted()) {
418
+            return $parent;
419
+        }
420
+
421
+        return $this->getParentEndToEndEncryptionContainer($userFolder, $file);
422
+    }
423
+
424
+    /**
425
+     * @param string $uid
426
+     * @return array
427
+     */
428
+    protected function getUser($uid) {
429
+        if (!isset($this->displayNames[$uid])) {
430
+            $this->displayNames[$uid] = $this->getDisplayName($uid);
431
+        }
432
+
433
+        return [
434
+            'type' => 'user',
435
+            'id' => $uid,
436
+            'name' => $this->displayNames[$uid],
437
+        ];
438
+    }
439
+
440
+    /**
441
+     * @param string $uid
442
+     * @return string
443
+     */
444
+    protected function getDisplayName($uid) {
445
+        $user = $this->userManager->get($uid);
446
+        if ($user instanceof IUser) {
447
+            return $user->getDisplayName();
448
+        } else {
449
+            return $uid;
450
+        }
451
+    }
452 452
 }
Please login to merge, or discard this patch.
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -114,9 +114,9 @@  discard block
 block discarded – undo
114 114
 
115 115
 	protected function setIcon(IEvent $event, $icon) {
116 116
 		if ($this->activityManager->getRequirePNG()) {
117
-			$event->setIcon($this->url->getAbsoluteURL($this->url->imagePath('files', $icon . '.png')));
117
+			$event->setIcon($this->url->getAbsoluteURL($this->url->imagePath('files', $icon.'.png')));
118 118
 		} else {
119
-			$event->setIcon($this->url->getAbsoluteURL($this->url->imagePath('files', $icon . '.svg')));
119
+			$event->setIcon($this->url->getAbsoluteURL($this->url->imagePath('files', $icon.'.svg')));
120 120
 		}
121 121
 	}
122 122
 
@@ -232,7 +232,7 @@  discard block
 block discarded – undo
232 232
 		}
233 233
 
234 234
 		if ($this->fileIsEncrypted) {
235
-			$event->setSubject($event->getSubject() . '_enc', $event->getSubjectParameters());
235
+			$event->setSubject($event->getSubject().'_enc', $event->getSubjectParameters());
236 236
 		}
237 237
 
238 238
 		if (!isset($parsedParameters['user'])) {
@@ -255,7 +255,7 @@  discard block
 block discarded – undo
255 255
 	protected function setSubjects(IEvent $event, $subject, array $parameters) {
256 256
 		$placeholders = $replacements = [];
257 257
 		foreach ($parameters as $placeholder => $parameter) {
258
-			$placeholders[] = '{' . $placeholder . '}';
258
+			$placeholders[] = '{'.$placeholder.'}';
259 259
 			if ($parameter['type'] === 'file') {
260 260
 				$replacements[] = $parameter['path'];
261 261
 			} else {
Please login to merge, or discard this patch.