Passed
Push — master ( 1dce30...f6efd5 )
by Joas
15:03 queued 13s
created
lib/private/Files/Node/NonExistingFolder.php 1 patch
Indentation   +143 added lines, -143 removed lines patch added patch discarded remove patch
@@ -27,147 +27,147 @@
 block discarded – undo
27 27
 use OCP\Files\NotFoundException;
28 28
 
29 29
 class NonExistingFolder extends Folder {
30
-	/**
31
-	 * @param string $newPath
32
-	 * @throws \OCP\Files\NotFoundException
33
-	 */
34
-	public function rename($newPath) {
35
-		throw new NotFoundException();
36
-	}
37
-
38
-	public function delete() {
39
-		throw new NotFoundException();
40
-	}
41
-
42
-	public function copy($newPath) {
43
-		throw new NotFoundException();
44
-	}
45
-
46
-	public function touch($mtime = null) {
47
-		throw new NotFoundException();
48
-	}
49
-
50
-	public function getId() {
51
-		if ($this->fileInfo) {
52
-			return parent::getId();
53
-		} else {
54
-			throw new NotFoundException();
55
-		}
56
-	}
57
-
58
-	public function stat() {
59
-		throw new NotFoundException();
60
-	}
61
-
62
-	public function getMTime() {
63
-		if ($this->fileInfo) {
64
-			return parent::getMTime();
65
-		} else {
66
-			throw new NotFoundException();
67
-		}
68
-	}
69
-
70
-	public function getSize($includeMounts = true) {
71
-		if ($this->fileInfo) {
72
-			return parent::getSize($includeMounts);
73
-		} else {
74
-			throw new NotFoundException();
75
-		}
76
-	}
77
-
78
-	public function getEtag() {
79
-		if ($this->fileInfo) {
80
-			return parent::getEtag();
81
-		} else {
82
-			throw new NotFoundException();
83
-		}
84
-	}
85
-
86
-	public function getPermissions() {
87
-		if ($this->fileInfo) {
88
-			return parent::getPermissions();
89
-		} else {
90
-			throw new NotFoundException();
91
-		}
92
-	}
93
-
94
-	public function isReadable() {
95
-		if ($this->fileInfo) {
96
-			return parent::isReadable();
97
-		} else {
98
-			throw new NotFoundException();
99
-		}
100
-	}
101
-
102
-	public function isUpdateable() {
103
-		if ($this->fileInfo) {
104
-			return parent::isUpdateable();
105
-		} else {
106
-			throw new NotFoundException();
107
-		}
108
-	}
109
-
110
-	public function isDeletable() {
111
-		if ($this->fileInfo) {
112
-			return parent::isDeletable();
113
-		} else {
114
-			throw new NotFoundException();
115
-		}
116
-	}
117
-
118
-	public function isShareable() {
119
-		if ($this->fileInfo) {
120
-			return parent::isShareable();
121
-		} else {
122
-			throw new NotFoundException();
123
-		}
124
-	}
125
-
126
-	public function get($path) {
127
-		throw new NotFoundException();
128
-	}
129
-
130
-	public function getDirectoryListing() {
131
-		throw new NotFoundException();
132
-	}
133
-
134
-	public function nodeExists($path) {
135
-		return false;
136
-	}
137
-
138
-	public function newFolder($path) {
139
-		throw new NotFoundException();
140
-	}
141
-
142
-	public function newFile($path, $content = null) {
143
-		throw new NotFoundException();
144
-	}
145
-
146
-	public function search($pattern) {
147
-		throw new NotFoundException();
148
-	}
149
-
150
-	public function searchByMime($mime) {
151
-		throw new NotFoundException();
152
-	}
153
-
154
-	public function searchByTag($tag, $userId) {
155
-		throw new NotFoundException();
156
-	}
157
-
158
-	public function getById($id) {
159
-		throw new NotFoundException();
160
-	}
161
-
162
-	public function getFreeSpace() {
163
-		throw new NotFoundException();
164
-	}
165
-
166
-	public function isCreatable() {
167
-		if ($this->fileInfo) {
168
-			return parent::isCreatable();
169
-		} else {
170
-			throw new NotFoundException();
171
-		}
172
-	}
30
+    /**
31
+     * @param string $newPath
32
+     * @throws \OCP\Files\NotFoundException
33
+     */
34
+    public function rename($newPath) {
35
+        throw new NotFoundException();
36
+    }
37
+
38
+    public function delete() {
39
+        throw new NotFoundException();
40
+    }
41
+
42
+    public function copy($newPath) {
43
+        throw new NotFoundException();
44
+    }
45
+
46
+    public function touch($mtime = null) {
47
+        throw new NotFoundException();
48
+    }
49
+
50
+    public function getId() {
51
+        if ($this->fileInfo) {
52
+            return parent::getId();
53
+        } else {
54
+            throw new NotFoundException();
55
+        }
56
+    }
57
+
58
+    public function stat() {
59
+        throw new NotFoundException();
60
+    }
61
+
62
+    public function getMTime() {
63
+        if ($this->fileInfo) {
64
+            return parent::getMTime();
65
+        } else {
66
+            throw new NotFoundException();
67
+        }
68
+    }
69
+
70
+    public function getSize($includeMounts = true) {
71
+        if ($this->fileInfo) {
72
+            return parent::getSize($includeMounts);
73
+        } else {
74
+            throw new NotFoundException();
75
+        }
76
+    }
77
+
78
+    public function getEtag() {
79
+        if ($this->fileInfo) {
80
+            return parent::getEtag();
81
+        } else {
82
+            throw new NotFoundException();
83
+        }
84
+    }
85
+
86
+    public function getPermissions() {
87
+        if ($this->fileInfo) {
88
+            return parent::getPermissions();
89
+        } else {
90
+            throw new NotFoundException();
91
+        }
92
+    }
93
+
94
+    public function isReadable() {
95
+        if ($this->fileInfo) {
96
+            return parent::isReadable();
97
+        } else {
98
+            throw new NotFoundException();
99
+        }
100
+    }
101
+
102
+    public function isUpdateable() {
103
+        if ($this->fileInfo) {
104
+            return parent::isUpdateable();
105
+        } else {
106
+            throw new NotFoundException();
107
+        }
108
+    }
109
+
110
+    public function isDeletable() {
111
+        if ($this->fileInfo) {
112
+            return parent::isDeletable();
113
+        } else {
114
+            throw new NotFoundException();
115
+        }
116
+    }
117
+
118
+    public function isShareable() {
119
+        if ($this->fileInfo) {
120
+            return parent::isShareable();
121
+        } else {
122
+            throw new NotFoundException();
123
+        }
124
+    }
125
+
126
+    public function get($path) {
127
+        throw new NotFoundException();
128
+    }
129
+
130
+    public function getDirectoryListing() {
131
+        throw new NotFoundException();
132
+    }
133
+
134
+    public function nodeExists($path) {
135
+        return false;
136
+    }
137
+
138
+    public function newFolder($path) {
139
+        throw new NotFoundException();
140
+    }
141
+
142
+    public function newFile($path, $content = null) {
143
+        throw new NotFoundException();
144
+    }
145
+
146
+    public function search($pattern) {
147
+        throw new NotFoundException();
148
+    }
149
+
150
+    public function searchByMime($mime) {
151
+        throw new NotFoundException();
152
+    }
153
+
154
+    public function searchByTag($tag, $userId) {
155
+        throw new NotFoundException();
156
+    }
157
+
158
+    public function getById($id) {
159
+        throw new NotFoundException();
160
+    }
161
+
162
+    public function getFreeSpace() {
163
+        throw new NotFoundException();
164
+    }
165
+
166
+    public function isCreatable() {
167
+        if ($this->fileInfo) {
168
+            return parent::isCreatable();
169
+        } else {
170
+            throw new NotFoundException();
171
+        }
172
+    }
173 173
 }
Please login to merge, or discard this patch.
lib/public/Share/Events/VerifyMountPointEvent.php 1 patch
Indentation   +41 added lines, -41 removed lines patch added patch discarded remove patch
@@ -33,51 +33,51 @@
 block discarded – undo
33 33
  */
34 34
 class VerifyMountPointEvent extends Event {
35 35
 
36
-	/** @var IShare */
37
-	private $share;
38
-	/** @var View */
39
-	private $view;
40
-	/** @var string */
41
-	private $parent;
36
+    /** @var IShare */
37
+    private $share;
38
+    /** @var View */
39
+    private $view;
40
+    /** @var string */
41
+    private $parent;
42 42
 
43
-	/**
44
-	 * @since 19.0.0
45
-	 */
46
-	public function __construct(IShare $share,
47
-								View $view,
48
-								string $parent) {
49
-		parent::__construct();
43
+    /**
44
+     * @since 19.0.0
45
+     */
46
+    public function __construct(IShare $share,
47
+                                View $view,
48
+                                string $parent) {
49
+        parent::__construct();
50 50
 
51
-		$this->share = $share;
52
-		$this->view = $view;
53
-		$this->parent = $parent;
54
-	}
51
+        $this->share = $share;
52
+        $this->view = $view;
53
+        $this->parent = $parent;
54
+    }
55 55
 
56
-	/**
57
-	 * @since 19.0.0
58
-	 */
59
-	public function getShare(): IShare {
60
-		return $this->share;
61
-	}
56
+    /**
57
+     * @since 19.0.0
58
+     */
59
+    public function getShare(): IShare {
60
+        return $this->share;
61
+    }
62 62
 
63
-	/**
64
-	 * @since 19.0.0
65
-	 */
66
-	public function getView(): View {
67
-		return $this->view;
68
-	}
63
+    /**
64
+     * @since 19.0.0
65
+     */
66
+    public function getView(): View {
67
+        return $this->view;
68
+    }
69 69
 
70
-	/**
71
-	 * @since 19.0.0
72
-	 */
73
-	public function getParent(): string {
74
-		return $this->parent;
75
-	}
70
+    /**
71
+     * @since 19.0.0
72
+     */
73
+    public function getParent(): string {
74
+        return $this->parent;
75
+    }
76 76
 
77
-	/**
78
-	 * @since 19.0.0
79
-	 */
80
-	public function setParent(string $parent): void {
81
-		$this->parent = $parent;
82
-	}
77
+    /**
78
+     * @since 19.0.0
79
+     */
80
+    public function setParent(string $parent): void {
81
+        $this->parent = $parent;
82
+    }
83 83
 }
Please login to merge, or discard this patch.
apps/files_versions/lib/Versions/IVersionBackend.php 1 patch
Indentation   +55 added lines, -55 removed lines patch added patch discarded remove patch
@@ -37,64 +37,64 @@
 block discarded – undo
37 37
  * @since 15.0.0
38 38
  */
39 39
 interface IVersionBackend {
40
-	/**
41
-	 * Whether or not this version backend should be used for a storage
42
-	 *
43
-	 * If false is returned then the next applicable backend will be used
44
-	 *
45
-	 * @param IStorage $storage
46
-	 * @return bool
47
-	 * @since 17.0.0
48
-	 */
49
-	public function useBackendForStorage(IStorage $storage): bool;
40
+    /**
41
+     * Whether or not this version backend should be used for a storage
42
+     *
43
+     * If false is returned then the next applicable backend will be used
44
+     *
45
+     * @param IStorage $storage
46
+     * @return bool
47
+     * @since 17.0.0
48
+     */
49
+    public function useBackendForStorage(IStorage $storage): bool;
50 50
 
51
-	/**
52
-	 * Get all versions for a file
53
-	 *
54
-	 * @param IUser $user
55
-	 * @param FileInfo $file
56
-	 * @return IVersion[]
57
-	 * @since 15.0.0
58
-	 */
59
-	public function getVersionsForFile(IUser $user, FileInfo $file): array;
51
+    /**
52
+     * Get all versions for a file
53
+     *
54
+     * @param IUser $user
55
+     * @param FileInfo $file
56
+     * @return IVersion[]
57
+     * @since 15.0.0
58
+     */
59
+    public function getVersionsForFile(IUser $user, FileInfo $file): array;
60 60
 
61
-	/**
62
-	 * Create a new version for a file
63
-	 *
64
-	 * @param IUser $user
65
-	 * @param FileInfo $file
66
-	 * @since 15.0.0
67
-	 */
68
-	public function createVersion(IUser $user, FileInfo $file);
61
+    /**
62
+     * Create a new version for a file
63
+     *
64
+     * @param IUser $user
65
+     * @param FileInfo $file
66
+     * @since 15.0.0
67
+     */
68
+    public function createVersion(IUser $user, FileInfo $file);
69 69
 
70
-	/**
71
-	 * Restore this version
72
-	 *
73
-	 * @param IVersion $version
74
-	 * @since 15.0.0
75
-	 */
76
-	public function rollback(IVersion $version);
70
+    /**
71
+     * Restore this version
72
+     *
73
+     * @param IVersion $version
74
+     * @since 15.0.0
75
+     */
76
+    public function rollback(IVersion $version);
77 77
 
78
-	/**
79
-	 * Open the file for reading
80
-	 *
81
-	 * @param IVersion $version
82
-	 * @return resource
83
-	 * @throws NotFoundException
84
-	 * @since 15.0.0
85
-	 */
86
-	public function read(IVersion $version);
78
+    /**
79
+     * Open the file for reading
80
+     *
81
+     * @param IVersion $version
82
+     * @return resource
83
+     * @throws NotFoundException
84
+     * @since 15.0.0
85
+     */
86
+    public function read(IVersion $version);
87 87
 
88
-	/**
89
-	 * Get the preview for a specific version of a file
90
-	 *
91
-	 * @param IUser $user
92
-	 * @param FileInfo $sourceFile
93
-	 * @param int|string $revision
94
-	 *
95
-	 * @return File
96
-	 *
97
-	 * @since 15.0.0
98
-	 */
99
-	public function getVersionFile(IUser $user, FileInfo $sourceFile, $revision): File;
88
+    /**
89
+     * Get the preview for a specific version of a file
90
+     *
91
+     * @param IUser $user
92
+     * @param FileInfo $sourceFile
93
+     * @param int|string $revision
94
+     *
95
+     * @return File
96
+     *
97
+     * @since 15.0.0
98
+     */
99
+    public function getVersionFile(IUser $user, FileInfo $sourceFile, $revision): File;
100 100
 }
