Passed
Push — master ( 4a52d9...223a91 )
by Morris
11:47 queued 10s
created
apps/dav/lib/CalDAV/Search/Xml/Filter/CompFilter.php 2 patches
Indentation   +14 added lines, -14 removed lines patch added patch discarded remove patch
@@ -27,21 +27,21 @@
 block discarded – undo
27 27
 
28 28
 class CompFilter implements XmlDeserializable {
29 29
 
30
-	/**
31
-	 * @param Reader $reader
32
-	 * @throws BadRequest
33
-	 * @return string
34
-	 */
35
-	static function xmlDeserialize(Reader $reader) {
36
-		$att = $reader->parseAttributes();
37
-		$componentName = $att['name'];
30
+    /**
31
+     * @param Reader $reader
32
+     * @throws BadRequest
33
+     * @return string
34
+     */
35
+    static function xmlDeserialize(Reader $reader) {
36
+        $att = $reader->parseAttributes();
37
+        $componentName = $att['name'];
38 38
 
39
-		$reader->parseInnerTree();
39
+        $reader->parseInnerTree();
40 40
 
41
-		if (!is_string($componentName)) {
42
-			throw new BadRequest('The {' . SearchPlugin::NS_Nextcloud . '}comp-filter requires a valid name attribute');
43
-		}
41
+        if (!is_string($componentName)) {
42
+            throw new BadRequest('The {' . SearchPlugin::NS_Nextcloud . '}comp-filter requires a valid name attribute');
43
+        }
44 44
 
45
-		return $componentName;
46
-	}
45
+        return $componentName;
46
+    }
47 47
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -39,7 +39,7 @@
 block discarded – undo
39 39
 		$reader->parseInnerTree();
40 40
 
41 41
 		if (!is_string($componentName)) {
42
-			throw new BadRequest('The {' . SearchPlugin::NS_Nextcloud . '}comp-filter requires a valid name attribute');
42
+			throw new BadRequest('The {'.SearchPlugin::NS_Nextcloud.'}comp-filter requires a valid name attribute');
43 43
 		}
44 44
 
45 45
 		return $componentName;
Please login to merge, or discard this patch.
apps/dav/lib/CalDAV/Search/Xml/Filter/SearchTermFilter.php 2 patches
Indentation   +12 added lines, -12 removed lines patch added patch discarded remove patch
@@ -27,17 +27,17 @@
 block discarded – undo
27 27
 
28 28
 class SearchTermFilter implements XmlDeserializable {
29 29
 
30
-	/**
31
-	 * @param Reader $reader
32
-	 * @throws BadRequest
33
-	 * @return string
34
-	 */
35
-	static function xmlDeserialize(Reader $reader) {
36
-		$value = $reader->parseInnerTree();
37
-		if (!is_string($value)) {
38
-			throw new BadRequest('The {' . SearchPlugin::NS_Nextcloud . '}search-term has illegal value');
39
-		}
30
+    /**
31
+     * @param Reader $reader
32
+     * @throws BadRequest
33
+     * @return string
34
+     */
35
+    static function xmlDeserialize(Reader $reader) {
36
+        $value = $reader->parseInnerTree();
37
+        if (!is_string($value)) {
38
+            throw new BadRequest('The {' . SearchPlugin::NS_Nextcloud . '}search-term has illegal value');
39
+        }
40 40
 
41
-		return $value;
42
-	}
41
+        return $value;
42
+    }
43 43
 }
44 44
\ No newline at end of file
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -35,7 +35,7 @@
 block discarded – undo
35 35
 	static function xmlDeserialize(Reader $reader) {
36 36
 		$value = $reader->parseInnerTree();
37 37
 		if (!is_string($value)) {
38
-			throw new BadRequest('The {' . SearchPlugin::NS_Nextcloud . '}search-term has illegal value');
38
+			throw new BadRequest('The {'.SearchPlugin::NS_Nextcloud.'}search-term has illegal value');
39 39
 		}
40 40
 
41 41
 		return $value;
Please login to merge, or discard this patch.
apps/dav/lib/CalDAV/Search/Xml/Filter/PropFilter.php 2 patches
Indentation   +14 added lines, -14 removed lines patch added patch discarded remove patch
@@ -27,21 +27,21 @@
 block discarded – undo
27 27
 
28 28
 class PropFilter implements XmlDeserializable {
29 29
 
30
-	/**
31
-	 * @param Reader $reader
32
-	 * @throws BadRequest
33
-	 * @return string
34
-	 */
35
-	static function xmlDeserialize(Reader $reader) {
36
-		$att = $reader->parseAttributes();
37
-		$componentName = $att['name'];
30
+    /**
31
+     * @param Reader $reader
32
+     * @throws BadRequest
33
+     * @return string
34
+     */
35
+    static function xmlDeserialize(Reader $reader) {
36
+        $att = $reader->parseAttributes();
37
+        $componentName = $att['name'];
38 38
 
39
-		$reader->parseInnerTree();
39
+        $reader->parseInnerTree();
40 40
 
41
-		if (!is_string($componentName)) {
42
-			throw new BadRequest('The {' . SearchPlugin::NS_Nextcloud . '}prop-filter requires a valid name attribute');
43
-		}
41
+        if (!is_string($componentName)) {
42
+            throw new BadRequest('The {' . SearchPlugin::NS_Nextcloud . '}prop-filter requires a valid name attribute');
43
+        }
44 44
 
45
-		return $componentName;
46
-	}
45
+        return $componentName;
46
+    }
47 47
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -39,7 +39,7 @@
 block discarded – undo
39 39
 		$reader->parseInnerTree();
40 40
 
41 41
 		if (!is_string($componentName)) {
42
-			throw new BadRequest('The {' . SearchPlugin::NS_Nextcloud . '}prop-filter requires a valid name attribute');
42
+			throw new BadRequest('The {'.SearchPlugin::NS_Nextcloud.'}prop-filter requires a valid name attribute');
43 43
 		}
44 44
 
45 45
 		return $componentName;
Please login to merge, or discard this patch.
apps/dav/lib/CalDAV/Search/Xml/Filter/ParamFilter.php 2 patches
Indentation   +21 added lines, -21 removed lines patch added patch discarded remove patch
@@ -27,29 +27,29 @@
 block discarded – undo
27 27
 
28 28
 class ParamFilter implements XmlDeserializable {
29 29
 
30
-	/**
31
-	 * @param Reader $reader
32
-	 * @throws BadRequest
33
-	 * @return string
34
-	 */
35
-	static function xmlDeserialize(Reader $reader) {
36
-		$att = $reader->parseAttributes();
37
-		$property = $att['property'];
38
-		$parameter = $att['name'];
30
+    /**
31
+     * @param Reader $reader
32
+     * @throws BadRequest
33
+     * @return string
34
+     */
35
+    static function xmlDeserialize(Reader $reader) {
36
+        $att = $reader->parseAttributes();
37
+        $property = $att['property'];
38
+        $parameter = $att['name'];
39 39
 
40
-		$reader->parseInnerTree();
40
+        $reader->parseInnerTree();
41 41
 
42
-		if (!is_string($property)) {
43
-			throw new BadRequest('The {' . SearchPlugin::NS_Nextcloud . '}param-filter requires a valid property attribute');
42
+        if (!is_string($property)) {
43
+            throw new BadRequest('The {' . SearchPlugin::NS_Nextcloud . '}param-filter requires a valid property attribute');
44 44
 
45
-		}
46
-		if (!is_string($parameter)) {
47
-			throw new BadRequest('The {' . SearchPlugin::NS_Nextcloud . '}param-filter requires a valid parameter attribute');
48
-		}
45
+        }
46
+        if (!is_string($parameter)) {
47
+            throw new BadRequest('The {' . SearchPlugin::NS_Nextcloud . '}param-filter requires a valid parameter attribute');
48
+        }
49 49
 
50
-		return [
51
-			'property' => $property,
52
-			'parameter' => $parameter,
53
-		];
54
-	}
50
+        return [
51
+            'property' => $property,
52
+            'parameter' => $parameter,
53
+        ];
54
+    }
55 55
 }
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -40,11 +40,11 @@
 block discarded – undo
40 40
 		$reader->parseInnerTree();
41 41
 
42 42
 		if (!is_string($property)) {
43
-			throw new BadRequest('The {' . SearchPlugin::NS_Nextcloud . '}param-filter requires a valid property attribute');
43
+			throw new BadRequest('The {'.SearchPlugin::NS_Nextcloud.'}param-filter requires a valid property attribute');
44 44
 
45 45
 		}
46 46
 		if (!is_string($parameter)) {
47
-			throw new BadRequest('The {' . SearchPlugin::NS_Nextcloud . '}param-filter requires a valid parameter attribute');
47
+			throw new BadRequest('The {'.SearchPlugin::NS_Nextcloud.'}param-filter requires a valid parameter attribute');
48 48
 		}
49 49
 
50 50
 		return [
Please login to merge, or discard this patch.
apps/dav/lib/DAV/CustomPropertiesBackend.php 2 patches
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -151,7 +151,7 @@  discard block
 block discarded – undo
151 151
 	 */
152 152
 	public function move($source, $destination) {
153 153
 		$statement = $this->connection->prepare(
154
-			'UPDATE `*PREFIX*properties` SET `propertypath` = ?' .
154
+			'UPDATE `*PREFIX*properties` SET `propertypath` = ?'.
155 155
 			' WHERE `userid` = ? AND `propertypath` = ?'
156 156
 		);
157 157
 		$statement->execute(array($destination, $this->user, $source));
@@ -213,13 +213,13 @@  discard block
 block discarded – undo
213 213
 	 */
214 214
 	private function updateProperties($path, $properties) {
215 215
 
216
-		$deleteStatement = 'DELETE FROM `*PREFIX*properties`' .
216
+		$deleteStatement = 'DELETE FROM `*PREFIX*properties`'.
217 217
 			' WHERE `userid` = ? AND `propertypath` = ? AND `propertyname` = ?';
218 218
 
219
-		$insertStatement = 'INSERT INTO `*PREFIX*properties`' .
219
+		$insertStatement = 'INSERT INTO `*PREFIX*properties`'.
220 220
 			' (`userid`,`propertypath`,`propertyname`,`propertyvalue`) VALUES(?,?,?,?)';
221 221
 
222
-		$updateStatement = 'UPDATE `*PREFIX*properties` SET `propertyvalue` = ?' .
222
+		$updateStatement = 'UPDATE `*PREFIX*properties` SET `propertyvalue` = ?'.
223 223
 			' WHERE `userid` = ? AND `propertypath` = ? AND `propertyname` = ?';
224 224
 
225 225
 		// TODO: use "insert or update" strategy ?
Please login to merge, or discard this patch.
Indentation   +254 added lines, -254 removed lines patch added patch discarded remove patch
@@ -34,259 +34,259 @@
 block discarded – undo
34 34
 
35 35
 class CustomPropertiesBackend implements BackendInterface {
36 36
 
37
-	/**
38
-	 * Ignored properties
39
-	 *
40
-	 * @var array
41
-	 */
42
-	private $ignoredProperties = array(
43
-		'{DAV:}getcontentlength',
44
-		'{DAV:}getcontenttype',
45
-		'{DAV:}getetag',
46
-		'{DAV:}quota-used-bytes',
47
-		'{DAV:}quota-available-bytes',
48
-		'{http://owncloud.org/ns}permissions',
49
-		'{http://owncloud.org/ns}downloadURL',
50
-		'{http://owncloud.org/ns}dDC',
51
-		'{http://owncloud.org/ns}size',
52
-		'{http://nextcloud.org/ns}is-encrypted',
53
-	);
54
-
55
-	/**
56
-	 * @var Tree
57
-	 */
58
-	private $tree;
59
-
60
-	/**
61
-	 * @var IDBConnection
62
-	 */
63
-	private $connection;
64
-
65
-	/**
66
-	 * @var string
67
-	 */
68
-	private $user;
69
-
70
-	/**
71
-	 * Properties cache
72
-	 *
73
-	 * @var array
74
-	 */
75
-	private $cache = [];
76
-
77
-	/**
78
-	 * @param Tree $tree node tree
79
-	 * @param IDBConnection $connection database connection
80
-	 * @param IUser $user owner of the tree and properties
81
-	 */
82
-	public function __construct(
83
-		Tree $tree,
84
-		IDBConnection $connection,
85
-		IUser $user) {
86
-		$this->tree = $tree;
87
-		$this->connection = $connection;
88
-		$this->user = $user->getUID();
89
-	}
90
-
91
-	/**
92
-	 * Fetches properties for a path.
93
-	 *
94
-	 * @param string $path
95
-	 * @param PropFind $propFind
96
-	 * @return void
97
-	 */
98
-	public function propFind($path, PropFind $propFind) {
99
-
100
-		$requestedProps = $propFind->get404Properties();
101
-
102
-		// these might appear
103
-		$requestedProps = array_diff(
104
-			$requestedProps,
105
-			$this->ignoredProperties
106
-		);
107
-
108
-		// substr of calendars/ => path is inside the CalDAV component
109
-		// two '/' => this a calendar (no calendar-home nor calendar object)
110
-		if (substr($path, 0, 10) === 'calendars/' && substr_count($path, '/') === 2) {
111
-			$allRequestedProps = $propFind->getRequestedProperties();
112
-			$customPropertiesForShares = [
113
-				'{DAV:}displayname',
114
-				'{urn:ietf:params:xml:ns:caldav}calendar-description',
115
-				'{urn:ietf:params:xml:ns:caldav}calendar-timezone',
116
-				'{http://apple.com/ns/ical/}calendar-order',
117
-				'{http://apple.com/ns/ical/}calendar-color',
118
-				'{urn:ietf:params:xml:ns:caldav}schedule-calendar-transp',
119
-			];
120
-
121
-			foreach ($customPropertiesForShares as $customPropertyForShares) {
122
-				if (in_array($customPropertyForShares, $allRequestedProps)) {
123
-					$requestedProps[] = $customPropertyForShares;
124
-				}
125
-			}
126
-		}
127
-
128
-		if (empty($requestedProps)) {
129
-			return;
130
-		}
131
-
132
-		$props = $this->getProperties($path, $requestedProps);
133
-		foreach ($props as $propName => $propValue) {
134
-			$propFind->set($propName, $propValue);
135
-		}
136
-	}
137
-
138
-	/**
139
-	 * Updates properties for a path
140
-	 *
141
-	 * @param string $path
142
-	 * @param PropPatch $propPatch
143
-	 *
144
-	 * @return void
145
-	 */
146
-	public function propPatch($path, PropPatch $propPatch) {
147
-		$propPatch->handleRemaining(function($changedProps) use ($path) {
148
-			return $this->updateProperties($path, $changedProps);
149
-		});
150
-	}
151
-
152
-	/**
153
-	 * This method is called after a node is deleted.
154
-	 *
155
-	 * @param string $path path of node for which to delete properties
156
-	 */
157
-	public function delete($path) {
158
-		$statement = $this->connection->prepare(
159
-			'DELETE FROM `*PREFIX*properties` WHERE `userid` = ? AND `propertypath` = ?'
160
-		);
161
-		$statement->execute(array($this->user, $path));
162
-		$statement->closeCursor();
163
-
164
-		unset($this->cache[$path]);
165
-	}
166
-
167
-	/**
168
-	 * This method is called after a successful MOVE
169
-	 *
170
-	 * @param string $source
171
-	 * @param string $destination
172
-	 *
173
-	 * @return void
174
-	 */
175
-	public function move($source, $destination) {
176
-		$statement = $this->connection->prepare(
177
-			'UPDATE `*PREFIX*properties` SET `propertypath` = ?' .
178
-			' WHERE `userid` = ? AND `propertypath` = ?'
179
-		);
180
-		$statement->execute(array($destination, $this->user, $source));
181
-		$statement->closeCursor();
182
-	}
183
-
184
-	/**
185
-	 * Returns a list of properties for this nodes.;
186
-	 * @param string $path
187
-	 * @param array $requestedProperties requested properties or empty array for "all"
188
-	 * @return array
189
-	 * @note The properties list is a list of propertynames the client
190
-	 * requested, encoded as xmlnamespace#tagName, for example:
191
-	 * http://www.example.org/namespace#author If the array is empty, all
192
-	 * properties should be returned
193
-	 */
194
-	private function getProperties($path, array $requestedProperties) {
195
-		if (isset($this->cache[$path])) {
196
-			return $this->cache[$path];
197
-		}
198
-
199
-		// TODO: chunking if more than 1000 properties
200
-		$sql = 'SELECT * FROM `*PREFIX*properties` WHERE `userid` = ? AND `propertypath` = ?';
201
-
202
-		$whereValues = array($this->user, $path);
203
-		$whereTypes = array(null, null);
204
-
205
-		if (!empty($requestedProperties)) {
206
-			// request only a subset
207
-			$sql .= ' AND `propertyname` in (?)';
208
-			$whereValues[] = $requestedProperties;
209
-			$whereTypes[] = \Doctrine\DBAL\Connection::PARAM_STR_ARRAY;
210
-		}
211
-
212
-		$result = $this->connection->executeQuery(
213
-			$sql,
214
-			$whereValues,
215
-			$whereTypes
216
-		);
217
-
218
-		$props = [];
219
-		while ($row = $result->fetch()) {
220
-			$props[$row['propertyname']] = $row['propertyvalue'];
221
-		}
222
-
223
-		$result->closeCursor();
224
-
225
-		$this->cache[$path] = $props;
226
-		return $props;
227
-	}
228
-
229
-	/**
230
-	 * Update properties
231
-	 *
232
-	 * @param string $path node for which to update properties
233
-	 * @param array $properties array of properties to update
234
-	 *
235
-	 * @return bool
236
-	 */
237
-	private function updateProperties($path, $properties) {
238
-
239
-		$deleteStatement = 'DELETE FROM `*PREFIX*properties`' .
240
-			' WHERE `userid` = ? AND `propertypath` = ? AND `propertyname` = ?';
241
-
242
-		$insertStatement = 'INSERT INTO `*PREFIX*properties`' .
243
-			' (`userid`,`propertypath`,`propertyname`,`propertyvalue`) VALUES(?,?,?,?)';
244
-
245
-		$updateStatement = 'UPDATE `*PREFIX*properties` SET `propertyvalue` = ?' .
246
-			' WHERE `userid` = ? AND `propertypath` = ? AND `propertyname` = ?';
247
-
248
-		// TODO: use "insert or update" strategy ?
249
-		$existing = $this->getProperties($path, array());
250
-		$this->connection->beginTransaction();
251
-		foreach ($properties as $propertyName => $propertyValue) {
252
-			// If it was null, we need to delete the property
253
-			if (is_null($propertyValue)) {
254
-				if (array_key_exists($propertyName, $existing)) {
255
-					$this->connection->executeUpdate($deleteStatement,
256
-						array(
257
-							$this->user,
258
-							$path,
259
-							$propertyName
260
-						)
261
-					);
262
-				}
263
-			} else {
264
-				if (!array_key_exists($propertyName, $existing)) {
265
-					$this->connection->executeUpdate($insertStatement,
266
-						array(
267
-							$this->user,
268
-							$path,
269
-							$propertyName,
270
-							$propertyValue
271
-						)
272
-					);
273
-				} else {
274
-					$this->connection->executeUpdate($updateStatement,
275
-						array(
276
-							$propertyValue,
277
-							$this->user,
278
-							$path,
279
-							$propertyName
280
-						)
281
-					);
282
-				}
283
-			}
284
-		}
285
-
286
-		$this->connection->commit();
287
-		unset($this->cache[$path]);
288
-
289
-		return true;
290
-	}
37
+    /**
38
+     * Ignored properties
39
+     *
40
+     * @var array
41
+     */
42
+    private $ignoredProperties = array(
43
+        '{DAV:}getcontentlength',
44
+        '{DAV:}getcontenttype',
45
+        '{DAV:}getetag',
46
+        '{DAV:}quota-used-bytes',
47
+        '{DAV:}quota-available-bytes',
48
+        '{http://owncloud.org/ns}permissions',
49
+        '{http://owncloud.org/ns}downloadURL',
50
+        '{http://owncloud.org/ns}dDC',
51
+        '{http://owncloud.org/ns}size',
52
+        '{http://nextcloud.org/ns}is-encrypted',
53
+    );
54
+
55
+    /**
56
+     * @var Tree
57
+     */
58
+    private $tree;
59
+
60
+    /**
61
+     * @var IDBConnection
62
+     */
63
+    private $connection;
64
+
65
+    /**
66
+     * @var string
67
+     */
68
+    private $user;
69
+
70
+    /**
71
+     * Properties cache
72
+     *
73
+     * @var array
74
+     */
75
+    private $cache = [];
76
+
77
+    /**
78
+     * @param Tree $tree node tree
79
+     * @param IDBConnection $connection database connection
80
+     * @param IUser $user owner of the tree and properties
81
+     */
82
+    public function __construct(
83
+        Tree $tree,
84
+        IDBConnection $connection,
85
+        IUser $user) {
86
+        $this->tree = $tree;
87
+        $this->connection = $connection;
88
+        $this->user = $user->getUID();
89
+    }
90
+
91
+    /**
92
+     * Fetches properties for a path.
93
+     *
94
+     * @param string $path
95
+     * @param PropFind $propFind
96
+     * @return void
97
+     */
98
+    public function propFind($path, PropFind $propFind) {
99
+
100
+        $requestedProps = $propFind->get404Properties();
101
+
102
+        // these might appear
103
+        $requestedProps = array_diff(
104
+            $requestedProps,
105
+            $this->ignoredProperties
106
+        );
107
+
108
+        // substr of calendars/ => path is inside the CalDAV component
109
+        // two '/' => this a calendar (no calendar-home nor calendar object)
110
+        if (substr($path, 0, 10) === 'calendars/' && substr_count($path, '/') === 2) {
111
+            $allRequestedProps = $propFind->getRequestedProperties();
112
+            $customPropertiesForShares = [
113
+                '{DAV:}displayname',
114
+                '{urn:ietf:params:xml:ns:caldav}calendar-description',
115
+                '{urn:ietf:params:xml:ns:caldav}calendar-timezone',
116
+                '{http://apple.com/ns/ical/}calendar-order',
117
+                '{http://apple.com/ns/ical/}calendar-color',
118
+                '{urn:ietf:params:xml:ns:caldav}schedule-calendar-transp',
119
+            ];
120
+
121
+            foreach ($customPropertiesForShares as $customPropertyForShares) {
122
+                if (in_array($customPropertyForShares, $allRequestedProps)) {
123
+                    $requestedProps[] = $customPropertyForShares;
124
+                }
125
+            }
126
+        }
127
+
128
+        if (empty($requestedProps)) {
129
+            return;
130
+        }
131
+
132
+        $props = $this->getProperties($path, $requestedProps);
133
+        foreach ($props as $propName => $propValue) {
134
+            $propFind->set($propName, $propValue);
135
+        }
136
+    }
137
+
138
+    /**
139
+     * Updates properties for a path
140
+     *
141
+     * @param string $path
142
+     * @param PropPatch $propPatch
143
+     *
144
+     * @return void
145
+     */
146
+    public function propPatch($path, PropPatch $propPatch) {
147
+        $propPatch->handleRemaining(function($changedProps) use ($path) {
148
+            return $this->updateProperties($path, $changedProps);
149
+        });
150
+    }
151
+
152
+    /**
153
+     * This method is called after a node is deleted.
154
+     *
155
+     * @param string $path path of node for which to delete properties
156
+     */
157
+    public function delete($path) {
158
+        $statement = $this->connection->prepare(
159
+            'DELETE FROM `*PREFIX*properties` WHERE `userid` = ? AND `propertypath` = ?'
160
+        );
161
+        $statement->execute(array($this->user, $path));
162
+        $statement->closeCursor();
163
+
164
+        unset($this->cache[$path]);
165
+    }
166
+
167
+    /**
168
+     * This method is called after a successful MOVE
169
+     *
170
+     * @param string $source
171
+     * @param string $destination
172
+     *
173
+     * @return void
174
+     */
175
+    public function move($source, $destination) {
176
+        $statement = $this->connection->prepare(
177
+            'UPDATE `*PREFIX*properties` SET `propertypath` = ?' .
178
+            ' WHERE `userid` = ? AND `propertypath` = ?'
179
+        );
180
+        $statement->execute(array($destination, $this->user, $source));
181
+        $statement->closeCursor();
182
+    }
183
+
184
+    /**
185
+     * Returns a list of properties for this nodes.;
186
+     * @param string $path
187
+     * @param array $requestedProperties requested properties or empty array for "all"
188
+     * @return array
189
+     * @note The properties list is a list of propertynames the client
190
+     * requested, encoded as xmlnamespace#tagName, for example:
191
+     * http://www.example.org/namespace#author If the array is empty, all
192
+     * properties should be returned
193
+     */
194
+    private function getProperties($path, array $requestedProperties) {
195
+        if (isset($this->cache[$path])) {
196
+            return $this->cache[$path];
197
+        }
198
+
199
+        // TODO: chunking if more than 1000 properties
200
+        $sql = 'SELECT * FROM `*PREFIX*properties` WHERE `userid` = ? AND `propertypath` = ?';
201
+
202
+        $whereValues = array($this->user, $path);
203
+        $whereTypes = array(null, null);
204
+
205
+        if (!empty($requestedProperties)) {
206
+            // request only a subset
207
+            $sql .= ' AND `propertyname` in (?)';
208
+            $whereValues[] = $requestedProperties;
209
+            $whereTypes[] = \Doctrine\DBAL\Connection::PARAM_STR_ARRAY;
210
+        }
211
+
212
+        $result = $this->connection->executeQuery(
213
+            $sql,
214
+            $whereValues,
215
+            $whereTypes
216
+        );
217
+
218
+        $props = [];
219
+        while ($row = $result->fetch()) {
220
+            $props[$row['propertyname']] = $row['propertyvalue'];
221
+        }
222
+
223
+        $result->closeCursor();
224
+
225
+        $this->cache[$path] = $props;
226
+        return $props;
227
+    }
228
+
229
+    /**
230
+     * Update properties
231
+     *
232
+     * @param string $path node for which to update properties
233
+     * @param array $properties array of properties to update
234
+     *
235
+     * @return bool
236
+     */
237
+    private function updateProperties($path, $properties) {
238
+
239
+        $deleteStatement = 'DELETE FROM `*PREFIX*properties`' .
240
+            ' WHERE `userid` = ? AND `propertypath` = ? AND `propertyname` = ?';
241
+
242
+        $insertStatement = 'INSERT INTO `*PREFIX*properties`' .
243
+            ' (`userid`,`propertypath`,`propertyname`,`propertyvalue`) VALUES(?,?,?,?)';
244
+
245
+        $updateStatement = 'UPDATE `*PREFIX*properties` SET `propertyvalue` = ?' .
246
+            ' WHERE `userid` = ? AND `propertypath` = ? AND `propertyname` = ?';
247
+
248
+        // TODO: use "insert or update" strategy ?
249
+        $existing = $this->getProperties($path, array());
250
+        $this->connection->beginTransaction();
251
+        foreach ($properties as $propertyName => $propertyValue) {
252
+            // If it was null, we need to delete the property
253
+            if (is_null($propertyValue)) {
254
+                if (array_key_exists($propertyName, $existing)) {
255
+                    $this->connection->executeUpdate($deleteStatement,
256
+                        array(
257
+                            $this->user,
258
+                            $path,
259
+                            $propertyName
260
+                        )
261
+                    );
262
+                }
263
+            } else {
264
+                if (!array_key_exists($propertyName, $existing)) {
265
+                    $this->connection->executeUpdate($insertStatement,
266
+                        array(
267
+                            $this->user,
268
+                            $path,
269
+                            $propertyName,
270
+                            $propertyValue
271
+                        )
272
+                    );
273
+                } else {
274
+                    $this->connection->executeUpdate($updateStatement,
275
+                        array(
276
+                            $propertyValue,
277
+                            $this->user,
278
+                            $path,
279
+                            $propertyName
280
+                        )
281
+                    );
282
+                }
283
+            }
284
+        }
285
+
286
+        $this->connection->commit();
287
+        unset($this->cache[$path]);
288
+
289
+        return true;
290
+    }
291 291
 
292 292
 }
Please login to merge, or discard this patch.
lib/private/Activity/EventMerger.php 2 patches
Indentation   +201 added lines, -201 removed lines patch added patch discarded remove patch
@@ -27,230 +27,230 @@
 block discarded – undo
27 27
 
28 28
 class EventMerger implements IEventMerger {
29 29
 
30
-	/** @var IL10N */
31
-	protected $l10n;
30
+    /** @var IL10N */
31
+    protected $l10n;
32 32
 
33
-	/**
34
-	 * @param IL10N $l10n
35
-	 */
36
-	public function __construct(IL10N $l10n) {
37
-		$this->l10n = $l10n;
38
-	}
33
+    /**
34
+     * @param IL10N $l10n
35
+     */
36
+    public function __construct(IL10N $l10n) {
37
+        $this->l10n = $l10n;
38
+    }
39 39
 
40
-	/**
41
-	 * Combines two events when possible to have grouping:
42
-	 *
43
-	 * Example1: Two events with subject '{user} created {file}' and
44
-	 * $mergeParameter file with different file and same user will be merged
45
-	 * to '{user} created {file1} and {file2}' and the childEvent on the return
46
-	 * will be set, if the events have been merged.
47
-	 *
48
-	 * Example2: Two events with subject '{user} created {file}' and
49
-	 * $mergeParameter file with same file and same user will be merged to
50
-	 * '{user} created {file1}' and the childEvent on the return will be set, if
51
-	 * the events have been merged.
52
-	 *
53
-	 * The following requirements have to be met, in order to be merged:
54
-	 * - Both events need to have the same `getApp()`
55
-	 * - Both events must not have a message `getMessage()`
56
-	 * - Both events need to have the same subject `getSubject()`
57
-	 * - Both events need to have the same object type `getObjectType()`
58
-	 * - The time difference between both events must not be bigger then 3 hours
59
-	 * - Only up to 5 events can be merged.
60
-	 * - All parameters apart from such starting with $mergeParameter must be
61
-	 *   the same for both events.
62
-	 *
63
-	 * @param string $mergeParameter
64
-	 * @param IEvent $event
65
-	 * @param IEvent|null $previousEvent
66
-	 * @return IEvent
67
-	 */
68
-	public function mergeEvents($mergeParameter, IEvent $event, IEvent $previousEvent = null) {
69
-		// No second event => can not combine
70
-		if (!$previousEvent instanceof IEvent) {
71
-			return $event;
72
-		}
40
+    /**
41
+     * Combines two events when possible to have grouping:
42
+     *
43
+     * Example1: Two events with subject '{user} created {file}' and
44
+     * $mergeParameter file with different file and same user will be merged
45
+     * to '{user} created {file1} and {file2}' and the childEvent on the return
46
+     * will be set, if the events have been merged.
47
+     *
48
+     * Example2: Two events with subject '{user} created {file}' and
49
+     * $mergeParameter file with same file and same user will be merged to
50
+     * '{user} created {file1}' and the childEvent on the return will be set, if
51
+     * the events have been merged.
52
+     *
53
+     * The following requirements have to be met, in order to be merged:
54
+     * - Both events need to have the same `getApp()`
55
+     * - Both events must not have a message `getMessage()`
56
+     * - Both events need to have the same subject `getSubject()`
57
+     * - Both events need to have the same object type `getObjectType()`
58
+     * - The time difference between both events must not be bigger then 3 hours
59
+     * - Only up to 5 events can be merged.
60
+     * - All parameters apart from such starting with $mergeParameter must be
61
+     *   the same for both events.
62
+     *
63
+     * @param string $mergeParameter
64
+     * @param IEvent $event
65
+     * @param IEvent|null $previousEvent
66
+     * @return IEvent
67
+     */
68
+    public function mergeEvents($mergeParameter, IEvent $event, IEvent $previousEvent = null) {
69
+        // No second event => can not combine
70
+        if (!$previousEvent instanceof IEvent) {
71
+            return $event;
72
+        }
73 73
 
74
-		// Different app => can not combine
75
-		if ($event->getApp() !== $previousEvent->getApp()) {
76
-			return $event;
77
-		}
74
+        // Different app => can not combine
75
+        if ($event->getApp() !== $previousEvent->getApp()) {
76
+            return $event;
77
+        }
78 78
 
79
-		// Message is set => can not combine
80
-		if ($event->getMessage() !== '' || $previousEvent->getMessage() !== '') {
81
-			return $event;
82
-		}
79
+        // Message is set => can not combine
80
+        if ($event->getMessage() !== '' || $previousEvent->getMessage() !== '') {
81
+            return $event;
82
+        }
83 83
 
84
-		// Different subject => can not combine
85
-		if ($event->getSubject() !== $previousEvent->getSubject()) {
86
-			return $event;
87
-		}
84
+        // Different subject => can not combine
85
+        if ($event->getSubject() !== $previousEvent->getSubject()) {
86
+            return $event;
87
+        }
88 88
 
89
-		// Different object type => can not combine
90
-		if ($event->getObjectType() !== $previousEvent->getObjectType()) {
91
-			return $event;
92
-		}
89
+        // Different object type => can not combine
90
+        if ($event->getObjectType() !== $previousEvent->getObjectType()) {
91
+            return $event;
92
+        }
93 93
 
94
-		// More than 3 hours difference => can not combine
95
-		if (abs($event->getTimestamp() - $previousEvent->getTimestamp()) > 3 * 60 * 60) {
96
-			return $event;
97
-		}
94
+        // More than 3 hours difference => can not combine
95
+        if (abs($event->getTimestamp() - $previousEvent->getTimestamp()) > 3 * 60 * 60) {
96
+            return $event;
97
+        }
98 98
 
99
-		// Other parameters are not the same => can not combine
100
-		try {
101
-			list($combined, $parameters) = $this->combineParameters($mergeParameter, $event, $previousEvent);
102
-		} catch (\UnexpectedValueException $e) {
103
-			return $event;
104
-		}
99
+        // Other parameters are not the same => can not combine
100
+        try {
101
+            list($combined, $parameters) = $this->combineParameters($mergeParameter, $event, $previousEvent);
102
+        } catch (\UnexpectedValueException $e) {
103
+            return $event;
104
+        }
105 105
 
106
-		try {
107
-			$newSubject = $this->getExtendedSubject($event->getRichSubject(), $mergeParameter, $combined);
108
-			$parsedSubject = $this->generateParsedSubject($newSubject, $parameters);
106
+        try {
107
+            $newSubject = $this->getExtendedSubject($event->getRichSubject(), $mergeParameter, $combined);
108
+            $parsedSubject = $this->generateParsedSubject($newSubject, $parameters);
109 109
 
110
-			$event->setRichSubject($newSubject, $parameters)
111
-				->setParsedSubject($parsedSubject)
112
-				->setChildEvent($previousEvent);
113
-		} catch (\UnexpectedValueException $e) {
114
-			return $event;
115
-		}
110
+            $event->setRichSubject($newSubject, $parameters)
111
+                ->setParsedSubject($parsedSubject)
112
+                ->setChildEvent($previousEvent);
113
+        } catch (\UnexpectedValueException $e) {
114
+            return $event;
115
+        }
116 116
 
117
-		return $event;
118
-	}
117
+        return $event;
118
+    }
119 119
 
120
-	/**
121
-	 * @param string $mergeParameter
122
-	 * @param IEvent $event
123
-	 * @param IEvent $previousEvent
124
-	 * @return array
125
-	 * @throws \UnexpectedValueException
126
-	 */
127
-	protected function combineParameters($mergeParameter, IEvent $event, IEvent $previousEvent) {
128
-		$params1 = $event->getRichSubjectParameters();
129
-		$params2 = $previousEvent->getRichSubjectParameters();
130
-		$params = [];
120
+    /**
121
+     * @param string $mergeParameter
122
+     * @param IEvent $event
123
+     * @param IEvent $previousEvent
124
+     * @return array
125
+     * @throws \UnexpectedValueException
126
+     */
127
+    protected function combineParameters($mergeParameter, IEvent $event, IEvent $previousEvent) {
128
+        $params1 = $event->getRichSubjectParameters();
129
+        $params2 = $previousEvent->getRichSubjectParameters();
130
+        $params = [];
131 131
 
132
-		$combined = 0;
132
+        $combined = 0;
133 133
 
134
-		// Check that all parameters from $event exist in $previousEvent
135
-		foreach ($params1 as $key => $parameter) {
136
-			if (preg_match('/^' . $mergeParameter . '(\d+)?$/', $key)) {
137
-				if (!$this->checkParameterAlreadyExits($params, $mergeParameter, $parameter)) {
138
-					$combined++;
139
-					$params[$mergeParameter . $combined] = $parameter;
140
-				}
141
-				continue;
142
-			}
134
+        // Check that all parameters from $event exist in $previousEvent
135
+        foreach ($params1 as $key => $parameter) {
136
+            if (preg_match('/^' . $mergeParameter . '(\d+)?$/', $key)) {
137
+                if (!$this->checkParameterAlreadyExits($params, $mergeParameter, $parameter)) {
138
+                    $combined++;
139
+                    $params[$mergeParameter . $combined] = $parameter;
140
+                }
141
+                continue;
142
+            }
143 143
 
144
-			if (!isset($params2[$key]) || $params2[$key] !== $parameter) {
145
-				// Parameter missing on $previousEvent or different => can not combine
146
-				throw new \UnexpectedValueException();
147
-			}
144
+            if (!isset($params2[$key]) || $params2[$key] !== $parameter) {
145
+                // Parameter missing on $previousEvent or different => can not combine
146
+                throw new \UnexpectedValueException();
147
+            }
148 148
 
149
-			$params[$key] = $parameter;
150
-		}
149
+            $params[$key] = $parameter;
150
+        }
151 151
 
152
-		// Check that all parameters from $previousEvent exist in $event
153
-		foreach ($params2 as $key => $parameter) {
154
-			if (preg_match('/^' . $mergeParameter . '(\d+)?$/', $key)) {
155
-				if (!$this->checkParameterAlreadyExits($params, $mergeParameter, $parameter)) {
156
-					$combined++;
157
-					$params[$mergeParameter . $combined] = $parameter;
158
-				}
159
-				continue;
160
-			}
152
+        // Check that all parameters from $previousEvent exist in $event
153
+        foreach ($params2 as $key => $parameter) {
154
+            if (preg_match('/^' . $mergeParameter . '(\d+)?$/', $key)) {
155
+                if (!$this->checkParameterAlreadyExits($params, $mergeParameter, $parameter)) {
156
+                    $combined++;
157
+                    $params[$mergeParameter . $combined] = $parameter;
158
+                }
159
+                continue;
160
+            }
161 161
 
162
-			if (!isset($params1[$key]) || $params1[$key] !== $parameter) {
163
-				// Parameter missing on $event or different => can not combine
164
-				throw new \UnexpectedValueException();
165
-			}
162
+            if (!isset($params1[$key]) || $params1[$key] !== $parameter) {
163
+                // Parameter missing on $event or different => can not combine
164
+                throw new \UnexpectedValueException();
165
+            }
166 166
 
167
-			$params[$key] = $parameter;
168
-		}
167
+            $params[$key] = $parameter;
168
+        }
169 169
 
170
-		return [$combined, $params];
171
-	}
170
+        return [$combined, $params];
171
+    }
172 172
 
173
-	/**
174
-	 * @param array[] $parameters
175
-	 * @param string $mergeParameter
176
-	 * @param array $parameter
177
-	 * @return bool
178
-	 */
179
-	protected function checkParameterAlreadyExits($parameters, $mergeParameter, $parameter) {
180
-		foreach ($parameters as $key => $param) {
181
-			if (preg_match('/^' . $mergeParameter . '(\d+)?$/', $key)) {
182
-				if ($param === $parameter) {
183
-					return true;
184
-				}
185
-			}
186
-		}
187
-		return false;
188
-	}
173
+    /**
174
+     * @param array[] $parameters
175
+     * @param string $mergeParameter
176
+     * @param array $parameter
177
+     * @return bool
178
+     */
179
+    protected function checkParameterAlreadyExits($parameters, $mergeParameter, $parameter) {
180
+        foreach ($parameters as $key => $param) {
181
+            if (preg_match('/^' . $mergeParameter . '(\d+)?$/', $key)) {
182
+                if ($param === $parameter) {
183
+                    return true;
184
+                }
185
+            }
186
+        }
187
+        return false;
188
+    }
189 189
 
190
-	/**
191
-	 * @param string $subject
192
-	 * @param string $parameter
193
-	 * @param int $counter
194
-	 * @return mixed
195
-	 */
196
-	protected function getExtendedSubject($subject, $parameter, $counter) {
197
-		switch ($counter) {
198
-			case 1:
199
-				$replacement = '{' . $parameter . '1}';
200
-				break;
201
-			case 2:
202
-				$replacement = $this->l10n->t(
203
-					'%1$s and %2$s',
204
-					['{' . $parameter . '2}', '{' . $parameter . '1}']
205
-				);
206
-				break;
207
-			case 3:
208
-				$replacement = $this->l10n->t(
209
-					'%1$s, %2$s and %3$s',
210
-					['{' . $parameter . '3}', '{' . $parameter . '2}', '{' . $parameter . '1}']
211
-				);
212
-				break;
213
-			case 4:
214
-				$replacement = $this->l10n->t(
215
-					'%1$s, %2$s, %3$s and %4$s',
216
-					['{' . $parameter . '4}', '{' . $parameter . '3}', '{' . $parameter . '2}', '{' . $parameter . '1}']
217
-				);
218
-				break;
219
-			case 5:
220
-				$replacement = $this->l10n->t(
221
-					'%1$s, %2$s, %3$s, %4$s and %5$s',
222
-					['{' . $parameter . '5}', '{' . $parameter . '4}', '{' . $parameter . '3}', '{' . $parameter . '2}', '{' . $parameter . '1}']
223
-				);
224
-				break;
225
-			default:
226
-				throw new \UnexpectedValueException();
227
-		}
190
+    /**
191
+     * @param string $subject
192
+     * @param string $parameter
193
+     * @param int $counter
194
+     * @return mixed
195
+     */
196
+    protected function getExtendedSubject($subject, $parameter, $counter) {
197
+        switch ($counter) {
198
+            case 1:
199
+                $replacement = '{' . $parameter . '1}';
200
+                break;
201
+            case 2:
202
+                $replacement = $this->l10n->t(
203
+                    '%1$s and %2$s',
204
+                    ['{' . $parameter . '2}', '{' . $parameter . '1}']
205
+                );
206
+                break;
207
+            case 3:
208
+                $replacement = $this->l10n->t(
209
+                    '%1$s, %2$s and %3$s',
210
+                    ['{' . $parameter . '3}', '{' . $parameter . '2}', '{' . $parameter . '1}']
211
+                );
212
+                break;
213
+            case 4:
214
+                $replacement = $this->l10n->t(
215
+                    '%1$s, %2$s, %3$s and %4$s',
216
+                    ['{' . $parameter . '4}', '{' . $parameter . '3}', '{' . $parameter . '2}', '{' . $parameter . '1}']
217
+                );
218
+                break;
219
+            case 5:
220
+                $replacement = $this->l10n->t(
221
+                    '%1$s, %2$s, %3$s, %4$s and %5$s',
222
+                    ['{' . $parameter . '5}', '{' . $parameter . '4}', '{' . $parameter . '3}', '{' . $parameter . '2}', '{' . $parameter . '1}']
223
+                );
224
+                break;
225
+            default:
226
+                throw new \UnexpectedValueException();
227
+        }
228 228
 
229
-		return str_replace(
230
-			'{' . $parameter . '}',
231
-			$replacement,
232
-			$subject
233
-		);
234
-	}
229
+        return str_replace(
230
+            '{' . $parameter . '}',
231
+            $replacement,
232
+            $subject
233
+        );
234
+    }
235 235
 
236
-	/**
237
-	 * @param string $subject
238
-	 * @param array[] $parameters
239
-	 * @return string
240
-	 */
241
-	protected function generateParsedSubject($subject, $parameters) {
242
-		$placeholders = $replacements = [];
243
-		foreach ($parameters as $placeholder => $parameter) {
244
-			$placeholders[] = '{' . $placeholder . '}';
245
-			if ($parameter['type'] === 'file') {
246
-				$replacements[] = trim($parameter['path'], '/');
247
-			} else if (isset($parameter['name'])) {
248
-				$replacements[] = $parameter['name'];
249
-			} else {
250
-				$replacements[] = $parameter['id'];
251
-			}
252
-		}
236
+    /**
237
+     * @param string $subject
238
+     * @param array[] $parameters
239
+     * @return string
240
+     */
241
+    protected function generateParsedSubject($subject, $parameters) {
242
+        $placeholders = $replacements = [];
243
+        foreach ($parameters as $placeholder => $parameter) {
244
+            $placeholders[] = '{' . $placeholder . '}';
245
+            if ($parameter['type'] === 'file') {
246
+                $replacements[] = trim($parameter['path'], '/');
247
+            } else if (isset($parameter['name'])) {
248
+                $replacements[] = $parameter['name'];
249
+            } else {
250
+                $replacements[] = $parameter['id'];
251
+            }
252
+        }
253 253
 
254
-		return str_replace($placeholders, $replacements, $subject);
255
-	}
254
+        return str_replace($placeholders, $replacements, $subject);
255
+    }
256 256
 }
Please login to merge, or discard this patch.
Spacing   +12 added lines, -12 removed lines patch added patch discarded remove patch
@@ -133,10 +133,10 @@  discard block
 block discarded – undo
133 133
 
134 134
 		// Check that all parameters from $event exist in $previousEvent
135 135
 		foreach ($params1 as $key => $parameter) {
136
-			if (preg_match('/^' . $mergeParameter . '(\d+)?$/', $key)) {
136
+			if (preg_match('/^'.$mergeParameter.'(\d+)?$/', $key)) {
137 137
 				if (!$this->checkParameterAlreadyExits($params, $mergeParameter, $parameter)) {
138 138
 					$combined++;
139
-					$params[$mergeParameter . $combined] = $parameter;
139
+					$params[$mergeParameter.$combined] = $parameter;
140 140
 				}
141 141
 				continue;
142 142
 			}
@@ -151,10 +151,10 @@  discard block
 block discarded – undo
151 151
 
152 152
 		// Check that all parameters from $previousEvent exist in $event
153 153
 		foreach ($params2 as $key => $parameter) {
154
-			if (preg_match('/^' . $mergeParameter . '(\d+)?$/', $key)) {
154
+			if (preg_match('/^'.$mergeParameter.'(\d+)?$/', $key)) {
155 155
 				if (!$this->checkParameterAlreadyExits($params, $mergeParameter, $parameter)) {
156 156
 					$combined++;
157
-					$params[$mergeParameter . $combined] = $parameter;
157
+					$params[$mergeParameter.$combined] = $parameter;
158 158
 				}
159 159
 				continue;
160 160
 			}
@@ -178,7 +178,7 @@  discard block
 block discarded – undo
178 178
 	 */
179 179
 	protected function checkParameterAlreadyExits($parameters, $mergeParameter, $parameter) {
180 180
 		foreach ($parameters as $key => $param) {
181
-			if (preg_match('/^' . $mergeParameter . '(\d+)?$/', $key)) {
181
+			if (preg_match('/^'.$mergeParameter.'(\d+)?$/', $key)) {
182 182
 				if ($param === $parameter) {
183 183
 					return true;
184 184
 				}
@@ -196,30 +196,30 @@  discard block
 block discarded – undo
196 196
 	protected function getExtendedSubject($subject, $parameter, $counter) {
197 197
 		switch ($counter) {
198 198
 			case 1:
199
-				$replacement = '{' . $parameter . '1}';
199
+				$replacement = '{'.$parameter.'1}';
200 200
 				break;
201 201
 			case 2:
202 202
 				$replacement = $this->l10n->t(
203 203
 					'%1$s and %2$s',
204
-					['{' . $parameter . '2}', '{' . $parameter . '1}']
204
+					['{'.$parameter.'2}', '{'.$parameter.'1}']
205 205
 				);
206 206
 				break;
207 207
 			case 3:
208 208
 				$replacement = $this->l10n->t(
209 209
 					'%1$s, %2$s and %3$s',
210
-					['{' . $parameter . '3}', '{' . $parameter . '2}', '{' . $parameter . '1}']
210
+					['{'.$parameter.'3}', '{'.$parameter.'2}', '{'.$parameter.'1}']
211 211
 				);
212 212
 				break;
213 213
 			case 4:
214 214
 				$replacement = $this->l10n->t(
215 215
 					'%1$s, %2$s, %3$s and %4$s',
216
-					['{' . $parameter . '4}', '{' . $parameter . '3}', '{' . $parameter . '2}', '{' . $parameter . '1}']
216
+					['{'.$parameter.'4}', '{'.$parameter.'3}', '{'.$parameter.'2}', '{'.$parameter.'1}']
217 217
 				);
218 218
 				break;
219 219
 			case 5:
220 220
 				$replacement = $this->l10n->t(
221 221
 					'%1$s, %2$s, %3$s, %4$s and %5$s',
222
-					['{' . $parameter . '5}', '{' . $parameter . '4}', '{' . $parameter . '3}', '{' . $parameter . '2}', '{' . $parameter . '1}']
222
+					['{'.$parameter.'5}', '{'.$parameter.'4}', '{'.$parameter.'3}', '{'.$parameter.'2}', '{'.$parameter.'1}']
223 223
 				);
224 224
 				break;
225 225
 			default:
@@ -227,7 +227,7 @@  discard block
 block discarded – undo
227 227
 		}
228 228
 
229 229
 		return str_replace(
230
-			'{' . $parameter . '}',
230
+			'{'.$parameter.'}',
231 231
 			$replacement,
232 232
 			$subject
233 233
 		);
@@ -241,7 +241,7 @@  discard block
 block discarded – undo
241 241
 	protected function generateParsedSubject($subject, $parameters) {
242 242
 		$placeholders = $replacements = [];
243 243
 		foreach ($parameters as $placeholder => $parameter) {
244
-			$placeholders[] = '{' . $placeholder . '}';
244
+			$placeholders[] = '{'.$placeholder.'}';
245 245
 			if ($parameter['type'] === 'file') {
246 246
 				$replacements[] = trim($parameter['path'], '/');
247 247
 			} else if (isset($parameter['name'])) {
Please login to merge, or discard this patch.
lib/private/Cache/CappedMemoryCache.php 1 patch
Indentation   +62 added lines, -62 removed lines patch added patch discarded remove patch
@@ -31,66 +31,66 @@
 block discarded – undo
31 31
  */
32 32
 class CappedMemoryCache implements ICache, \ArrayAccess {
33 33
 
34
-	private $capacity;
35
-	private $cache = [];
36
-
37
-	public function __construct($capacity = 512) {
38
-		$this->capacity = $capacity;
39
-	}
40
-
41
-	public function hasKey($key) {
42
-		return isset($this->cache[$key]);
43
-	}
44
-
45
-	public function get($key) {
46
-		return isset($this->cache[$key]) ? $this->cache[$key] : null;
47
-	}
48
-
49
-	public function set($key, $value, $ttl = 0) {
50
-		if (is_null($key)) {
51
-			$this->cache[] = $value;
52
-		} else {
53
-			$this->cache[$key] = $value;
54
-		}
55
-		$this->garbageCollect();
56
-	}
57
-
58
-	public function remove($key) {
59
-		unset($this->cache[$key]);
60
-		return true;
61
-	}
62
-
63
-	public function clear($prefix = '') {
64
-		$this->cache = [];
65
-		return true;
66
-	}
67
-
68
-	public function offsetExists($offset) {
69
-		return $this->hasKey($offset);
70
-	}
71
-
72
-	public function &offsetGet($offset) {
73
-		return $this->cache[$offset];
74
-	}
75
-
76
-	public function offsetSet($offset, $value) {
77
-		$this->set($offset, $value);
78
-	}
79
-
80
-	public function offsetUnset($offset) {
81
-		$this->remove($offset);
82
-	}
83
-
84
-	public function getData() {
85
-		return $this->cache;
86
-	}
87
-
88
-
89
-	private function garbageCollect() {
90
-		while (count($this->cache) > $this->capacity) {
91
-			reset($this->cache);
92
-			$key = key($this->cache);
93
-			$this->remove($key);
94
-		}
95
-	}
34
+    private $capacity;
35
+    private $cache = [];
36
+
37
+    public function __construct($capacity = 512) {
38
+        $this->capacity = $capacity;
39
+    }
40
+
41
+    public function hasKey($key) {
42
+        return isset($this->cache[$key]);
43
+    }
44
+
45
+    public function get($key) {
46
+        return isset($this->cache[$key]) ? $this->cache[$key] : null;
47
+    }
48
+
49
+    public function set($key, $value, $ttl = 0) {
50
+        if (is_null($key)) {
51
+            $this->cache[] = $value;
52
+        } else {
53
+            $this->cache[$key] = $value;
54
+        }
55
+        $this->garbageCollect();
56
+    }
57
+
58
+    public function remove($key) {
59
+        unset($this->cache[$key]);
60
+        return true;
61
+    }
62
+
63
+    public function clear($prefix = '') {
64
+        $this->cache = [];
65
+        return true;
66
+    }
67
+
68
+    public function offsetExists($offset) {
69
+        return $this->hasKey($offset);
70
+    }
71
+
72
+    public function &offsetGet($offset) {
73
+        return $this->cache[$offset];
74
+    }
75
+
76
+    public function offsetSet($offset, $value) {
77
+        $this->set($offset, $value);
78
+    }
79
+
80
+    public function offsetUnset($offset) {
81
+        $this->remove($offset);
82
+    }
83
+
84
+    public function getData() {
85
+        return $this->cache;
86
+    }
87
+
88
+
89
+    private function garbageCollect() {
90
+        while (count($this->cache) > $this->capacity) {
91
+            reset($this->cache);
92
+            $key = key($this->cache);
93
+            $this->remove($key);
94
+        }
95
+    }
96 96
 }
Please login to merge, or discard this patch.
lib/private/Repair/CleanTags.php 2 patches
Spacing   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -171,14 +171,14 @@
 block discarded – undo
171 171
 	protected function deleteOrphanEntries(IOutput $output, $repairInfo, $deleteTable, $deleteId, $sourceTable, $sourceId, $sourceNullColumn) {
172 172
 		$qb = $this->connection->getQueryBuilder();
173 173
 
174
-		$qb->select('d.' . $deleteId)
174
+		$qb->select('d.'.$deleteId)
175 175
 			->from($deleteTable, 'd')
176
-			->leftJoin('d', $sourceTable, 's', $qb->expr()->eq('d.' . $deleteId, 's.' . $sourceId))
176
+			->leftJoin('d', $sourceTable, 's', $qb->expr()->eq('d.'.$deleteId, 's.'.$sourceId))
177 177
 			->where(
178 178
 				$qb->expr()->eq('d.type', $qb->expr()->literal('files'))
179 179
 			)
180 180
 			->andWhere(
181
-				$qb->expr()->isNull('s.' . $sourceNullColumn)
181
+				$qb->expr()->isNull('s.'.$sourceNullColumn)
182 182
 			);
183 183
 		$result = $qb->execute();
184 184
 
Please login to merge, or discard this patch.
Indentation   +168 added lines, -168 removed lines patch added patch discarded remove patch
@@ -37,172 +37,172 @@
 block discarded – undo
37 37
  */
38 38
 class CleanTags implements IRepairStep {
39 39
 
40
-	/** @var IDBConnection */
41
-	protected $connection;
42
-
43
-	/** @var IUserManager */
44
-	protected $userManager;
45
-
46
-	protected $deletedTags = 0;
47
-
48
-	/**
49
-	 * @param IDBConnection $connection
50
-	 * @param IUserManager $userManager
51
-	 */
52
-	public function __construct(IDBConnection $connection, IUserManager $userManager) {
53
-		$this->connection = $connection;
54
-		$this->userManager = $userManager;
55
-	}
56
-
57
-	/**
58
-	 * @return string
59
-	 */
60
-	public function getName() {
61
-		return 'Clean tags and favorites';
62
-	}
63
-
64
-	/**
65
-	 * Updates the configuration after running an update
66
-	 */
67
-	public function run(IOutput $output) {
68
-		$this->deleteOrphanTags($output);
69
-		$this->deleteOrphanFileEntries($output);
70
-		$this->deleteOrphanTagEntries($output);
71
-		$this->deleteOrphanCategoryEntries($output);
72
-	}
73
-
74
-	/**
75
-	 * Delete tags for deleted users
76
-	 */
77
-	protected function deleteOrphanTags(IOutput $output) {
78
-		$offset = 0;
79
-		while ($this->checkTags($offset)) {
80
-			$offset += 50;
81
-		}
82
-
83
-		$output->info(sprintf('%d tags of deleted users have been removed.', $this->deletedTags));
84
-	}
85
-
86
-	protected function checkTags($offset) {
87
-		$query = $this->connection->getQueryBuilder();
88
-		$query->select('uid')
89
-			->from('vcategory')
90
-			->groupBy('uid')
91
-			->orderBy('uid')
92
-			->setMaxResults(50)
93
-			->setFirstResult($offset);
94
-		$result = $query->execute();
95
-
96
-		$users = [];
97
-		$hadResults = false;
98
-		while ($row = $result->fetch()) {
99
-			$hadResults = true;
100
-			if (!$this->userManager->userExists($row['uid'])) {
101
-				$users[] = $row['uid'];
102
-			}
103
-		}
104
-		$result->closeCursor();
105
-
106
-		if (!$hadResults) {
107
-			// No more tags, stop looping
108
-			return false;
109
-		}
110
-
111
-		if (!empty($users)) {
112
-			$query = $this->connection->getQueryBuilder();
113
-			$query->delete('vcategory')
114
-				->where($query->expr()->in('uid', $query->createNamedParameter($users, IQueryBuilder::PARAM_STR_ARRAY)));
115
-			$this->deletedTags += $query->execute();
116
-		}
117
-		return true;
118
-	}
119
-
120
-	/**
121
-	 * Delete tag entries for deleted files
122
-	 */
123
-	protected function deleteOrphanFileEntries(IOutput $output) {
124
-		$this->deleteOrphanEntries(
125
-			$output,
126
-			'%d tags for delete files have been removed.',
127
-			'vcategory_to_object', 'objid',
128
-			'filecache', 'fileid', 'path_hash'
129
-		);
130
-	}
131
-
132
-	/**
133
-	 * Delete tag entries for deleted tags
134
-	 */
135
-	protected function deleteOrphanTagEntries(IOutput $output) {
136
-		$this->deleteOrphanEntries(
137
-			$output,
138
-			'%d tag entries for deleted tags have been removed.',
139
-			'vcategory_to_object', 'categoryid',
140
-			'vcategory', 'id', 'uid'
141
-		);
142
-	}
143
-
144
-	/**
145
-	 * Delete tags that have no entries
146
-	 */
147
-	protected function deleteOrphanCategoryEntries(IOutput $output) {
148
-		$this->deleteOrphanEntries(
149
-			$output,
150
-			'%d tags with no entries have been removed.',
151
-			'vcategory', 'id',
152
-			'vcategory_to_object', 'categoryid', 'type'
153
-		);
154
-	}
155
-
156
-	/**
157
-	 * Deletes all entries from $deleteTable that do not have a matching entry in $sourceTable
158
-	 *
159
-	 * A query joins $deleteTable.$deleteId = $sourceTable.$sourceId and checks
160
-	 * whether $sourceNullColumn is null. If it is null, the entry in $deleteTable
161
-	 * is being deleted.
162
-	 *
163
-	 * @param string $repairInfo
164
-	 * @param string $deleteTable
165
-	 * @param string $deleteId
166
-	 * @param string $sourceTable
167
-	 * @param string $sourceId
168
-	 * @param string $sourceNullColumn	If this column is null in the source table,
169
-	 * 								the entry is deleted in the $deleteTable
170
-	 * @suppress SqlInjectionChecker
171
-	 */
172
-	protected function deleteOrphanEntries(IOutput $output, $repairInfo, $deleteTable, $deleteId, $sourceTable, $sourceId, $sourceNullColumn) {
173
-		$qb = $this->connection->getQueryBuilder();
174
-
175
-		$qb->select('d.' . $deleteId)
176
-			->from($deleteTable, 'd')
177
-			->leftJoin('d', $sourceTable, 's', $qb->expr()->eq('d.' . $deleteId, 's.' . $sourceId))
178
-			->where(
179
-				$qb->expr()->eq('d.type', $qb->expr()->literal('files'))
180
-			)
181
-			->andWhere(
182
-				$qb->expr()->isNull('s.' . $sourceNullColumn)
183
-			);
184
-		$result = $qb->execute();
185
-
186
-		$orphanItems = array();
187
-		while ($row = $result->fetch()) {
188
-			$orphanItems[] = (int) $row[$deleteId];
189
-		}
190
-
191
-		if (!empty($orphanItems)) {
192
-			$orphanItemsBatch = array_chunk($orphanItems, 200);
193
-			foreach ($orphanItemsBatch as $items) {
194
-				$qb->delete($deleteTable)
195
-					->where(
196
-						$qb->expr()->eq('type', $qb->expr()->literal('files'))
197
-					)
198
-					->andWhere($qb->expr()->in($deleteId, $qb->createParameter('ids')));
199
-				$qb->setParameter('ids', $items, IQueryBuilder::PARAM_INT_ARRAY);
200
-				$qb->execute();
201
-			}
202
-		}
203
-
204
-		if ($repairInfo) {
205
-			$output->info(sprintf($repairInfo, count($orphanItems)));
206
-		}
207
-	}
40
+    /** @var IDBConnection */
41
+    protected $connection;
42
+
43
+    /** @var IUserManager */
44
+    protected $userManager;
45
+
46
+    protected $deletedTags = 0;
47
+
48
+    /**
49
+     * @param IDBConnection $connection
50
+     * @param IUserManager $userManager
51
+     */
52
+    public function __construct(IDBConnection $connection, IUserManager $userManager) {
53
+        $this->connection = $connection;
54
+        $this->userManager = $userManager;
55
+    }
56
+
57
+    /**
58
+     * @return string
59
+     */
60
+    public function getName() {
61
+        return 'Clean tags and favorites';
62
+    }
63
+
64
+    /**
65
+     * Updates the configuration after running an update
66
+     */
67
+    public function run(IOutput $output) {
68
+        $this->deleteOrphanTags($output);
69
+        $this->deleteOrphanFileEntries($output);
70
+        $this->deleteOrphanTagEntries($output);
71
+        $this->deleteOrphanCategoryEntries($output);
72
+    }
73
+
74
+    /**
75
+     * Delete tags for deleted users
76
+     */
77
+    protected function deleteOrphanTags(IOutput $output) {
78
+        $offset = 0;
79
+        while ($this->checkTags($offset)) {
80
+            $offset += 50;
81
+        }
82
+
83
+        $output->info(sprintf('%d tags of deleted users have been removed.', $this->deletedTags));
84
+    }
85
+
86
+    protected function checkTags($offset) {
87
+        $query = $this->connection->getQueryBuilder();
88
+        $query->select('uid')
89
+            ->from('vcategory')
90
+            ->groupBy('uid')
91
+            ->orderBy('uid')
92
+            ->setMaxResults(50)
93
+            ->setFirstResult($offset);
94
+        $result = $query->execute();
95
+
96
+        $users = [];
97
+        $hadResults = false;
98
+        while ($row = $result->fetch()) {
99
+            $hadResults = true;
100
+            if (!$this->userManager->userExists($row['uid'])) {
101
+                $users[] = $row['uid'];
102
+            }
103
+        }
104
+        $result->closeCursor();
105
+
106
+        if (!$hadResults) {
107
+            // No more tags, stop looping
108
+            return false;
109
+        }
110
+
111
+        if (!empty($users)) {
112
+            $query = $this->connection->getQueryBuilder();
113
+            $query->delete('vcategory')
114
+                ->where($query->expr()->in('uid', $query->createNamedParameter($users, IQueryBuilder::PARAM_STR_ARRAY)));
115
+            $this->deletedTags += $query->execute();
116
+        }
117
+        return true;
118
+    }
119
+
120
+    /**
121
+     * Delete tag entries for deleted files
122
+     */
123
+    protected function deleteOrphanFileEntries(IOutput $output) {
124
+        $this->deleteOrphanEntries(
125
+            $output,
126
+            '%d tags for delete files have been removed.',
127
+            'vcategory_to_object', 'objid',
128
+            'filecache', 'fileid', 'path_hash'
129
+        );
130
+    }
131
+
132
+    /**
133
+     * Delete tag entries for deleted tags
134
+     */
135
+    protected function deleteOrphanTagEntries(IOutput $output) {
136
+        $this->deleteOrphanEntries(
137
+            $output,
138
+            '%d tag entries for deleted tags have been removed.',
139
+            'vcategory_to_object', 'categoryid',
140
+            'vcategory', 'id', 'uid'
141
+        );
142
+    }
143
+
144
+    /**
145
+     * Delete tags that have no entries
146
+     */
147
+    protected function deleteOrphanCategoryEntries(IOutput $output) {
148
+        $this->deleteOrphanEntries(
149
+            $output,
150
+            '%d tags with no entries have been removed.',
151
+            'vcategory', 'id',
152
+            'vcategory_to_object', 'categoryid', 'type'
153
+        );
154
+    }
155
+
156
+    /**
157
+     * Deletes all entries from $deleteTable that do not have a matching entry in $sourceTable
158
+     *
159
+     * A query joins $deleteTable.$deleteId = $sourceTable.$sourceId and checks
160
+     * whether $sourceNullColumn is null. If it is null, the entry in $deleteTable
161
+     * is being deleted.
162
+     *
163
+     * @param string $repairInfo
164
+     * @param string $deleteTable
165
+     * @param string $deleteId
166
+     * @param string $sourceTable
167
+     * @param string $sourceId
168
+     * @param string $sourceNullColumn	If this column is null in the source table,
169
+     * 								the entry is deleted in the $deleteTable
170
+     * @suppress SqlInjectionChecker
171
+     */
172
+    protected function deleteOrphanEntries(IOutput $output, $repairInfo, $deleteTable, $deleteId, $sourceTable, $sourceId, $sourceNullColumn) {
173
+        $qb = $this->connection->getQueryBuilder();
174
+
175
+        $qb->select('d.' . $deleteId)
176
+            ->from($deleteTable, 'd')
177
+            ->leftJoin('d', $sourceTable, 's', $qb->expr()->eq('d.' . $deleteId, 's.' . $sourceId))
178
+            ->where(
179
+                $qb->expr()->eq('d.type', $qb->expr()->literal('files'))
180
+            )
181
+            ->andWhere(
182
+                $qb->expr()->isNull('s.' . $sourceNullColumn)
183
+            );
184
+        $result = $qb->execute();
185
+
186
+        $orphanItems = array();
187
+        while ($row = $result->fetch()) {
188
+            $orphanItems[] = (int) $row[$deleteId];
189
+        }
190
+
191
+        if (!empty($orphanItems)) {
192
+            $orphanItemsBatch = array_chunk($orphanItems, 200);
193
+            foreach ($orphanItemsBatch as $items) {
194
+                $qb->delete($deleteTable)
195
+                    ->where(
196
+                        $qb->expr()->eq('type', $qb->expr()->literal('files'))
197
+                    )
198
+                    ->andWhere($qb->expr()->in($deleteId, $qb->createParameter('ids')));
199
+                $qb->setParameter('ids', $items, IQueryBuilder::PARAM_INT_ARRAY);
200
+                $qb->execute();
201
+            }
202
+        }
203
+
204
+        if ($repairInfo) {
205
+            $output->info(sprintf($repairInfo, count($orphanItems)));
206
+        }
207
+    }
208 208
 }
Please login to merge, or discard this patch.
apps/workflowengine/lib/Check/FileSystemTags.php 1 patch
Indentation   +133 added lines, -133 removed lines patch added patch discarded remove patch
@@ -33,137 +33,137 @@
 block discarded – undo
33 33
 
34 34
 class FileSystemTags implements ICheck {
35 35
 
36
-	/** @var array */
37
-	protected $fileIds;
38
-
39
-	/** @var array */
40
-	protected $fileSystemTags;
41
-
42
-	/** @var IL10N */
43
-	protected $l;
44
-
45
-	/** @var ISystemTagManager */
46
-	protected $systemTagManager;
47
-
48
-	/** @var ISystemTagObjectMapper */
49
-	protected $systemTagObjectMapper;
50
-
51
-	/** @var IStorage */
52
-	protected $storage;
53
-
54
-	/** @var string */
55
-	protected $path;
56
-
57
-	/**
58
-	 * @param IL10N $l
59
-	 * @param ISystemTagManager $systemTagManager
60
-	 * @param ISystemTagObjectMapper $systemTagObjectMapper
61
-	 */
62
-	public function __construct(IL10N $l, ISystemTagManager $systemTagManager, ISystemTagObjectMapper $systemTagObjectMapper) {
63
-		$this->l = $l;
64
-		$this->systemTagManager = $systemTagManager;
65
-		$this->systemTagObjectMapper = $systemTagObjectMapper;
66
-	}
67
-
68
-	/**
69
-	 * @param IStorage $storage
70
-	 * @param string $path
71
-	 */
72
-	public function setFileInfo(IStorage $storage, $path) {
73
-		$this->storage = $storage;
74
-		$this->path = $path;
75
-	}
76
-
77
-	/**
78
-	 * @param string $operator
79
-	 * @param string $value
80
-	 * @return bool
81
-	 */
82
-	public function executeCheck($operator, $value) {
83
-		$systemTags = $this->getSystemTags();
84
-		return ($operator === 'is') === in_array($value, $systemTags);
85
-	}
86
-
87
-	/**
88
-	 * @param string $operator
89
-	 * @param string $value
90
-	 * @throws \UnexpectedValueException
91
-	 */
92
-	public function validateCheck($operator, $value) {
93
-		if (!in_array($operator, ['is', '!is'])) {
94
-			throw new \UnexpectedValueException($this->l->t('The given operator is invalid'), 1);
95
-		}
96
-
97
-		try {
98
-			$this->systemTagManager->getTagsByIds($value);
99
-		} catch (TagNotFoundException $e) {
100
-			throw new \UnexpectedValueException($this->l->t('The given tag id is invalid'), 2);
101
-		} catch (\InvalidArgumentException $e) {
102
-			throw new \UnexpectedValueException($this->l->t('The given tag id is invalid'), 3);
103
-		}
104
-	}
105
-
106
-	/**
107
-	 * Get the ids of the assigned system tags
108
-	 * @return string[]
109
-	 */
110
-	protected function getSystemTags() {
111
-		$cache = $this->storage->getCache();
112
-		$fileIds = $this->getFileIds($cache, $this->path, !$this->storage->instanceOfStorage(IHomeStorage::class));
113
-
114
-		$systemTags = [];
115
-		foreach ($fileIds as $i => $fileId) {
116
-			if (isset($this->fileSystemTags[$fileId])) {
117
-				$systemTags[] = $this->fileSystemTags[$fileId];
118
-				unset($fileIds[$i]);
119
-			}
120
-		}
121
-
122
-		if (!empty($fileIds)) {
123
-			$mappedSystemTags = $this->systemTagObjectMapper->getTagIdsForObjects($fileIds, 'files');
124
-			foreach ($mappedSystemTags as $fileId => $fileSystemTags) {
125
-				$this->fileSystemTags[$fileId] = $fileSystemTags;
126
-				$systemTags[] = $fileSystemTags;
127
-			}
128
-		}
129
-
130
-		$systemTags = call_user_func_array('array_merge', $systemTags);
131
-		$systemTags = array_unique($systemTags);
132
-		return $systemTags;
133
-	}
134
-
135
-	/**
136
-	 * Get the file ids of the given path and its parents
137
-	 * @param ICache $cache
138
-	 * @param string $path
139
-	 * @param bool $isExternalStorage
140
-	 * @return int[]
141
-	 */
142
-	protected function getFileIds(ICache $cache, $path, $isExternalStorage) {
143
-		$cacheId = $cache->getNumericStorageId();
144
-		if (isset($this->fileIds[$cacheId][$path])) {
145
-			return $this->fileIds[$cacheId][$path];
146
-		}
147
-
148
-		$parentIds = [];
149
-		if ($path !== $this->dirname($path)) {
150
-			$parentIds = $this->getFileIds($cache, $this->dirname($path), $isExternalStorage);
151
-		} else if (!$isExternalStorage) {
152
-			return [];
153
-		}
154
-
155
-		$fileId = $cache->getId($path);
156
-		if ($fileId !== -1) {
157
-			$parentIds[] = $cache->getId($path);
158
-		}
159
-
160
-		$this->fileIds[$cacheId][$path] = $parentIds;
161
-
162
-		return $parentIds;
163
-	}
164
-
165
-	protected function dirname($path) {
166
-		$dir = dirname($path);
167
-		return $dir === '.' ? '' : $dir;
168
-	}
36
+    /** @var array */
37
+    protected $fileIds;
38
+
39
+    /** @var array */
40
+    protected $fileSystemTags;
41
+
42
+    /** @var IL10N */
43
+    protected $l;
44
+
45
+    /** @var ISystemTagManager */
46
+    protected $systemTagManager;
47
+
48
+    /** @var ISystemTagObjectMapper */
49
+    protected $systemTagObjectMapper;
50
+
51
+    /** @var IStorage */
52
+    protected $storage;
53
+
54
+    /** @var string */
55
+    protected $path;
56
+
57
+    /**
58
+     * @param IL10N $l
59
+     * @param ISystemTagManager $systemTagManager
60
+     * @param ISystemTagObjectMapper $systemTagObjectMapper
61
+     */
62
+    public function __construct(IL10N $l, ISystemTagManager $systemTagManager, ISystemTagObjectMapper $systemTagObjectMapper) {
63
+        $this->l = $l;
64
+        $this->systemTagManager = $systemTagManager;
65
+        $this->systemTagObjectMapper = $systemTagObjectMapper;
66
+    }
67
+
68
+    /**
69
+     * @param IStorage $storage
70
+     * @param string $path
71
+     */
72
+    public function setFileInfo(IStorage $storage, $path) {
73
+        $this->storage = $storage;
74
+        $this->path = $path;
75
+    }
76
+
77
+    /**
78
+     * @param string $operator
79
+     * @param string $value
80
+     * @return bool
81
+     */
82
+    public function executeCheck($operator, $value) {
83
+        $systemTags = $this->getSystemTags();
84
+        return ($operator === 'is') === in_array($value, $systemTags);
85
+    }
86
+
87
+    /**
88
+     * @param string $operator
89
+     * @param string $value
90
+     * @throws \UnexpectedValueException
91
+     */
92
+    public function validateCheck($operator, $value) {
93
+        if (!in_array($operator, ['is', '!is'])) {
94
+            throw new \UnexpectedValueException($this->l->t('The given operator is invalid'), 1);
95
+        }
96
+
97
+        try {
98
+            $this->systemTagManager->getTagsByIds($value);
99
+        } catch (TagNotFoundException $e) {
100
+            throw new \UnexpectedValueException($this->l->t('The given tag id is invalid'), 2);
101
+        } catch (\InvalidArgumentException $e) {
102
+            throw new \UnexpectedValueException($this->l->t('The given tag id is invalid'), 3);
103
+        }
104
+    }
105
+
106
+    /**
107
+     * Get the ids of the assigned system tags
108
+     * @return string[]
109
+     */
110
+    protected function getSystemTags() {
111
+        $cache = $this->storage->getCache();
112
+        $fileIds = $this->getFileIds($cache, $this->path, !$this->storage->instanceOfStorage(IHomeStorage::class));
113
+
114
+        $systemTags = [];
115
+        foreach ($fileIds as $i => $fileId) {
116
+            if (isset($this->fileSystemTags[$fileId])) {
117
+                $systemTags[] = $this->fileSystemTags[$fileId];
118
+                unset($fileIds[$i]);
119
+            }
120
+        }
121
+
122
+        if (!empty($fileIds)) {
123
+            $mappedSystemTags = $this->systemTagObjectMapper->getTagIdsForObjects($fileIds, 'files');
124
+            foreach ($mappedSystemTags as $fileId => $fileSystemTags) {
125
+                $this->fileSystemTags[$fileId] = $fileSystemTags;
126
+                $systemTags[] = $fileSystemTags;
127
+            }
128
+        }
129
+
130
+        $systemTags = call_user_func_array('array_merge', $systemTags);
131
+        $systemTags = array_unique($systemTags);
132
+        return $systemTags;
133
+    }
134
+
135
+    /**
136
+     * Get the file ids of the given path and its parents
137
+     * @param ICache $cache
138
+     * @param string $path
139
+     * @param bool $isExternalStorage
140
+     * @return int[]
141
+     */
142
+    protected function getFileIds(ICache $cache, $path, $isExternalStorage) {
143
+        $cacheId = $cache->getNumericStorageId();
144
+        if (isset($this->fileIds[$cacheId][$path])) {
145
+            return $this->fileIds[$cacheId][$path];
146
+        }
147
+
148
+        $parentIds = [];
149
+        if ($path !== $this->dirname($path)) {
150
+            $parentIds = $this->getFileIds($cache, $this->dirname($path), $isExternalStorage);
151
+        } else if (!$isExternalStorage) {
152
+            return [];
153
+        }
154
+
155
+        $fileId = $cache->getId($path);
156
+        if ($fileId !== -1) {
157
+            $parentIds[] = $cache->getId($path);
158
+        }
159
+
160
+        $this->fileIds[$cacheId][$path] = $parentIds;
161
+
162
+        return $parentIds;
163
+    }
164
+
165
+    protected function dirname($path) {
166
+        $dir = dirname($path);
167
+        return $dir === '.' ? '' : $dir;
168
+    }
169 169
 }
Please login to merge, or discard this patch.