Please login to merge, or discard this patch.
lib/private/Authentication/TwoFactorAuth/EnforcementState.php 1 patch
Indentation   +45 added lines, -45 removed lines patch added patch discarded remove patch
@@ -30,57 +30,57 @@
 block discarded – undo
30 30
 
31 31
 class EnforcementState implements JsonSerializable {
32 32
 
33
-	/** @var bool */
34
-	private $enforced;
33
+    /** @var bool */
34
+    private $enforced;
35 35
 
36
-	/** @var array */
37
-	private $enforcedGroups;
36
+    /** @var array */
37
+    private $enforcedGroups;
38 38
 
39
-	/** @var array */
40
-	private $excludedGroups;
39
+    /** @var array */
40
+    private $excludedGroups;
41 41
 
42
-	/**
43
-	 * EnforcementState constructor.
44
-	 *
45
-	 * @param bool $enforced
46
-	 * @param string[] $enforcedGroups
47
-	 * @param string[] $excludedGroups
48
-	 */
49
-	public function __construct(bool $enforced,
50
-								array $enforcedGroups = [],
51
-								array $excludedGroups = []) {
52
-		$this->enforced = $enforced;
53
-		$this->enforcedGroups = $enforcedGroups;
54
-		$this->excludedGroups = $excludedGroups;
55
-	}
42
+    /**
43
+     * EnforcementState constructor.
44
+     *
45
+     * @param bool $enforced
46
+     * @param string[] $enforcedGroups
47
+     * @param string[] $excludedGroups
48
+     */
49
+    public function __construct(bool $enforced,
50
+                                array $enforcedGroups = [],
51
+                                array $excludedGroups = []) {
52
+        $this->enforced = $enforced;
53
+        $this->enforcedGroups = $enforcedGroups;
54
+        $this->excludedGroups = $excludedGroups;
55
+    }
56 56
 
57
-	/**
58
-	 * @return bool
59
-	 */
60
-	public function isEnforced(): bool {
61
-		return $this->enforced;
62
-	}
57
+    /**
58
+     * @return bool
59
+     */
60
+    public function isEnforced(): bool {
61
+        return $this->enforced;
62
+    }
63 63
 
64
-	/**
65
-	 * @return string[]
66
-	 */
67
-	public function getEnforcedGroups(): array {
68
-		return $this->enforcedGroups;
69
-	}
64
+    /**
65
+     * @return string[]
66
+     */
67
+    public function getEnforcedGroups(): array {
68
+        return $this->enforcedGroups;
69
+    }
70 70
 
71
-	/**
72
-	 * @return string[]
73
-	 */
74
-	public function getExcludedGroups(): array {
75
-		return $this->excludedGroups;
76
-	}
71
+    /**
72
+     * @return string[]
73
+     */
74
+    public function getExcludedGroups(): array {
75
+        return $this->excludedGroups;
76
+    }
77 77
 
78
-	public function jsonSerialize(): array {
79
-		return [
80
-			'enforced' => $this->enforced,
81
-			'enforcedGroups' => $this->enforcedGroups,
82
-			'excludedGroups' => $this->excludedGroups,
83
-		];
84
-	}
78
+    public function jsonSerialize(): array {
79
+        return [
80
+            'enforced' => $this->enforced,
81
+            'enforcedGroups' => $this->enforcedGroups,
82
+            'excludedGroups' => $this->excludedGroups,
83
+        ];
84
+    }
85 85
 
86 86
 }
Please login to merge, or discard this patch.
apps/files/lib/Activity/Provider.php 2 patches
Spacing   +5 added lines, -5 removed lines patch added patch discarded remove patch
@@ -124,9 +124,9 @@  discard block
 block discarded – undo
124 124
 
125 125
 	protected function setIcon(IEvent $event, string $icon, string $app = 'files') {
126 126
 		if ($this->activityManager->getRequirePNG()) {
127
-			$event->setIcon($this->url->getAbsoluteURL($this->url->imagePath($app, $icon . '.png')));
127
+			$event->setIcon($this->url->getAbsoluteURL($this->url->imagePath($app, $icon.'.png')));
128 128
 		} else {
129
-			$event->setIcon($this->url->getAbsoluteURL($this->url->imagePath($app, $icon . '.svg')));
129
+			$event->setIcon($this->url->getAbsoluteURL($this->url->imagePath($app, $icon.'.svg')));
130 130
 		}
131 131
 	}
132 132
 
@@ -245,7 +245,7 @@  discard block
 block discarded – undo
245 245
 		}
246 246
 
247 247
 		if ($this->fileIsEncrypted) {
248
-			$event->setSubject($event->getSubject() . '_enc', $event->getSubjectParameters());
248
+			$event->setSubject($event->getSubject().'_enc', $event->getSubjectParameters());
249 249
 		}
250 250
 
251 251
 		if (!isset($parsedParameters['user'])) {
@@ -272,7 +272,7 @@  discard block
 block discarded – undo
272 272
 	protected function setSubjects(IEvent $event, $subject, array $parameters) {
273 273
 		$placeholders = $replacements = [];
274 274
 		foreach ($parameters as $placeholder => $parameter) {
275
-			$placeholders[] = '{' . $placeholder . '}';
275
+			$placeholders[] = '{'.$placeholder.'}';
276 276
 			if ($parameter['type'] === 'file') {
277 277
 				$replacements[] = $parameter['path'];
278 278
 			} else {
@@ -538,7 +538,7 @@  discard block
 block discarded – undo
538 538
 				$lowerSearch = strtolower($search);
539 539
 				foreach ($cloudIds as $cloudId) {
540 540
 					if (strtolower($cloudId) === $lowerSearch) {
541
-						$this->displayNames[$search] = $contact['FN'] . " ($cloudId)";
541
+						$this->displayNames[$search] = $contact['FN']." ($cloudId)";
542 542
 						return $this->displayNames[$search];
543 543
 					}
544 544
 				}
Please login to merge, or discard this patch.
Indentation   +545 added lines, -545 removed lines patch added patch discarded remove patch
@@ -44,549 +44,549 @@
 block discarded – undo
44 44
 
45 45
 class Provider implements IProvider {
46 46
 
47
-	/** @var IFactory */
48
-	protected $languageFactory;
49
-
50
-	/** @var IL10N */
51
-	protected $l;
52
-	/** @var IL10N */
53
-	protected $activityLang;
54
-
55
-	/** @var IURLGenerator */
56
-	protected $url;
57
-
58
-	/** @var IManager */
59
-	protected $activityManager;
60
-
61
-	/** @var IUserManager */
62
-	protected $userManager;
63
-
64
-	/** @var IRootFolder */
65
-	protected $rootFolder;
66
-
67
-	/** @var IEventMerger */
68
-	protected $eventMerger;
69
-
70
-	/** @var ICloudIdManager */
71
-	protected $cloudIdManager;
72
-
73
-	/** @var IContactsManager */
74
-	protected $contactsManager;
75
-
76
-	/** @var string[] cached displayNames - key is the cloud id and value the displayname */
77
-	protected $displayNames = [];
78
-
79
-	protected $fileIsEncrypted = false;
80
-
81
-	public function __construct(IFactory $languageFactory,
82
-								IURLGenerator $url,
83
-								IManager $activityManager,
84
-								IUserManager $userManager,
85
-								IRootFolder $rootFolder,
86
-								ICloudIdManager $cloudIdManager,
87
-								IContactsManager $contactsManager,
88
-								IEventMerger $eventMerger) {
89
-		$this->languageFactory = $languageFactory;
90
-		$this->url = $url;
91
-		$this->activityManager = $activityManager;
92
-		$this->userManager = $userManager;
93
-		$this->rootFolder = $rootFolder;
94
-		$this->cloudIdManager = $cloudIdManager;
95
-		$this->contactsManager = $contactsManager;
96
-		$this->eventMerger = $eventMerger;
97
-	}
98
-
99
-	/**
100
-	 * @param string $language
101
-	 * @param IEvent $event
102
-	 * @param IEvent|null $previousEvent
103
-	 * @return IEvent
104
-	 * @throws \InvalidArgumentException
105
-	 * @since 11.0.0
106
-	 */
107
-	public function parse($language, IEvent $event, IEvent $previousEvent = null) {
108
-		if ($event->getApp() !== 'files') {
109
-			throw new \InvalidArgumentException();
110
-		}
111
-
112
-		$this->l = $this->languageFactory->get('files', $language);
113
-		$this->activityLang = $this->languageFactory->get('activity', $language);
114
-
115
-		if ($this->activityManager->isFormattingFilteredObject()) {
116
-			try {
117
-				return $this->parseShortVersion($event, $previousEvent);
118
-			} catch (\InvalidArgumentException $e) {
119
-				// Ignore and simply use the long version...
120
-			}
121
-		}
122
-
123
-		return $this->parseLongVersion($event, $previousEvent);
124
-	}
125
-
126
-	protected function setIcon(IEvent $event, string $icon, string $app = 'files') {
127
-		if ($this->activityManager->getRequirePNG()) {
128
-			$event->setIcon($this->url->getAbsoluteURL($this->url->imagePath($app, $icon . '.png')));
129
-		} else {
130
-			$event->setIcon($this->url->getAbsoluteURL($this->url->imagePath($app, $icon . '.svg')));
131
-		}
132
-	}
133
-
134
-	/**
135
-	 * @param IEvent $event
136
-	 * @param IEvent|null $previousEvent
137
-	 * @return IEvent
138
-	 * @throws \InvalidArgumentException
139
-	 * @since 11.0.0
140
-	 */
141
-	public function parseShortVersion(IEvent $event, IEvent $previousEvent = null) {
142
-		$parsedParameters = $this->getParameters($event);
143
-
144
-		if ($event->getSubject() === 'created_by') {
145
-			$subject = $this->l->t('Created by {user}');
146
-			$this->setIcon($event, 'add-color');
147
-		} elseif ($event->getSubject() === 'changed_by') {
148
-			$subject = $this->l->t('Changed by {user}');
149
-			$this->setIcon($event, 'change');
150
-		} elseif ($event->getSubject() === 'deleted_by') {
151
-			$subject = $this->l->t('Deleted by {user}');
152
-			$this->setIcon($event, 'delete-color');
153
-		} elseif ($event->getSubject() === 'restored_by') {
154
-			$subject = $this->l->t('Restored by {user}');
155
-			$this->setIcon($event, 'actions/history', 'core');
156
-		} elseif ($event->getSubject() === 'renamed_by') {
157
-			$subject = $this->l->t('Renamed by {user}');
158
-			$this->setIcon($event, 'change');
159
-		} elseif ($event->getSubject() === 'moved_by') {
160
-			$subject = $this->l->t('Moved by {user}');
161
-			$this->setIcon($event, 'change');
162
-		} else {
163
-			throw new \InvalidArgumentException();
164
-		}
165
-
166
-		if (!isset($parsedParameters['user'])) {
167
-			// External user via public link share
168
-			$subject = str_replace('{user}', $this->activityLang->t('"remote user"'), $subject);
169
-		}
170
-
171
-		$this->setSubjects($event, $subject, $parsedParameters);
172
-
173
-		return $this->eventMerger->mergeEvents('user', $event, $previousEvent);
174
-	}
175
-
176
-	/**
177
-	 * @param IEvent $event
178
-	 * @param IEvent|null $previousEvent
179
-	 * @return IEvent
180
-	 * @throws \InvalidArgumentException
181
-	 * @since 11.0.0
182
-	 */
183
-	public function parseLongVersion(IEvent $event, IEvent $previousEvent = null) {
184
-		$this->fileIsEncrypted = false;
185
-		$parsedParameters = $this->getParameters($event);
186
-
187
-		if ($event->getSubject() === 'created_self') {
188
-			$subject = $this->l->t('You created {file}');
189
-			if ($this->fileIsEncrypted) {
190
-				$subject = $this->l->t('You created an encrypted file in {file}');
191
-			}
192
-			$this->setIcon($event, 'add-color');
193
-		} elseif ($event->getSubject() === 'created_by') {
194
-			$subject = $this->l->t('{user} created {file}');
195
-			if ($this->fileIsEncrypted) {
196
-				$subject = $this->l->t('{user} created an encrypted file in {file}');
197
-			}
198
-			$this->setIcon($event, 'add-color');
199
-		} elseif ($event->getSubject() === 'created_public') {
200
-			$subject = $this->l->t('{file} was created in a public folder');
201
-			$this->setIcon($event, 'add-color');
202
-		} elseif ($event->getSubject() === 'changed_self') {
203
-			$subject = $this->l->t('You changed {file}');
204
-			if ($this->fileIsEncrypted) {
205
-				$subject = $this->l->t('You changed an encrypted file in {file}');
206
-			}
207
-			$this->setIcon($event, 'change');
208
-		} elseif ($event->getSubject() === 'changed_by') {
209
-			$subject = $this->l->t('{user} changed {file}');
210
-			if ($this->fileIsEncrypted) {
211
-				$subject = $this->l->t('{user} changed an encrypted file in {file}');
212
-			}
213
-			$this->setIcon($event, 'change');
214
-		} elseif ($event->getSubject() === 'deleted_self') {
215
-			$subject = $this->l->t('You deleted {file}');
216
-			if ($this->fileIsEncrypted) {
217
-				$subject = $this->l->t('You deleted an encrypted file in {file}');
218
-			}
219
-			$this->setIcon($event, 'delete-color');
220
-		} elseif ($event->getSubject() === 'deleted_by') {
221
-			$subject = $this->l->t('{user} deleted {file}');
222
-			if ($this->fileIsEncrypted) {
223
-				$subject = $this->l->t('{user} deleted an encrypted file in {file}');
224
-			}
225
-			$this->setIcon($event, 'delete-color');
226
-		} elseif ($event->getSubject() === 'restored_self') {
227
-			$subject = $this->l->t('You restored {file}');
228
-			$this->setIcon($event, 'actions/history', 'core');
229
-		} elseif ($event->getSubject() === 'restored_by') {
230
-			$subject = $this->l->t('{user} restored {file}');
231
-			$this->setIcon($event, 'actions/history', 'core');
232
-		} elseif ($event->getSubject() === 'renamed_self') {
233
-			$oldFileName = $parsedParameters['oldfile']['name'];
234
-			$newFileName = $parsedParameters['newfile']['name'];
235
-
236
-			if ($this->isHiddenFile($oldFileName)) {
237
-				if ($this->isHiddenFile($newFileName)) {
238
-					$subject = $this->l->t('You renamed {oldfile} (hidden) to {newfile} (hidden)');
239
-				} else {
240
-					$subject = $this->l->t('You renamed {oldfile} (hidden) to {newfile}');
241
-				}
242
-			} else {
243
-				if ($this->isHiddenFile($newFileName)) {
244
-					$subject = $this->l->t('You renamed {oldfile} to {newfile} (hidden)');
245
-				} else {
246
-					$subject = $this->l->t('You renamed {oldfile} to {newfile}');
247
-				}
248
-			}
249
-
250
-			$this->setIcon($event, 'change');
251
-		} elseif ($event->getSubject() === 'renamed_by') {
252
-			$oldFileName = $parsedParameters['oldfile']['name'];
253
-			$newFileName = $parsedParameters['newfile']['name'];
254
-
255
-			if ($this->isHiddenFile($oldFileName)) {
256
-				if ($this->isHiddenFile($newFileName)) {
257
-					$subject = $this->l->t('{user} renamed {oldfile} (hidden) to {newfile} (hidden)');
258
-				} else {
259
-					$subject = $this->l->t('{user} renamed {oldfile} (hidden) to {newfile}');
260
-				}
261
-			} else {
262
-				if ($this->isHiddenFile($newFileName)) {
263
-					$subject = $this->l->t('{user} renamed {oldfile} to {newfile} (hidden)');
264
-				} else {
265
-					$subject = $this->l->t('{user} renamed {oldfile} to {newfile}');
266
-				}
267
-			}
268
-
269
-			$this->setIcon($event, 'change');
270
-		} elseif ($event->getSubject() === 'moved_self') {
271
-			$subject = $this->l->t('You moved {oldfile} to {newfile}');
272
-			$this->setIcon($event, 'change');
273
-		} elseif ($event->getSubject() === 'moved_by') {
274
-			$subject = $this->l->t('{user} moved {oldfile} to {newfile}');
275
-			$this->setIcon($event, 'change');
276
-		} else {
277
-			throw new \InvalidArgumentException();
278
-		}
279
-
280
-		if ($this->fileIsEncrypted) {
281
-			$event->setSubject($event->getSubject() . '_enc', $event->getSubjectParameters());
282
-		}
283
-
284
-		if (!isset($parsedParameters['user'])) {
285
-			// External user via public link share
286
-			$subject = str_replace('{user}', $this->activityLang->t('"remote user"'), $subject);
287
-		}
288
-
289
-		$this->setSubjects($event, $subject, $parsedParameters);
290
-
291
-		if ($event->getSubject() === 'moved_self' || $event->getSubject() === 'moved_by') {
292
-			$event = $this->eventMerger->mergeEvents('oldfile', $event, $previousEvent);
293
-		} else {
294
-			$event = $this->eventMerger->mergeEvents('file', $event, $previousEvent);
295
-		}
296
-
297
-		if ($event->getChildEvent() === null) {
298
-			// Couldn't group by file, maybe we can group by user
299
-			$event = $this->eventMerger->mergeEvents('user', $event, $previousEvent);
300
-		}
301
-
302
-		return $event;
303
-	}
304
-
305
-	private function isHiddenFile(string $filename): bool {
306
-		return strlen($filename) > 0 && $filename[0] === '.';
307
-	}
308
-
309
-	protected function setSubjects(IEvent $event, $subject, array $parameters) {
310
-		$placeholders = $replacements = [];
311
-		foreach ($parameters as $placeholder => $parameter) {
312
-			$placeholders[] = '{' . $placeholder . '}';
313
-			if ($parameter['type'] === 'file') {
314
-				$replacements[] = $parameter['path'];
315
-			} else {
316
-				$replacements[] = $parameter['name'];
317
-			}
318
-		}
319
-
320
-		$event->setParsedSubject(str_replace($placeholders, $replacements, $subject))
321
-			->setRichSubject($subject, $parameters);
322
-	}
323
-
324
-	/**
325
-	 * @param IEvent $event
326
-	 * @return array
327
-	 * @throws \InvalidArgumentException
328
-	 */
329
-	protected function getParameters(IEvent $event) {
330
-		$parameters = $event->getSubjectParameters();
331
-		switch ($event->getSubject()) {
332
-			case 'created_self':
333
-			case 'created_public':
334
-			case 'changed_self':
335
-			case 'deleted_self':
336
-			case 'restored_self':
337
-				return [
338
-					'file' => $this->getFile($parameters[0], $event),
339
-				];
340
-			case 'created_by':
341
-			case 'changed_by':
342
-			case 'deleted_by':
343
-			case 'restored_by':
344
-				if ($parameters[1] === '') {
345
-					// External user via public link share
346
-					return [
347
-						'file' => $this->getFile($parameters[0], $event),
348
-					];
349
-				}
350
-				return [
351
-					'file' => $this->getFile($parameters[0], $event),
352
-					'user' => $this->getUser($parameters[1]),
353
-				];
354
-			case 'renamed_self':
355
-			case 'moved_self':
356
-				return [
357
-					'newfile' => $this->getFile($parameters[0]),
358
-					'oldfile' => $this->getFile($parameters[1]),
359
-				];
360
-			case 'renamed_by':
361
-			case 'moved_by':
362
-				if ($parameters[1] === '') {
363
-					// External user via public link share
364
-					return [
365
-						'newfile' => $this->getFile($parameters[0]),
366
-						'oldfile' => $this->getFile($parameters[2]),
367
-					];
368
-				}
369
-				return [
370
-					'newfile' => $this->getFile($parameters[0]),
371
-					'user' => $this->getUser($parameters[1]),
372
-					'oldfile' => $this->getFile($parameters[2]),
373
-				];
374
-		}
375
-		return [];
376
-	}
377
-
378
-	/**
379
-	 * @param array|string $parameter
380
-	 * @param IEvent|null $event
381
-	 * @return array
382
-	 * @throws \InvalidArgumentException
383
-	 */
384
-	protected function getFile($parameter, IEvent $event = null) {
385
-		if (is_array($parameter)) {
386
-			$path = reset($parameter);
387
-			$id = (string) key($parameter);
388
-		} elseif ($event !== null) {
389
-			// Legacy from before ownCloud 8.2
390
-			$path = $parameter;
391
-			$id = $event->getObjectId();
392
-		} else {
393
-			throw new \InvalidArgumentException('Could not generate file parameter');
394
-		}
395
-
396
-		$encryptionContainer = $this->getEndToEndEncryptionContainer($id, $path);
397
-		if ($encryptionContainer instanceof Folder) {
398
-			$this->fileIsEncrypted = true;
399
-			try {
400
-				$fullPath = rtrim($encryptionContainer->getPath(), '/');
401
-				// Remove /user/files/...
402
-				[,,, $path] = explode('/', $fullPath, 4);
403
-				if (!$path) {
404
-					throw new InvalidPathException('Path could not be split correctly');
405
-				}
406
-
407
-				return [
408
-					'type' => 'file',
409
-					'id' => $encryptionContainer->getId(),
410
-					'name' => $encryptionContainer->getName(),
411
-					'path' => $path,
412
-					'link' => $this->url->linkToRouteAbsolute('files.viewcontroller.showFile', ['fileid' => $encryptionContainer->getId()]),
413
-				];
414
-			} catch (\Exception $e) {
415
-				// fall back to the normal one
416
-				$this->fileIsEncrypted = false;
417
-			}
418
-		}
419
-
420
-		return [
421
-			'type' => 'file',
422
-			'id' => $id,
423
-			'name' => basename($path),
424
-			'path' => trim($path, '/'),
425
-			'link' => $this->url->linkToRouteAbsolute('files.viewcontroller.showFile', ['fileid' => $id]),
426
-		];
427
-	}
428
-
429
-	protected $fileEncrypted = [];
430
-
431
-	/**
432
-	 * Check if a file is end2end encrypted
433
-	 * @param int $fileId
434
-	 * @param string $path
435
-	 * @return Folder|null
436
-	 */
437
-	protected function getEndToEndEncryptionContainer($fileId, $path) {
438
-		if (isset($this->fileEncrypted[$fileId])) {
439
-			return $this->fileEncrypted[$fileId];
440
-		}
441
-
442
-		$fileName = basename($path);
443
-		if (!preg_match('/^[0-9a-fA-F]{32}$/', $fileName)) {
444
-			$this->fileEncrypted[$fileId] = false;
445
-			return $this->fileEncrypted[$fileId];
446
-		}
447
-
448
-		$userFolder = $this->rootFolder->getUserFolder($this->activityManager->getCurrentUserId());
449
-		$files = $userFolder->getById($fileId);
450
-		if (empty($files)) {
451
-			try {
452
-				// Deleted, try with parent
453
-				$file = $this->findExistingParent($userFolder, dirname($path));
454
-			} catch (NotFoundException $e) {
455
-				return null;
456
-			}
457
-
458
-			if (!$file instanceof Folder || !$file->isEncrypted()) {
459
-				return null;
460
-			}
461
-
462
-			$this->fileEncrypted[$fileId] = $file;
463
-			return $file;
464
-		}
465
-
466
-		$file = array_shift($files);
467
-
468
-		if ($file instanceof Folder && $file->isEncrypted()) {
469
-			// If the folder is encrypted, it is the Container,
470
-			// but can be the name is just fine.
471
-			$this->fileEncrypted[$fileId] = true;
472
-			return null;
473
-		}
474
-
475
-		$this->fileEncrypted[$fileId] = $this->getParentEndToEndEncryptionContainer($userFolder, $file);
476
-		return $this->fileEncrypted[$fileId];
477
-	}
478
-
479
-	/**
480
-	 * @param Folder $userFolder
481
-	 * @param string $path
482
-	 * @return Folder
483
-	 * @throws NotFoundException
484
-	 */
485
-	protected function findExistingParent(Folder $userFolder, $path) {
486
-		if ($path === '/') {
487
-			throw new NotFoundException('Reached the root');
488
-		}
489
-
490
-		try {
491
-			$folder = $userFolder->get(dirname($path));
492
-		} catch (NotFoundException $e) {
493
-			return $this->findExistingParent($userFolder, dirname($path));
494
-		}
495
-
496
-		return $folder;
497
-	}
498
-
499
-	/**
500
-	 * Check all parents until the user's root folder if one is encrypted
501
-	 *
502
-	 * @param Folder $userFolder
503
-	 * @param Node $file
504
-	 * @return Node|null
505
-	 */
506
-	protected function getParentEndToEndEncryptionContainer(Folder $userFolder, Node $file) {
507
-		try {
508
-			$parent = $file->getParent();
509
-
510
-			if ($userFolder->getId() === $parent->getId()) {
511
-				return null;
512
-			}
513
-		} catch (\Exception $e) {
514
-			return null;
515
-		}
516
-
517
-		if ($parent->isEncrypted()) {
518
-			return $parent;
519
-		}
520
-
521
-		return $this->getParentEndToEndEncryptionContainer($userFolder, $parent);
522
-	}
523
-
524
-	/**
525
-	 * @param string $uid
526
-	 * @return array
527
-	 */
528
-	protected function getUser($uid) {
529
-		// First try local user
530
-		$displayName = $this->userManager->getDisplayName($uid);
531
-		if ($displayName !== null) {
532
-			return [
533
-				'type' => 'user',
534
-				'id' => $uid,
535
-				'name' => $displayName,
536
-			];
537
-		}
538
-
539
-		// Then a contact from the addressbook
540
-		if ($this->cloudIdManager->isValidCloudId($uid)) {
541
-			$cloudId = $this->cloudIdManager->resolveCloudId($uid);
542
-			return [
543
-				'type' => 'user',
544
-				'id' => $cloudId->getUser(),
545
-				'name' => $this->getDisplayNameFromAddressBook($cloudId->getDisplayId()),
546
-				'server' => $cloudId->getRemote(),
547
-			];
548
-		}
549
-
550
-		// Fallback to empty dummy data
551
-		return [
552
-			'type' => 'user',
553
-			'id' => $uid,
554
-			'name' => $uid,
555
-		];
556
-	}
557
-
558
-	protected function getDisplayNameFromAddressBook(string $search): string {
559
-		if (isset($this->displayNames[$search])) {
560
-			return $this->displayNames[$search];
561
-		}
562
-
563
-		$addressBookContacts = $this->contactsManager->search($search, ['CLOUD'], [
564
-			'limit' => 1,
565
-			'enumeration' => false,
566
-			'fullmatch' => false,
567
-			'strict_search' => true,
568
-		]);
569
-		foreach ($addressBookContacts as $contact) {
570
-			if (isset($contact['isLocalSystemBook'])) {
571
-				continue;
572
-			}
573
-
574
-			if (isset($contact['CLOUD'])) {
575
-				$cloudIds = $contact['CLOUD'];
576
-				if (is_string($cloudIds)) {
577
-					$cloudIds = [$cloudIds];
578
-				}
579
-
580
-				$lowerSearch = strtolower($search);
581
-				foreach ($cloudIds as $cloudId) {
582
-					if (strtolower($cloudId) === $lowerSearch) {
583
-						$this->displayNames[$search] = $contact['FN'] . " ($cloudId)";
584
-						return $this->displayNames[$search];
585
-					}
586
-				}
587
-			}
588
-		}
589
-
590
-		return $search;
591
-	}
47
+    /** @var IFactory */
48
+    protected $languageFactory;
49
+
50
+    /** @var IL10N */
51
+    protected $l;
52
+    /** @var IL10N */
53
+    protected $activityLang;
54
+
55
+    /** @var IURLGenerator */
56
+    protected $url;
57
+
58
+    /** @var IManager */
59
+    protected $activityManager;
60
+
61
+    /** @var IUserManager */
62
+    protected $userManager;
63
+
64
+    /** @var IRootFolder */
65
+    protected $rootFolder;
66
+
67
+    /** @var IEventMerger */
68
+    protected $eventMerger;
69
+
70
+    /** @var ICloudIdManager */
71
+    protected $cloudIdManager;
72
+
73
+    /** @var IContactsManager */
74
+    protected $contactsManager;
75
+
76
+    /** @var string[] cached displayNames - key is the cloud id and value the displayname */
77
+    protected $displayNames = [];
78
+
79
+    protected $fileIsEncrypted = false;
80
+
81
+    public function __construct(IFactory $languageFactory,
82
+                                IURLGenerator $url,
83
+                                IManager $activityManager,
84
+                                IUserManager $userManager,
85
+                                IRootFolder $rootFolder,
86
+                                ICloudIdManager $cloudIdManager,
87
+                                IContactsManager $contactsManager,
88
+                                IEventMerger $eventMerger) {
89
+        $this->languageFactory = $languageFactory;
90
+        $this->url = $url;
91
+        $this->activityManager = $activityManager;
92
+        $this->userManager = $userManager;
93
+        $this->rootFolder = $rootFolder;
94
+        $this->cloudIdManager = $cloudIdManager;
95
+        $this->contactsManager = $contactsManager;
96
+        $this->eventMerger = $eventMerger;
97
+    }
98
+
99
+    /**
100
+     * @param string $language
101
+     * @param IEvent $event
102
+     * @param IEvent|null $previousEvent
103
+     * @return IEvent
104
+     * @throws \InvalidArgumentException
105
+     * @since 11.0.0
106
+     */
107
+    public function parse($language, IEvent $event, IEvent $previousEvent = null) {
108
+        if ($event->getApp() !== 'files') {
109
+            throw new \InvalidArgumentException();
110
+        }
111
+
112
+        $this->l = $this->languageFactory->get('files', $language);
113
+        $this->activityLang = $this->languageFactory->get('activity', $language);
114
+
115
+        if ($this->activityManager->isFormattingFilteredObject()) {
116
+            try {
117
+                return $this->parseShortVersion($event, $previousEvent);
118
+            } catch (\InvalidArgumentException $e) {
119
+                // Ignore and simply use the long version...
120
+            }
121
+        }
122
+
123
+        return $this->parseLongVersion($event, $previousEvent);
124
+    }
125
+
126
+    protected function setIcon(IEvent $event, string $icon, string $app = 'files') {
127
+        if ($this->activityManager->getRequirePNG()) {
128
+            $event->setIcon($this->url->getAbsoluteURL($this->url->imagePath($app, $icon . '.png')));
129
+        } else {
130
+            $event->setIcon($this->url->getAbsoluteURL($this->url->imagePath($app, $icon . '.svg')));
131
+        }
132
+    }
133
+
134
+    /**
135
+     * @param IEvent $event
136
+     * @param IEvent|null $previousEvent
137
+     * @return IEvent
138
+     * @throws \InvalidArgumentException
139
+     * @since 11.0.0
140
+     */
141
+    public function parseShortVersion(IEvent $event, IEvent $previousEvent = null) {
142
+        $parsedParameters = $this->getParameters($event);
143
+
144
+        if ($event->getSubject() === 'created_by') {
145
+            $subject = $this->l->t('Created by {user}');
146
+            $this->setIcon($event, 'add-color');
147
+        } elseif ($event->getSubject() === 'changed_by') {
148
+            $subject = $this->l->t('Changed by {user}');
149
+            $this->setIcon($event, 'change');
150
+        } elseif ($event->getSubject() === 'deleted_by') {
151
+            $subject = $this->l->t('Deleted by {user}');
152
+            $this->setIcon($event, 'delete-color');
153
+        } elseif ($event->getSubject() === 'restored_by') {
154
+            $subject = $this->l->t('Restored by {user}');
155
+            $this->setIcon($event, 'actions/history', 'core');
156
+        } elseif ($event->getSubject() === 'renamed_by') {
157
+            $subject = $this->l->t('Renamed by {user}');
158
+            $this->setIcon($event, 'change');
159
+        } elseif ($event->getSubject() === 'moved_by') {
160
+            $subject = $this->l->t('Moved by {user}');
161
+            $this->setIcon($event, 'change');
162
+        } else {
163
+            throw new \InvalidArgumentException();
164
+        }
165
+
166
+        if (!isset($parsedParameters['user'])) {
167
+            // External user via public link share
168
+            $subject = str_replace('{user}', $this->activityLang->t('"remote user"'), $subject);
169
+        }
170
+
171
+        $this->setSubjects($event, $subject, $parsedParameters);
172
+
173
+        return $this->eventMerger->mergeEvents('user', $event, $previousEvent);
174
+    }
175
+
176
+    /**
177
+     * @param IEvent $event
178
+     * @param IEvent|null $previousEvent
179
+     * @return IEvent
180
+     * @throws \InvalidArgumentException
181
+     * @since 11.0.0
182
+     */
183
+    public function parseLongVersion(IEvent $event, IEvent $previousEvent = null) {
184
+        $this->fileIsEncrypted = false;
185
+        $parsedParameters = $this->getParameters($event);
186
+
187
+        if ($event->getSubject() === 'created_self') {
188
+            $subject = $this->l->t('You created {file}');
189
+            if ($this->fileIsEncrypted) {
190
+                $subject = $this->l->t('You created an encrypted file in {file}');
191
+            }
192
+            $this->setIcon($event, 'add-color');
193
+        } elseif ($event->getSubject() === 'created_by') {
194
+            $subject = $this->l->t('{user} created {file}');
195
+            if ($this->fileIsEncrypted) {
196
+                $subject = $this->l->t('{user} created an encrypted file in {file}');
197
+            }
198
+            $this->setIcon($event, 'add-color');
199
+        } elseif ($event->getSubject() === 'created_public') {
200
+            $subject = $this->l->t('{file} was created in a public folder');
201
+            $this->setIcon($event, 'add-color');
202
+        } elseif ($event->getSubject() === 'changed_self') {
203
+            $subject = $this->l->t('You changed {file}');
204
+            if ($this->fileIsEncrypted) {
205
+                $subject = $this->l->t('You changed an encrypted file in {file}');
206
+            }
207
+            $this->setIcon($event, 'change');
208
+        } elseif ($event->getSubject() === 'changed_by') {
209
+            $subject = $this->l->t('{user} changed {file}');
210
+            if ($this->fileIsEncrypted) {
211
+                $subject = $this->l->t('{user} changed an encrypted file in {file}');
212
+            }
213
+            $this->setIcon($event, 'change');
214
+        } elseif ($event->getSubject() === 'deleted_self') {
215
+            $subject = $this->l->t('You deleted {file}');
216
+            if ($this->fileIsEncrypted) {
217
+                $subject = $this->l->t('You deleted an encrypted file in {file}');
218
+            }
219
+            $this->setIcon($event, 'delete-color');
220
+        } elseif ($event->getSubject() === 'deleted_by') {
221
+            $subject = $this->l->t('{user} deleted {file}');
222
+            if ($this->fileIsEncrypted) {
223
+                $subject = $this->l->t('{user} deleted an encrypted file in {file}');
224
+            }
225
+            $this->setIcon($event, 'delete-color');
226
+        } elseif ($event->getSubject() === 'restored_self') {
227
+            $subject = $this->l->t('You restored {file}');
228
+            $this->setIcon($event, 'actions/history', 'core');
229
+        } elseif ($event->getSubject() === 'restored_by') {
230
+            $subject = $this->l->t('{user} restored {file}');
231
+            $this->setIcon($event, 'actions/history', 'core');
232
+        } elseif ($event->getSubject() === 'renamed_self') {
233
+            $oldFileName = $parsedParameters['oldfile']['name'];
234
+            $newFileName = $parsedParameters['newfile']['name'];
235
+
236
+            if ($this->isHiddenFile($oldFileName)) {
237
+                if ($this->isHiddenFile($newFileName)) {
238
+                    $subject = $this->l->t('You renamed {oldfile} (hidden) to {newfile} (hidden)');
239
+                } else {
240
+                    $subject = $this->l->t('You renamed {oldfile} (hidden) to {newfile}');
241
+                }
242
+            } else {
243
+                if ($this->isHiddenFile($newFileName)) {
244
+                    $subject = $this->l->t('You renamed {oldfile} to {newfile} (hidden)');
245
+                } else {
246
+                    $subject = $this->l->t('You renamed {oldfile} to {newfile}');
247
+                }
248
+            }
249
+
250
+            $this->setIcon($event, 'change');
251
+        } elseif ($event->getSubject() === 'renamed_by') {
252
+            $oldFileName = $parsedParameters['oldfile']['name'];
253
+            $newFileName = $parsedParameters['newfile']['name'];
254
+
255
+            if ($this->isHiddenFile($oldFileName)) {
256
+                if ($this->isHiddenFile($newFileName)) {
257
+                    $subject = $this->l->t('{user} renamed {oldfile} (hidden) to {newfile} (hidden)');
258
+                } else {
259
+                    $subject = $this->l->t('{user} renamed {oldfile} (hidden) to {newfile}');
260
+                }
261
+            } else {
262
+                if ($this->isHiddenFile($newFileName)) {
263
+                    $subject = $this->l->t('{user} renamed {oldfile} to {newfile} (hidden)');
264
+                } else {
265
+                    $subject = $this->l->t('{user} renamed {oldfile} to {newfile}');
266
+                }
267
+            }
268
+
269
+            $this->setIcon($event, 'change');
270
+        } elseif ($event->getSubject() === 'moved_self') {
271
+            $subject = $this->l->t('You moved {oldfile} to {newfile}');
272
+            $this->setIcon($event, 'change');
273
+        } elseif ($event->getSubject() === 'moved_by') {
274
+            $subject = $this->l->t('{user} moved {oldfile} to {newfile}');
275
+            $this->setIcon($event, 'change');
276
+        } else {
277
+            throw new \InvalidArgumentException();
278
+        }
279
+
280
+        if ($this->fileIsEncrypted) {
281
+            $event->setSubject($event->getSubject() . '_enc', $event->getSubjectParameters());
282
+        }
283
+
284
+        if (!isset($parsedParameters['user'])) {
285
+            // External user via public link share
286
+            $subject = str_replace('{user}', $this->activityLang->t('"remote user"'), $subject);
287
+        }
288
+
289
+        $this->setSubjects($event, $subject, $parsedParameters);
290
+
291
+        if ($event->getSubject() === 'moved_self' || $event->getSubject() === 'moved_by') {
292
+            $event = $this->eventMerger->mergeEvents('oldfile', $event, $previousEvent);
293
+        } else {
294
+            $event = $this->eventMerger->mergeEvents('file', $event, $previousEvent);
295
+        }
296
+
297
+        if ($event->getChildEvent() === null) {
298
+            // Couldn't group by file, maybe we can group by user
299
+            $event = $this->eventMerger->mergeEvents('user', $event, $previousEvent);
300
+        }
301
+
302
+        return $event;
303
+    }
304
+
305
+    private function isHiddenFile(string $filename): bool {
306
+        return strlen($filename) > 0 && $filename[0] === '.';
307
+    }
308
+
309
+    protected function setSubjects(IEvent $event, $subject, array $parameters) {
310
+        $placeholders = $replacements = [];
311
+        foreach ($parameters as $placeholder => $parameter) {
312
+            $placeholders[] = '{' . $placeholder . '}';
313
+            if ($parameter['type'] === 'file') {
314
+                $replacements[] = $parameter['path'];
315
+            } else {
316
+                $replacements[] = $parameter['name'];
317
+            }
318
+        }
319
+
320
+        $event->setParsedSubject(str_replace($placeholders, $replacements, $subject))
321
+            ->setRichSubject($subject, $parameters);
322
+    }
323
+
324
+    /**
325
+     * @param IEvent $event
326
+     * @return array
327
+     * @throws \InvalidArgumentException
328
+     */
329
+    protected function getParameters(IEvent $event) {
330
+        $parameters = $event->getSubjectParameters();
331
+        switch ($event->getSubject()) {
332
+            case 'created_self':
333
+            case 'created_public':
334
+            case 'changed_self':
335
+            case 'deleted_self':
336
+            case 'restored_self':
337
+                return [
338
+                    'file' => $this->getFile($parameters[0], $event),
339
+                ];
340
+            case 'created_by':
341
+            case 'changed_by':
342
+            case 'deleted_by':
343
+            case 'restored_by':
344
+                if ($parameters[1] === '') {
345
+                    // External user via public link share
346
+                    return [
347
+                        'file' => $this->getFile($parameters[0], $event),
348
+                    ];
349
+                }
350
+                return [
351
+                    'file' => $this->getFile($parameters[0], $event),
352
+                    'user' => $this->getUser($parameters[1]),
353
+                ];
354
+            case 'renamed_self':
355
+            case 'moved_self':
356
+                return [
357
+                    'newfile' => $this->getFile($parameters[0]),
358
+                    'oldfile' => $this->getFile($parameters[1]),
359
+                ];
360
+            case 'renamed_by':
361
+            case 'moved_by':
362
+                if ($parameters[1] === '') {
363
+                    // External user via public link share
364
+                    return [
365
+                        'newfile' => $this->getFile($parameters[0]),
366
+                        'oldfile' => $this->getFile($parameters[2]),
367
+                    ];
368
+                }
369
+                return [
370
+                    'newfile' => $this->getFile($parameters[0]),
371
+                    'user' => $this->getUser($parameters[1]),
372
+                    'oldfile' => $this->getFile($parameters[2]),
373
+                ];
374
+        }
375
+        return [];
376
+    }
377
+
378
+    /**
379
+     * @param array|string $parameter
380
+     * @param IEvent|null $event
381
+     * @return array
382
+     * @throws \InvalidArgumentException
383
+     */
384
+    protected function getFile($parameter, IEvent $event = null) {
385
+        if (is_array($parameter)) {
386
+            $path = reset($parameter);
387
+            $id = (string) key($parameter);
388
+        } elseif ($event !== null) {
389
+            // Legacy from before ownCloud 8.2
390
+            $path = $parameter;
391
+            $id = $event->getObjectId();
392
+        } else {
393
+            throw new \InvalidArgumentException('Could not generate file parameter');
394
+        }
395
+
396
+        $encryptionContainer = $this->getEndToEndEncryptionContainer($id, $path);
397
+        if ($encryptionContainer instanceof Folder) {
398
+            $this->fileIsEncrypted = true;
399
+            try {
400
+                $fullPath = rtrim($encryptionContainer->getPath(), '/');
401
+                // Remove /user/files/...
402
+                [,,, $path] = explode('/', $fullPath, 4);
403
+                if (!$path) {
404
+                    throw new InvalidPathException('Path could not be split correctly');
405
+                }
406
+
407
+                return [
408
+                    'type' => 'file',
409
+                    'id' => $encryptionContainer->getId(),
410
+                    'name' => $encryptionContainer->getName(),
411
+                    'path' => $path,
412
+                    'link' => $this->url->linkToRouteAbsolute('files.viewcontroller.showFile', ['fileid' => $encryptionContainer->getId()]),
413
+                ];
414
+            } catch (\Exception $e) {
415
+                // fall back to the normal one
416
+                $this->fileIsEncrypted = false;
417
+            }
418
+        }
419
+
420
+        return [
421
+            'type' => 'file',
422
+            'id' => $id,
423
+            'name' => basename($path),
424
+            'path' => trim($path, '/'),
425
+            'link' => $this->url->linkToRouteAbsolute('files.viewcontroller.showFile', ['fileid' => $id]),
426
+        ];
427
+    }
428
+
429
+    protected $fileEncrypted = [];
430
+
431
+    /**
432
+     * Check if a file is end2end encrypted
433
+     * @param int $fileId
434
+     * @param string $path
435
+     * @return Folder|null
436
+     */
437
+    protected function getEndToEndEncryptionContainer($fileId, $path) {
438
+        if (isset($this->fileEncrypted[$fileId])) {
439
+            return $this->fileEncrypted[$fileId];
440
+        }
441
+
442
+        $fileName = basename($path);
443
+        if (!preg_match('/^[0-9a-fA-F]{32}$/', $fileName)) {
444
+            $this->fileEncrypted[$fileId] = false;
445
+            return $this->fileEncrypted[$fileId];
446
+        }
447
+
448
+        $userFolder = $this->rootFolder->getUserFolder($this->activityManager->getCurrentUserId());
449
+        $files = $userFolder->getById($fileId);
450
+        if (empty($files)) {
451
+            try {
452
+                // Deleted, try with parent
453
+                $file = $this->findExistingParent($userFolder, dirname($path));
454
+            } catch (NotFoundException $e) {
455
+                return null;
456
+            }
457
+
458
+            if (!$file instanceof Folder || !$file->isEncrypted()) {
459
+                return null;
460
+            }
461
+
462
+            $this->fileEncrypted[$fileId] = $file;
463
+            return $file;
464
+        }
465
+
466
+        $file = array_shift($files);
467
+
468
+        if ($file instanceof Folder && $file->isEncrypted()) {
469
+            // If the folder is encrypted, it is the Container,
470
+            // but can be the name is just fine.
471
+            $this->fileEncrypted[$fileId] = true;
472
+            return null;
473
+        }
474
+
475
+        $this->fileEncrypted[$fileId] = $this->getParentEndToEndEncryptionContainer($userFolder, $file);
476
+        return $this->fileEncrypted[$fileId];
477
+    }
478
+
479
+    /**
480
+     * @param Folder $userFolder
481
+     * @param string $path
482
+     * @return Folder
483
+     * @throws NotFoundException
484
+     */
485
+    protected function findExistingParent(Folder $userFolder, $path) {
486
+        if ($path === '/') {
487
+            throw new NotFoundException('Reached the root');
488
+        }
489
+
490
+        try {
491
+            $folder = $userFolder->get(dirname($path));
492
+        } catch (NotFoundException $e) {
493
+            return $this->findExistingParent($userFolder, dirname($path));
494
+        }
495
+
496
+        return $folder;
497
+    }
498
+
499
+    /**
500
+     * Check all parents until the user's root folder if one is encrypted
501
+     *
502
+     * @param Folder $userFolder
503
+     * @param Node $file
504
+     * @return Node|null
505
+     */
506
+    protected function getParentEndToEndEncryptionContainer(Folder $userFolder, Node $file) {
507
+        try {
508
+            $parent = $file->getParent();
509
+
510
+            if ($userFolder->getId() === $parent->getId()) {
511
+                return null;
512
+            }
513
+        } catch (\Exception $e) {
514
+            return null;
515
+        }
516
+
517
+        if ($parent->isEncrypted()) {
518
+            return $parent;
519
+        }
520
+
521
+        return $this->getParentEndToEndEncryptionContainer($userFolder, $parent);
522
+    }
523
+
524
+    /**
525
+     * @param string $uid
526
+     * @return array
527
+     */
528
+    protected function getUser($uid) {
529
+        // First try local user
530
+        $displayName = $this->userManager->getDisplayName($uid);
531
+        if ($displayName !== null) {
532
+            return [
533
+                'type' => 'user',
534
+                'id' => $uid,
535
+                'name' => $displayName,
536
+            ];
537
+        }
538
+
539
+        // Then a contact from the addressbook
540
+        if ($this->cloudIdManager->isValidCloudId($uid)) {
541
+            $cloudId = $this->cloudIdManager->resolveCloudId($uid);
542
+            return [
543
+                'type' => 'user',
544
+                'id' => $cloudId->getUser(),
545
+                'name' => $this->getDisplayNameFromAddressBook($cloudId->getDisplayId()),
546
+                'server' => $cloudId->getRemote(),
547
+            ];
548
+        }
549
+
550
+        // Fallback to empty dummy data
551
+        return [
552
+            'type' => 'user',
553
+            'id' => $uid,
554
+            'name' => $uid,
555
+        ];
556
+    }
557
+
558
+    protected function getDisplayNameFromAddressBook(string $search): string {
559
+        if (isset($this->displayNames[$search])) {
560
+            return $this->displayNames[$search];
561
+        }
562
+
563
+        $addressBookContacts = $this->contactsManager->search($search, ['CLOUD'], [
564
+            'limit' => 1,
565
+            'enumeration' => false,
566
+            'fullmatch' => false,
567
+            'strict_search' => true,
568
+        ]);
569
+        foreach ($addressBookContacts as $contact) {
570
+            if (isset($contact['isLocalSystemBook'])) {
571
+                continue;
572
+            }
573
+
574
+            if (isset($contact['CLOUD'])) {
575
+                $cloudIds = $contact['CLOUD'];
576
+                if (is_string($cloudIds)) {
577
+                    $cloudIds = [$cloudIds];
578
+                }
579
+
580
+                $lowerSearch = strtolower($search);
581
+                foreach ($cloudIds as $cloudId) {
582
+                    if (strtolower($cloudId) === $lowerSearch) {
583
+                        $this->displayNames[$search] = $contact['FN'] . " ($cloudId)";
584
+                        return $this->displayNames[$search];
585
+                    }
586
+                }
587
+            }
588
+        }
589
+
590
+        return $search;
591
+    }
592 592
 }
Please login to merge, or discard this patch.
apps/files_sharing/lib/Activity/Providers/Base.php 2 patches
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -125,7 +125,7 @@  discard block
 block discarded – undo
125 125
 	protected function setSubjects(IEvent $event, $subject, array $parameters) {
126 126
 		$placeholders = $replacements = [];
127 127
 		foreach ($parameters as $placeholder => $parameter) {
128
-			$placeholders[] = '{' . $placeholder . '}';
128
+			$placeholders[] = '{'.$placeholder.'}';
129 129
 			if ($parameter['type'] === 'file') {
130 130
 				$replacements[] = $parameter['path'];
131 131
 			} else {
@@ -218,7 +218,7 @@  discard block
 block discarded – undo
218 218
 				$lowerSearch = strtolower($search);
219 219
 				foreach ($cloudIds as $cloudId) {
220 220
 					if (strtolower($cloudId) === $lowerSearch) {
221
-						$this->displayNames[$search] = $contact['FN'] . " ($cloudId)";
221
+						$this->displayNames[$search] = $contact['FN']." ($cloudId)";
222 222
 						return $this->displayNames[$search];
223 223
 					}
224 224
 				}
Please login to merge, or discard this patch.
Indentation   +202 added lines, -202 removed lines patch added patch discarded remove patch
@@ -37,206 +37,206 @@
 block discarded – undo
37 37
 
38 38
 abstract class Base implements IProvider {
39 39
 
40
-	/** @var IFactory */
41
-	protected $languageFactory;
42
-
43
-	/** @var IL10N */
44
-	protected $l;
45
-
46
-	/** @var IURLGenerator */
47
-	protected $url;
48
-
49
-	/** @var IManager */
50
-	protected $activityManager;
51
-
52
-	/** @var IUserManager */
53
-	protected $userManager;
54
-
55
-	/** @var IEventMerger */
56
-	protected $eventMerger;
57
-
58
-	/** @var IContactsManager */
59
-	protected $contactsManager;
60
-
61
-	/** @var ICloudIdManager */
62
-	protected $cloudIdManager;
63
-
64
-	/** @var array */
65
-	protected $displayNames = [];
66
-
67
-	public function __construct(IFactory $languageFactory,
68
-								IURLGenerator $url,
69
-								IManager $activityManager,
70
-								IUserManager $userManager,
71
-								ICloudIdManager $cloudIdManager,
72
-								IContactsManager $contactsManager,
73
-								IEventMerger $eventMerger) {
74
-		$this->languageFactory = $languageFactory;
75
-		$this->url = $url;
76
-		$this->activityManager = $activityManager;
77
-		$this->userManager = $userManager;
78
-		$this->cloudIdManager = $cloudIdManager;
79
-		$this->contactsManager = $contactsManager;
80
-		$this->eventMerger = $eventMerger;
81
-	}
82
-
83
-	/**
84
-	 * @param string $language
85
-	 * @param IEvent $event
86
-	 * @param IEvent|null $previousEvent
87
-	 * @return IEvent
88
-	 * @throws \InvalidArgumentException
89
-	 * @since 11.0.0
90
-	 */
91
-	public function parse($language, IEvent $event, IEvent $previousEvent = null) {
92
-		if ($event->getApp() !== 'files_sharing') {
93
-			throw new \InvalidArgumentException();
94
-		}
95
-
96
-		$this->l = $this->languageFactory->get('files_sharing', $language);
97
-
98
-		if ($this->activityManager->isFormattingFilteredObject()) {
99
-			try {
100
-				return $this->parseShortVersion($event);
101
-			} catch (\InvalidArgumentException $e) {
102
-				// Ignore and simply use the long version...
103
-			}
104
-		}
105
-
106
-		return $this->parseLongVersion($event, $previousEvent);
107
-	}
108
-
109
-	/**
110
-	 * @param IEvent $event
111
-	 * @return IEvent
112
-	 * @throws \InvalidArgumentException
113
-	 * @since 11.0.0
114
-	 */
115
-	abstract protected function parseShortVersion(IEvent $event);
116
-
117
-	/**
118
-	 * @param IEvent $event
119
-	 * @param IEvent|null $previousEvent
120
-	 * @return IEvent
121
-	 * @throws \InvalidArgumentException
122
-	 * @since 11.0.0
123
-	 */
124
-	abstract protected function parseLongVersion(IEvent $event, IEvent $previousEvent = null);
125
-
126
-	/**
127
-	 * @param IEvent $event
128
-	 * @param string $subject
129
-	 * @param array $parameters
130
-	 * @throws \InvalidArgumentException
131
-	 */
132
-	protected function setSubjects(IEvent $event, $subject, array $parameters) {
133
-		$placeholders = $replacements = [];
134
-		foreach ($parameters as $placeholder => $parameter) {
135
-			$placeholders[] = '{' . $placeholder . '}';
136
-			if ($parameter['type'] === 'file') {
137
-				$replacements[] = $parameter['path'];
138
-			} else {
139
-				$replacements[] = $parameter['name'];
140
-			}
141
-		}
142
-
143
-		$event->setParsedSubject(str_replace($placeholders, $replacements, $subject))
144
-			->setRichSubject($subject, $parameters);
145
-	}
146
-
147
-	/**
148
-	 * @param array|string $parameter
149
-	 * @param IEvent|null $event
150
-	 * @return array
151
-	 * @throws \InvalidArgumentException
152
-	 */
153
-	protected function getFile($parameter, IEvent $event = null) {
154
-		if (is_array($parameter)) {
155
-			$path = reset($parameter);
156
-			$id = (string) key($parameter);
157
-		} elseif ($event !== null) {
158
-			// Legacy from before ownCloud 8.2
159
-			$path = $parameter;
160
-			$id = $event->getObjectId();
161
-		} else {
162
-			throw new \InvalidArgumentException('Could not generate file parameter');
163
-		}
164
-
165
-		return [
166
-			'type' => 'file',
167
-			'id' => $id,
168
-			'name' => basename($path),
169
-			'path' => trim($path, '/'),
170
-			'link' => $this->url->linkToRouteAbsolute('files.viewcontroller.showFile', ['fileid' => $id]),
171
-		];
172
-	}
173
-
174
-	/**
175
-	 * @param string $uid
176
-	 * @return array
177
-	 */
178
-	protected function getUser($uid) {
179
-		// First try local user
180
-		$displayName = $this->userManager->getDisplayName($uid);
181
-		if ($displayName !== null) {
182
-			return [
183
-				'type' => 'user',
184
-				'id' => $uid,
185
-				'name' => $displayName,
186
-			];
187
-		}
188
-
189
-		// Then a contact from the addressbook
190
-		if ($this->cloudIdManager->isValidCloudId($uid)) {
191
-			$cloudId = $this->cloudIdManager->resolveCloudId($uid);
192
-			return [
193
-				'type' => 'user',
194
-				'id' => $cloudId->getUser(),
195
-				'name' => $this->getDisplayNameFromAddressBook($cloudId->getDisplayId()),
196
-				'server' => $cloudId->getRemote(),
197
-			];
198
-		}
199
-
200
-		// Fallback to empty dummy data
201
-		return [
202
-			'type' => 'user',
203
-			'id' => $uid,
204
-			'name' => $uid,
205
-		];
206
-	}
207
-
208
-	protected function getDisplayNameFromAddressBook(string $search): string {
209
-		if (isset($this->displayNames[$search])) {
210
-			return $this->displayNames[$search];
211
-		}
212
-
213
-		$addressBookContacts = $this->contactsManager->search($search, ['CLOUD'], [
214
-			'limit' => 1,
215
-			'enumeration' => false,
216
-			'fullmatch' => false,
217
-			'strict_search' => true,
218
-		]);
219
-		foreach ($addressBookContacts as $contact) {
220
-			if (isset($contact['isLocalSystemBook'])) {
221
-				continue;
222
-			}
223
-
224
-			if (isset($contact['CLOUD'])) {
225
-				$cloudIds = $contact['CLOUD'];
226
-				if (is_string($cloudIds)) {
227
-					$cloudIds = [$cloudIds];
228
-				}
229
-
230
-				$lowerSearch = strtolower($search);
231
-				foreach ($cloudIds as $cloudId) {
232
-					if (strtolower($cloudId) === $lowerSearch) {
233
-						$this->displayNames[$search] = $contact['FN'] . " ($cloudId)";
234
-						return $this->displayNames[$search];
235
-					}
236
-				}
237
-			}
238
-		}
239
-
240
-		return $search;
241
-	}
40
+    /** @var IFactory */
41
+    protected $languageFactory;
42
+
43
+    /** @var IL10N */
44
+    protected $l;
45
+
46
+    /** @var IURLGenerator */
47
+    protected $url;
48
+
49
+    /** @var IManager */
50
+    protected $activityManager;
51
+
52
+    /** @var IUserManager */
53
+    protected $userManager;
54
+
55
+    /** @var IEventMerger */
56
+    protected $eventMerger;
57
+
58
+    /** @var IContactsManager */
59
+    protected $contactsManager;
60
+
61
+    /** @var ICloudIdManager */
62
+    protected $cloudIdManager;
63
+
64
+    /** @var array */
65
+    protected $displayNames = [];
66
+
67
+    public function __construct(IFactory $languageFactory,
68
+                                IURLGenerator $url,
69
+                                IManager $activityManager,
70
+                                IUserManager $userManager,
71
+                                ICloudIdManager $cloudIdManager,
72
+                                IContactsManager $contactsManager,
73
+                                IEventMerger $eventMerger) {
74
+        $this->languageFactory = $languageFactory;
75
+        $this->url = $url;
76
+        $this->activityManager = $activityManager;
77
+        $this->userManager = $userManager;
78
+        $this->cloudIdManager = $cloudIdManager;
79
+        $this->contactsManager = $contactsManager;
80
+        $this->eventMerger = $eventMerger;
81
+    }
82
+
83
+    /**
84
+     * @param string $language
85
+     * @param IEvent $event
86
+     * @param IEvent|null $previousEvent
87
+     * @return IEvent
88
+     * @throws \InvalidArgumentException
89
+     * @since 11.0.0
90
+     */
91
+    public function parse($language, IEvent $event, IEvent $previousEvent = null) {
92
+        if ($event->getApp() !== 'files_sharing') {
93
+            throw new \InvalidArgumentException();
94
+        }
95
+
96
+        $this->l = $this->languageFactory->get('files_sharing', $language);
97
+
98
+        if ($this->activityManager->isFormattingFilteredObject()) {
99
+            try {
100
+                return $this->parseShortVersion($event);
101
+            } catch (\InvalidArgumentException $e) {
102
+                // Ignore and simply use the long version...
103
+            }
104
+        }
105
+
106
+        return $this->parseLongVersion($event, $previousEvent);
107
+    }
108
+
109
+    /**
110
+     * @param IEvent $event
111
+     * @return IEvent
112
+     * @throws \InvalidArgumentException
113
+     * @since 11.0.0
114
+     */
115
+    abstract protected function parseShortVersion(IEvent $event);
116
+
117
+    /**
118
+     * @param IEvent $event
119
+     * @param IEvent|null $previousEvent
120
+     * @return IEvent
121
+     * @throws \InvalidArgumentException
122
+     * @since 11.0.0
123
+     */
124
+    abstract protected function parseLongVersion(IEvent $event, IEvent $previousEvent = null);
125
+
126
+    /**
127
+     * @param IEvent $event
128
+     * @param string $subject
129
+     * @param array $parameters
130
+     * @throws \InvalidArgumentException
131
+     */
132
+    protected function setSubjects(IEvent $event, $subject, array $parameters) {
133
+        $placeholders = $replacements = [];
134
+        foreach ($parameters as $placeholder => $parameter) {
135
+            $placeholders[] = '{' . $placeholder . '}';
136
+            if ($parameter['type'] === 'file') {
137
+                $replacements[] = $parameter['path'];
138
+            } else {
139
+                $replacements[] = $parameter['name'];
140
+            }
141
+        }
142
+
143
+        $event->setParsedSubject(str_replace($placeholders, $replacements, $subject))
144
+            ->setRichSubject($subject, $parameters);
145
+    }
146
+
147
+    /**
148
+     * @param array|string $parameter
149
+     * @param IEvent|null $event
150
+     * @return array
151
+     * @throws \InvalidArgumentException
152
+     */
153
+    protected function getFile($parameter, IEvent $event = null) {
154
+        if (is_array($parameter)) {
155
+            $path = reset($parameter);
156
+            $id = (string) key($parameter);
157
+        } elseif ($event !== null) {
158
+            // Legacy from before ownCloud 8.2
159
+            $path = $parameter;
160
+            $id = $event->getObjectId();
161
+        } else {
162
+            throw new \InvalidArgumentException('Could not generate file parameter');
163
+        }
164
+
165
+        return [
166
+            'type' => 'file',
167
+            'id' => $id,
168
+            'name' => basename($path),
169
+            'path' => trim($path, '/'),
170
+            'link' => $this->url->linkToRouteAbsolute('files.viewcontroller.showFile', ['fileid' => $id]),
171
+        ];
172
+    }
173
+
174
+    /**
175
+     * @param string $uid
176
+     * @return array
177
+     */
178
+    protected function getUser($uid) {
179
+        // First try local user
180
+        $displayName = $this->userManager->getDisplayName($uid);
181
+        if ($displayName !== null) {
182
+            return [
183
+                'type' => 'user',
184
+                'id' => $uid,
185
+                'name' => $displayName,
186
+            ];
187
+        }
188
+
189
+        // Then a contact from the addressbook
190
+        if ($this->cloudIdManager->isValidCloudId($uid)) {
191
+            $cloudId = $this->cloudIdManager->resolveCloudId($uid);
192
+            return [
193
+                'type' => 'user',
194
+                'id' => $cloudId->getUser(),
195
+                'name' => $this->getDisplayNameFromAddressBook($cloudId->getDisplayId()),
196
+                'server' => $cloudId->getRemote(),
197
+            ];
198
+        }
199
+
200
+        // Fallback to empty dummy data
201
+        return [
202
+            'type' => 'user',
203
+            'id' => $uid,
204
+            'name' => $uid,
205
+        ];
206
+    }
207
+
208
+    protected function getDisplayNameFromAddressBook(string $search): string {
209
+        if (isset($this->displayNames[$search])) {
210
+            return $this->displayNames[$search];
211
+        }
212
+
213
+        $addressBookContacts = $this->contactsManager->search($search, ['CLOUD'], [
214
+            'limit' => 1,
215
+            'enumeration' => false,
216
+            'fullmatch' => false,
217
+            'strict_search' => true,
218
+        ]);
219
+        foreach ($addressBookContacts as $contact) {
220
+            if (isset($contact['isLocalSystemBook'])) {
221
+                continue;
222
+            }
223
+
224
+            if (isset($contact['CLOUD'])) {
225
+                $cloudIds = $contact['CLOUD'];
226
+                if (is_string($cloudIds)) {
227
+                    $cloudIds = [$cloudIds];
228
+                }
229
+
230
+                $lowerSearch = strtolower($search);
231
+                foreach ($cloudIds as $cloudId) {
232
+                    if (strtolower($cloudId) === $lowerSearch) {
233
+                        $this->displayNames[$search] = $contact['FN'] . " ($cloudId)";
234
+                        return $this->displayNames[$search];
235
+                    }
236
+                }
237
+            }
238
+        }
239
+
240
+        return $search;
241
+    }
242 242
 }
Please login to merge, or discard this patch.
apps/files_sharing/lib/Controller/ExternalSharesController.php 2 patches
Spacing   +6 added lines, -6 removed lines patch added patch discarded remove patch
@@ -135,15 +135,15 @@
 block discarded – undo
135 135
 		}
136 136
 
137 137
 		if (
138
-			$this->testUrl('https://' . $remote . '/ocs-provider/') ||
139
-			$this->testUrl('https://' . $remote . '/ocs-provider/index.php') ||
140
-			$this->testUrl('https://' . $remote . '/status.php', true)
138
+			$this->testUrl('https://'.$remote.'/ocs-provider/') ||
139
+			$this->testUrl('https://'.$remote.'/ocs-provider/index.php') ||
140
+			$this->testUrl('https://'.$remote.'/status.php', true)
141 141
 		) {
142 142
 			return new DataResponse('https');
143 143
 		} elseif (
144
-			$this->testUrl('http://' . $remote . '/ocs-provider/') ||
145
-			$this->testUrl('http://' . $remote . '/ocs-provider/index.php') ||
146
-			$this->testUrl('http://' . $remote . '/status.php', true)
144
+			$this->testUrl('http://'.$remote.'/ocs-provider/') ||
145
+			$this->testUrl('http://'.$remote.'/ocs-provider/index.php') ||
146
+			$this->testUrl('http://'.$remote.'/status.php', true)
147 147
 		) {
148 148
 			return new DataResponse('http');
149 149
 		} else {
Please login to merge, or discard this patch.
Indentation   +103 added lines, -103 removed lines patch added patch discarded remove patch
@@ -40,115 +40,115 @@
 block discarded – undo
40 40
  */
41 41
 class ExternalSharesController extends Controller {
42 42
 
43
-	/** @var \OCA\Files_Sharing\External\Manager */
44
-	private $externalManager;
45
-	/** @var IClientService */
46
-	private $clientService;
43
+    /** @var \OCA\Files_Sharing\External\Manager */
44
+    private $externalManager;
45
+    /** @var IClientService */
46
+    private $clientService;
47 47
 
48
-	/**
49
-	 * @param string $appName
50
-	 * @param IRequest $request
51
-	 * @param \OCA\Files_Sharing\External\Manager $externalManager
52
-	 * @param IClientService $clientService
53
-	 */
54
-	public function __construct($appName,
55
-								IRequest $request,
56
-								\OCA\Files_Sharing\External\Manager $externalManager,
57
-								IClientService $clientService) {
58
-		parent::__construct($appName, $request);
59
-		$this->externalManager = $externalManager;
60
-		$this->clientService = $clientService;
61
-	}
48
+    /**
49
+     * @param string $appName
50
+     * @param IRequest $request
51
+     * @param \OCA\Files_Sharing\External\Manager $externalManager
52
+     * @param IClientService $clientService
53
+     */
54
+    public function __construct($appName,
55
+                                IRequest $request,
56
+                                \OCA\Files_Sharing\External\Manager $externalManager,
57
+                                IClientService $clientService) {
58
+        parent::__construct($appName, $request);
59
+        $this->externalManager = $externalManager;
60
+        $this->clientService = $clientService;
61
+    }
62 62
 
63
-	/**
64
-	 * @NoAdminRequired
65
-	 * @NoOutgoingFederatedSharingRequired
66
-	 *
67
-	 * @return JSONResponse
68
-	 */
69
-	public function index() {
70
-		return new JSONResponse($this->externalManager->getOpenShares());
71
-	}
63
+    /**
64
+     * @NoAdminRequired
65
+     * @NoOutgoingFederatedSharingRequired
66
+     *
67
+     * @return JSONResponse
68
+     */
69
+    public function index() {
70
+        return new JSONResponse($this->externalManager->getOpenShares());
71
+    }
72 72
 
73
-	/**
74
-	 * @NoAdminRequired
75
-	 * @NoOutgoingFederatedSharingRequired
76
-	 *
77
-	 * @param int $id
78
-	 * @return JSONResponse
79
-	 */
80
-	public function create($id) {
81
-		$this->externalManager->acceptShare($id);
82
-		return new JSONResponse();
83
-	}
73
+    /**
74
+     * @NoAdminRequired
75
+     * @NoOutgoingFederatedSharingRequired
76
+     *
77
+     * @param int $id
78
+     * @return JSONResponse
79
+     */
80
+    public function create($id) {
81
+        $this->externalManager->acceptShare($id);
82
+        return new JSONResponse();
83
+    }
84 84
 
85
-	/**
86
-	 * @NoAdminRequired
87
-	 * @NoOutgoingFederatedSharingRequired
88
-	 *
89
-	 * @param integer $id
90
-	 * @return JSONResponse
91
-	 */
92
-	public function destroy($id) {
93
-		$this->externalManager->declineShare($id);
94
-		return new JSONResponse();
95
-	}
85
+    /**
86
+     * @NoAdminRequired
87
+     * @NoOutgoingFederatedSharingRequired
88
+     *
89
+     * @param integer $id
90
+     * @return JSONResponse
91
+     */
92
+    public function destroy($id) {
93
+        $this->externalManager->declineShare($id);
94
+        return new JSONResponse();
95
+    }
96 96
 
97
-	/**
98
-	 * Test whether the specified remote is accessible
99
-	 *
100
-	 * @param string $remote
101
-	 * @param bool $checkVersion
102
-	 * @return bool
103
-	 */
104
-	protected function testUrl($remote, $checkVersion = false) {
105
-		try {
106
-			$client = $this->clientService->newClient();
107
-			$response = json_decode($client->get(
108
-				$remote,
109
-				[
110
-					'timeout' => 3,
111
-					'connect_timeout' => 3,
112
-				]
113
-			)->getBody());
97
+    /**
98
+     * Test whether the specified remote is accessible
99
+     *
100
+     * @param string $remote
101
+     * @param bool $checkVersion
102
+     * @return bool
103
+     */
104
+    protected function testUrl($remote, $checkVersion = false) {
105
+        try {
106
+            $client = $this->clientService->newClient();
107
+            $response = json_decode($client->get(
108
+                $remote,
109
+                [
110
+                    'timeout' => 3,
111
+                    'connect_timeout' => 3,
112
+                ]
113
+            )->getBody());
114 114
 
115
-			if ($checkVersion) {
116
-				return !empty($response->version) && version_compare($response->version, '7.0.0', '>=');
117
-			} else {
118
-				return is_object($response);
119
-			}
120
-		} catch (\Exception $e) {
121
-			return false;
122
-		}
123
-	}
115
+            if ($checkVersion) {
116
+                return !empty($response->version) && version_compare($response->version, '7.0.0', '>=');
117
+            } else {
118
+                return is_object($response);
119
+            }
120
+        } catch (\Exception $e) {
121
+            return false;
122
+        }
123
+    }
124 124
 
125
-	/**
126
-	 * @PublicPage
127
-	 * @NoOutgoingFederatedSharingRequired
128
-	 * @NoIncomingFederatedSharingRequired
129
-	 *
130
-	 * @param string $remote
131
-	 * @return DataResponse
132
-	 */
133
-	public function testRemote($remote) {
134
-		if (strpos($remote, '#') !== false || strpos($remote, '?') !== false || strpos($remote, ';') !== false) {
135
-			return new DataResponse(false);
136
-		}
125
+    /**
126
+     * @PublicPage
127
+     * @NoOutgoingFederatedSharingRequired
128
+     * @NoIncomingFederatedSharingRequired
129
+     *
130
+     * @param string $remote
131
+     * @return DataResponse
132
+     */
133
+    public function testRemote($remote) {
134
+        if (strpos($remote, '#') !== false || strpos($remote, '?') !== false || strpos($remote, ';') !== false) {
135
+            return new DataResponse(false);
136
+        }
137 137
 
138
-		if (
139
-			$this->testUrl('https://' . $remote . '/ocs-provider/') ||
140
-			$this->testUrl('https://' . $remote . '/ocs-provider/index.php') ||
141
-			$this->testUrl('https://' . $remote . '/status.php', true)
142
-		) {
143
-			return new DataResponse('https');
144
-		} elseif (
145
-			$this->testUrl('http://' . $remote . '/ocs-provider/') ||
146
-			$this->testUrl('http://' . $remote . '/ocs-provider/index.php') ||
147
-			$this->testUrl('http://' . $remote . '/status.php', true)
148
-		) {
149
-			return new DataResponse('http');
150
-		} else {
151
-			return new DataResponse(false);
152
-		}
153
-	}
138
+        if (
139
+            $this->testUrl('https://' . $remote . '/ocs-provider/') ||
140
+            $this->testUrl('https://' . $remote . '/ocs-provider/index.php') ||
141
+            $this->testUrl('https://' . $remote . '/status.php', true)
142
+        ) {
143
+            return new DataResponse('https');
144
+        } elseif (
145
+            $this->testUrl('http://' . $remote . '/ocs-provider/') ||
146
+            $this->testUrl('http://' . $remote . '/ocs-provider/index.php') ||
147
+            $this->testUrl('http://' . $remote . '/status.php', true)
148
+        ) {
149
+            return new DataResponse('http');
150
+        } else {
151
+            return new DataResponse(false);
152
+        }
153
+    }
154 154
 }
Please login to merge, or discard this patch.
apps/contactsinteraction/lib/Migration/Version010000Date20200304152605.php 2 patches
Indentation   +54 added lines, -54 removed lines patch added patch discarded remove patch
@@ -33,61 +33,61 @@
 block discarded – undo
33 33
 
34 34
 class Version010000Date20200304152605 extends SimpleMigrationStep {
35 35
 
36
-	/**
37
-	 * @param IOutput $output
38
-	 * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
39
-	 * @param array $options
40
-	 *
41
-	 * @return ISchemaWrapper
42
-	 */
43
-	public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ISchemaWrapper {
44
-		/** @var ISchemaWrapper $schema */
45
-		$schema = $schemaClosure();
36
+    /**
37
+     * @param IOutput $output
38
+     * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
39
+     * @param array $options
40
+     *
41
+     * @return ISchemaWrapper
42
+     */
43
+    public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ISchemaWrapper {
44
+        /** @var ISchemaWrapper $schema */
45
+        $schema = $schemaClosure();
46 46
 
47
-		$table = $schema->createTable(RecentContactMapper::TABLE_NAME);
48
-		$table->addColumn('id', 'integer', [
49
-			'autoincrement' => true,
50
-			'notnull' => true,
51
-			'length' => 4,
52
-		]);
53
-		$table->addColumn('actor_uid', 'string', [
54
-			'notnull' => true,
55
-			'length' => 64,
56
-		]);
57
-		$table->addColumn('uid', 'string', [
58
-			'notnull' => false,
59
-			'length' => 64,
60
-		]);
61
-		$table->addColumn('email', 'string', [
62
-			'notnull' => false,
63
-			'length' => 255,
64
-		]);
65
-		$table->addColumn('federated_cloud_id', 'string', [
66
-			'notnull' => false,
67
-			'length' => 255,
68
-		]);
69
-		$table->addColumn('card', 'blob', [
70
-			'notnull' => true,
71
-		]);
72
-		$table->addColumn('last_contact', 'integer', [
73
-			'notnull' => true,
74
-			'length' => 4,
75
-		]);
76
-		$table->setPrimaryKey(['id']);
77
-		// To find all recent entries
78
-		$table->addIndex(['actor_uid'], RecentContactMapper::TABLE_NAME . '_actor_uid');
79
-		// To find a specific entry
80
-		$table->addIndex(['id', 'actor_uid'], RecentContactMapper::TABLE_NAME . '_id_uid');
81
-		// To find all recent entries with a given UID
82
-		$table->addIndex(['uid'], RecentContactMapper::TABLE_NAME . '_uid');
83
-		// To find all recent entries with a given email address
84
-		$table->addIndex(['email'], RecentContactMapper::TABLE_NAME . '_email');
85
-		// To find all recent entries with a give federated cloud id
86
-		$table->addIndex(['federated_cloud_id'], RecentContactMapper::TABLE_NAME . '_fed_id');
87
-		// For the cleanup
88
-		$table->addIndex(['last_contact'], RecentContactMapper::TABLE_NAME . '_last_contact');
47
+        $table = $schema->createTable(RecentContactMapper::TABLE_NAME);
48
+        $table->addColumn('id', 'integer', [
49
+            'autoincrement' => true,
50
+            'notnull' => true,
51
+            'length' => 4,
52
+        ]);
53
+        $table->addColumn('actor_uid', 'string', [
54
+            'notnull' => true,
55
+            'length' => 64,
56
+        ]);
57
+        $table->addColumn('uid', 'string', [
58
+            'notnull' => false,
59
+            'length' => 64,
60
+        ]);
61
+        $table->addColumn('email', 'string', [
62
+            'notnull' => false,
63
+            'length' => 255,
64
+        ]);
65
+        $table->addColumn('federated_cloud_id', 'string', [
66
+            'notnull' => false,
67
+            'length' => 255,
68
+        ]);
69
+        $table->addColumn('card', 'blob', [
70
+            'notnull' => true,
71
+        ]);
72
+        $table->addColumn('last_contact', 'integer', [
73
+            'notnull' => true,
74
+            'length' => 4,
75
+        ]);
76
+        $table->setPrimaryKey(['id']);
77
+        // To find all recent entries
78
+        $table->addIndex(['actor_uid'], RecentContactMapper::TABLE_NAME . '_actor_uid');
79
+        // To find a specific entry
80
+        $table->addIndex(['id', 'actor_uid'], RecentContactMapper::TABLE_NAME . '_id_uid');
81
+        // To find all recent entries with a given UID
82
+        $table->addIndex(['uid'], RecentContactMapper::TABLE_NAME . '_uid');
83
+        // To find all recent entries with a given email address
84
+        $table->addIndex(['email'], RecentContactMapper::TABLE_NAME . '_email');
85
+        // To find all recent entries with a give federated cloud id
86
+        $table->addIndex(['federated_cloud_id'], RecentContactMapper::TABLE_NAME . '_fed_id');
87
+        // For the cleanup
88
+        $table->addIndex(['last_contact'], RecentContactMapper::TABLE_NAME . '_last_contact');
89 89
 
90
-		return $schema;
91
-	}
90
+        return $schema;
91
+    }
92 92
 
93 93
 }
Please login to merge, or discard this patch.
Spacing   +6 added lines, -6 removed lines patch added patch discarded remove patch
@@ -75,17 +75,17 @@
 block discarded – undo
75 75
 		]);
76 76
 		$table->setPrimaryKey(['id']);
77 77
 		// To find all recent entries
78
-		$table->addIndex(['actor_uid'], RecentContactMapper::TABLE_NAME . '_actor_uid');
78
+		$table->addIndex(['actor_uid'], RecentContactMapper::TABLE_NAME.'_actor_uid');
79 79
 		// To find a specific entry
80
-		$table->addIndex(['id', 'actor_uid'], RecentContactMapper::TABLE_NAME . '_id_uid');
80
+		$table->addIndex(['id', 'actor_uid'], RecentContactMapper::TABLE_NAME.'_id_uid');
81 81
 		// To find all recent entries with a given UID
82
-		$table->addIndex(['uid'], RecentContactMapper::TABLE_NAME . '_uid');
82
+		$table->addIndex(['uid'], RecentContactMapper::TABLE_NAME.'_uid');
83 83
 		// To find all recent entries with a given email address
84
-		$table->addIndex(['email'], RecentContactMapper::TABLE_NAME . '_email');
84
+		$table->addIndex(['email'], RecentContactMapper::TABLE_NAME.'_email');
85 85
 		// To find all recent entries with a give federated cloud id
86
-		$table->addIndex(['federated_cloud_id'], RecentContactMapper::TABLE_NAME . '_fed_id');
86
+		$table->addIndex(['federated_cloud_id'], RecentContactMapper::TABLE_NAME.'_fed_id');
87 87
 		// For the cleanup
88
-		$table->addIndex(['last_contact'], RecentContactMapper::TABLE_NAME . '_last_contact');
88
+		$table->addIndex(['last_contact'], RecentContactMapper::TABLE_NAME.'_last_contact');
89 89
 
90 90
 		return $schema;
91 91
 	}
Please login to merge, or discard this patch.
apps/contactsinteraction/lib/Db/CardSearchDao.php 2 patches
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -67,7 +67,7 @@
 block discarded – undo
67 67
 		}
68 68
 		$addressbooksQuery->selectDistinct('id')
69 69
 			->from('addressbooks')
70
-			->where($addressbooksQuery->expr()->eq('principaluri', $cardQuery->createNamedParameter("principals/users/" . $user->getUID())));
70
+			->where($addressbooksQuery->expr()->eq('principaluri', $cardQuery->createNamedParameter("principals/users/".$user->getUID())));
71 71
 		$propQuery->selectDistinct('cardid')
72 72
 			->from('cards_properties')
73 73
 			->where($propQuery->expr()->in('addressbookid', $propQuery->createFunction($addressbooksQuery->getSQL()), IQueryBuilder::PARAM_INT_ARRAY))
Please login to merge, or discard this patch.
Indentation   +55 added lines, -55 removed lines patch added patch discarded remove patch
@@ -33,64 +33,64 @@
 block discarded – undo
33 33
 
34 34
 class CardSearchDao {
35 35
 
36
-	/** @var IDBConnection */
37
-	private $db;
36
+    /** @var IDBConnection */
37
+    private $db;
38 38
 
39
-	public function __construct(IDBConnection $db) {
40
-		$this->db = $db;
41
-	}
39
+    public function __construct(IDBConnection $db) {
40
+        $this->db = $db;
41
+    }
42 42
 
43
-	public function findExisting(IUser $user,
44
-								 ?string $uid,
45
-								 ?string $email,
46
-								 ?string $cloudId): ?string {
47
-		$addressbooksQuery = $this->db->getQueryBuilder();
48
-		$cardQuery = $this->db->getQueryBuilder();
49
-		$propQuery = $this->db->getQueryBuilder();
43
+    public function findExisting(IUser $user,
44
+                                 ?string $uid,
45
+                                 ?string $email,
46
+                                 ?string $cloudId): ?string {
47
+        $addressbooksQuery = $this->db->getQueryBuilder();
48
+        $cardQuery = $this->db->getQueryBuilder();
49
+        $propQuery = $this->db->getQueryBuilder();
50 50
 
51
-		$propOr = $propQuery->expr()->orX();
52
-		if ($uid !== null) {
53
-			$propOr->add($propQuery->expr()->andX(
54
-				$propQuery->expr()->eq('name', $cardQuery->createNamedParameter('UID')),
55
-				$propQuery->expr()->eq('value', $cardQuery->createNamedParameter($uid))
56
-			));
57
-		}
58
-		if ($email !== null) {
59
-			$propOr->add($propQuery->expr()->andX(
60
-				$propQuery->expr()->eq('name', $cardQuery->createNamedParameter('EMAIL')),
61
-				$propQuery->expr()->eq('value', $cardQuery->createNamedParameter($email))
62
-			));
63
-		}
64
-		if ($cloudId !== null) {
65
-			$propOr->add($propQuery->expr()->andX(
66
-				$propQuery->expr()->eq('name', $cardQuery->createNamedParameter('CLOUD')),
67
-				$propQuery->expr()->eq('value', $cardQuery->createNamedParameter($cloudId))
68
-			));
69
-		}
70
-		$addressbooksQuery->selectDistinct('id')
71
-			->from('addressbooks')
72
-			->where($addressbooksQuery->expr()->eq('principaluri', $cardQuery->createNamedParameter("principals/users/" . $user->getUID())));
73
-		$propQuery->selectDistinct('cardid')
74
-			->from('cards_properties')
75
-			->where($propQuery->expr()->in('addressbookid', $propQuery->createFunction($addressbooksQuery->getSQL()), IQueryBuilder::PARAM_INT_ARRAY))
76
-			->andWhere($propOr)
77
-			->groupBy('cardid');
78
-		$cardQuery->select('carddata')
79
-			->from('cards')
80
-			->where($cardQuery->expr()->in('id', $cardQuery->createFunction($propQuery->getSQL()), IQueryBuilder::PARAM_INT_ARRAY))
81
-			->andWhere($cardQuery->expr()->in('addressbookid', $cardQuery->createFunction($addressbooksQuery->getSQL()), IQueryBuilder::PARAM_INT_ARRAY))
82
-			->setMaxResults(1);
83
-		$result = $cardQuery->execute();
84
-		/** @var string|resource|false $card */
85
-		$card = $result->fetchOne();
51
+        $propOr = $propQuery->expr()->orX();
52
+        if ($uid !== null) {
53
+            $propOr->add($propQuery->expr()->andX(
54
+                $propQuery->expr()->eq('name', $cardQuery->createNamedParameter('UID')),
55
+                $propQuery->expr()->eq('value', $cardQuery->createNamedParameter($uid))
56
+            ));
57
+        }
58
+        if ($email !== null) {
59
+            $propOr->add($propQuery->expr()->andX(
60
+                $propQuery->expr()->eq('name', $cardQuery->createNamedParameter('EMAIL')),
61
+                $propQuery->expr()->eq('value', $cardQuery->createNamedParameter($email))
62
+            ));
63
+        }
64
+        if ($cloudId !== null) {
65
+            $propOr->add($propQuery->expr()->andX(
66
+                $propQuery->expr()->eq('name', $cardQuery->createNamedParameter('CLOUD')),
67
+                $propQuery->expr()->eq('value', $cardQuery->createNamedParameter($cloudId))
68
+            ));
69
+        }
70
+        $addressbooksQuery->selectDistinct('id')
71
+            ->from('addressbooks')
72
+            ->where($addressbooksQuery->expr()->eq('principaluri', $cardQuery->createNamedParameter("principals/users/" . $user->getUID())));
73
+        $propQuery->selectDistinct('cardid')
74
+            ->from('cards_properties')
75
+            ->where($propQuery->expr()->in('addressbookid', $propQuery->createFunction($addressbooksQuery->getSQL()), IQueryBuilder::PARAM_INT_ARRAY))
76
+            ->andWhere($propOr)
77
+            ->groupBy('cardid');
78
+        $cardQuery->select('carddata')
79
+            ->from('cards')
80
+            ->where($cardQuery->expr()->in('id', $cardQuery->createFunction($propQuery->getSQL()), IQueryBuilder::PARAM_INT_ARRAY))
81
+            ->andWhere($cardQuery->expr()->in('addressbookid', $cardQuery->createFunction($addressbooksQuery->getSQL()), IQueryBuilder::PARAM_INT_ARRAY))
82
+            ->setMaxResults(1);
83
+        $result = $cardQuery->execute();
84
+        /** @var string|resource|false $card */
85
+        $card = $result->fetchOne();
86 86
 
87
-		if ($card === false) {
88
-			return null;
89
-		}
90
-		if (is_resource($card)) {
91
-			return stream_get_contents($card);
92
-		}
87
+        if ($card === false) {
88
+            return null;
89
+        }
90
+        if (is_resource($card)) {
91
+            return stream_get_contents($card);
92
+        }
93 93
 
94
-		return $card;
95
-	}
94
+        return $card;
95
+    }
96 96
 }
Please login to merge, or discard this patch.