Passed
Push — master ( 2df57b...447277 )
by Roeland
15:20 queued 04:25
created
lib/private/AllConfig.php 1 patch
Indentation   +497 added lines, -497 removed lines patch added patch discarded remove patch
@@ -40,501 +40,501 @@
 block discarded – undo
40 40
  * Class to combine all the configuration options ownCloud offers
41 41
  */
42 42
 class AllConfig implements \OCP\IConfig {
43
-	/** @var SystemConfig */
44
-	private $systemConfig;
45
-
46
-	/** @var IDBConnection */
47
-	private $connection;
48
-
49
-	/**
50
-	 * 3 dimensional array with the following structure:
51
-	 * [ $userId =>
52
-	 *     [ $appId =>
53
-	 *         [ $key => $value ]
54
-	 *     ]
55
-	 * ]
56
-	 *
57
-	 * database table: preferences
58
-	 *
59
-	 * methods that use this:
60
-	 *   - setUserValue
61
-	 *   - getUserValue
62
-	 *   - getUserKeys
63
-	 *   - deleteUserValue
64
-	 *   - deleteAllUserValues
65
-	 *   - deleteAppFromAllUsers
66
-	 *
67
-	 * @var CappedMemoryCache $userCache
68
-	 */
69
-	private $userCache;
70
-
71
-	/**
72
-	 * @param SystemConfig $systemConfig
73
-	 */
74
-	public function __construct(SystemConfig $systemConfig) {
75
-		$this->userCache = new CappedMemoryCache();
76
-		$this->systemConfig = $systemConfig;
77
-	}
78
-
79
-	/**
80
-	 * TODO - FIXME This fixes an issue with base.php that cause cyclic
81
-	 * dependencies, especially with autoconfig setup
82
-	 *
83
-	 * Replace this by properly injected database connection. Currently the
84
-	 * base.php triggers the getDatabaseConnection too early which causes in
85
-	 * autoconfig setup case a too early distributed database connection and
86
-	 * the autoconfig then needs to reinit all already initialized dependencies
87
-	 * that use the database connection.
88
-	 *
89
-	 * otherwise a SQLite database is created in the wrong directory
90
-	 * because the database connection was created with an uninitialized config
91
-	 */
92
-	private function fixDIInit() {
93
-		if ($this->connection === null) {
94
-			$this->connection = \OC::$server->getDatabaseConnection();
95
-		}
96
-	}
97
-
98
-	/**
99
-	 * Sets and deletes system wide values
100
-	 *
101
-	 * @param array $configs Associative array with `key => value` pairs
102
-	 *                       If value is null, the config key will be deleted
103
-	 */
104
-	public function setSystemValues(array $configs) {
105
-		$this->systemConfig->setValues($configs);
106
-	}
107
-
108
-	/**
109
-	 * Sets a new system wide value
110
-	 *
111
-	 * @param string $key the key of the value, under which will be saved
112
-	 * @param mixed $value the value that should be stored
113
-	 */
114
-	public function setSystemValue($key, $value) {
115
-		$this->systemConfig->setValue($key, $value);
116
-	}
117
-
118
-	/**
119
-	 * Looks up a system wide defined value
120
-	 *
121
-	 * @param string $key the key of the value, under which it was saved
122
-	 * @param mixed $default the default value to be returned if the value isn't set
123
-	 * @return mixed the value or $default
124
-	 */
125
-	public function getSystemValue($key, $default = '') {
126
-		return $this->systemConfig->getValue($key, $default);
127
-	}
128
-
129
-	/**
130
-	 * Looks up a boolean system wide defined value
131
-	 *
132
-	 * @param string $key the key of the value, under which it was saved
133
-	 * @param bool $default the default value to be returned if the value isn't set
134
-	 *
135
-	 * @return bool
136
-	 *
137
-	 * @since 16.0.0
138
-	 */
139
-	public function getSystemValueBool(string $key, bool $default = false): bool {
140
-		return (bool) $this->getSystemValue($key, $default);
141
-	}
142
-
143
-	/**
144
-	 * Looks up an integer system wide defined value
145
-	 *
146
-	 * @param string $key the key of the value, under which it was saved
147
-	 * @param int $default the default value to be returned if the value isn't set
148
-	 *
149
-	 * @return int
150
-	 *
151
-	 * @since 16.0.0
152
-	 */
153
-	public function getSystemValueInt(string $key, int $default = 0): int {
154
-		return (int) $this->getSystemValue($key, $default);
155
-	}
156
-
157
-	/**
158
-	 * Looks up a string system wide defined value
159
-	 *
160
-	 * @param string $key the key of the value, under which it was saved
161
-	 * @param string $default the default value to be returned if the value isn't set
162
-	 *
163
-	 * @return string
164
-	 *
165
-	 * @since 16.0.0
166
-	 */
167
-	public function getSystemValueString(string $key, string $default = ''): string {
168
-		return (string) $this->getSystemValue($key, $default);
169
-	}
170
-
171
-	/**
172
-	 * Looks up a system wide defined value and filters out sensitive data
173
-	 *
174
-	 * @param string $key the key of the value, under which it was saved
175
-	 * @param mixed $default the default value to be returned if the value isn't set
176
-	 * @return mixed the value or $default
177
-	 */
178
-	public function getFilteredSystemValue($key, $default = '') {
179
-		return $this->systemConfig->getFilteredValue($key, $default);
180
-	}
181
-
182
-	/**
183
-	 * Delete a system wide defined value
184
-	 *
185
-	 * @param string $key the key of the value, under which it was saved
186
-	 */
187
-	public function deleteSystemValue($key) {
188
-		$this->systemConfig->deleteValue($key);
189
-	}
190
-
191
-	/**
192
-	 * Get all keys stored for an app
193
-	 *
194
-	 * @param string $appName the appName that we stored the value under
195
-	 * @return string[] the keys stored for the app
196
-	 */
197
-	public function getAppKeys($appName) {
198
-		return \OC::$server->query(\OC\AppConfig::class)->getKeys($appName);
199
-	}
200
-
201
-	/**
202
-	 * Writes a new app wide value
203
-	 *
204
-	 * @param string $appName the appName that we want to store the value under
205
-	 * @param string $key the key of the value, under which will be saved
206
-	 * @param string|float|int $value the value that should be stored
207
-	 */
208
-	public function setAppValue($appName, $key, $value) {
209
-		\OC::$server->query(\OC\AppConfig::class)->setValue($appName, $key, $value);
210
-	}
211
-
212
-	/**
213
-	 * Looks up an app wide defined value
214
-	 *
215
-	 * @param string $appName the appName that we stored the value under
216
-	 * @param string $key the key of the value, under which it was saved
217
-	 * @param string $default the default value to be returned if the value isn't set
218
-	 * @return string the saved value
219
-	 */
220
-	public function getAppValue($appName, $key, $default = '') {
221
-		return \OC::$server->query(\OC\AppConfig::class)->getValue($appName, $key, $default);
222
-	}
223
-
224
-	/**
225
-	 * Delete an app wide defined value
226
-	 *
227
-	 * @param string $appName the appName that we stored the value under
228
-	 * @param string $key the key of the value, under which it was saved
229
-	 */
230
-	public function deleteAppValue($appName, $key) {
231
-		\OC::$server->query(\OC\AppConfig::class)->deleteKey($appName, $key);
232
-	}
233
-
234
-	/**
235
-	 * Removes all keys in appconfig belonging to the app
236
-	 *
237
-	 * @param string $appName the appName the configs are stored under
238
-	 */
239
-	public function deleteAppValues($appName) {
240
-		\OC::$server->query(\OC\AppConfig::class)->deleteApp($appName);
241
-	}
242
-
243
-
244
-	/**
245
-	 * Set a user defined value
246
-	 *
247
-	 * @param string $userId the userId of the user that we want to store the value under
248
-	 * @param string $appName the appName that we want to store the value under
249
-	 * @param string $key the key under which the value is being stored
250
-	 * @param string|float|int $value the value that you want to store
251
-	 * @param string $preCondition only update if the config value was previously the value passed as $preCondition
252
-	 * @throws \OCP\PreConditionNotMetException if a precondition is specified and is not met
253
-	 * @throws \UnexpectedValueException when trying to store an unexpected value
254
-	 */
255
-	public function setUserValue($userId, $appName, $key, $value, $preCondition = null) {
256
-		if (!is_int($value) && !is_float($value) && !is_string($value)) {
257
-			throw new \UnexpectedValueException('Only integers, floats and strings are allowed as value');
258
-		}
259
-
260
-		// TODO - FIXME
261
-		$this->fixDIInit();
262
-
263
-		$prevValue = $this->getUserValue($userId, $appName, $key, null);
264
-
265
-		if ($prevValue !== null) {
266
-			if ($prevValue === (string)$value) {
267
-				return;
268
-			} elseif ($preCondition !== null && $prevValue !== (string)$preCondition) {
269
-				throw new PreConditionNotMetException();
270
-			} else {
271
-				$qb = $this->connection->getQueryBuilder();
272
-				$qb->update('preferences')
273
-					->set('configvalue', $qb->createNamedParameter($value))
274
-					->where($qb->expr()->eq('userid', $qb->createNamedParameter($userId)))
275
-					->andWhere($qb->expr()->eq('appid', $qb->createNamedParameter($appName)))
276
-					->andWhere($qb->expr()->eq('configkey', $qb->createNamedParameter($key)));
277
-				$qb->execute();
278
-
279
-				$this->userCache[$userId][$appName][$key] = (string)$value;
280
-				return;
281
-			}
282
-		}
283
-
284
-		$preconditionArray = [];
285
-		if (isset($preCondition)) {
286
-			$preconditionArray = [
287
-				'configvalue' => $preCondition,
288
-			];
289
-		}
290
-
291
-		$this->connection->setValues('preferences', [
292
-			'userid' => $userId,
293
-			'appid' => $appName,
294
-			'configkey' => $key,
295
-		], [
296
-			'configvalue' => $value,
297
-		], $preconditionArray);
298
-
299
-		// only add to the cache if we already loaded data for the user
300
-		if (isset($this->userCache[$userId])) {
301
-			if (!isset($this->userCache[$userId][$appName])) {
302
-				$this->userCache[$userId][$appName] = [];
303
-			}
304
-			$this->userCache[$userId][$appName][$key] = (string)$value;
305
-		}
306
-	}
307
-
308
-	/**
309
-	 * Getting a user defined value
310
-	 *
311
-	 * @param string $userId the userId of the user that we want to store the value under
312
-	 * @param string $appName the appName that we stored the value under
313
-	 * @param string $key the key under which the value is being stored
314
-	 * @param mixed $default the default value to be returned if the value isn't set
315
-	 * @return string
316
-	 */
317
-	public function getUserValue($userId, $appName, $key, $default = '') {
318
-		$data = $this->getUserValues($userId);
319
-		if (isset($data[$appName]) and isset($data[$appName][$key])) {
320
-			return $data[$appName][$key];
321
-		} else {
322
-			return $default;
323
-		}
324
-	}
325
-
326
-	/**
327
-	 * Get the keys of all stored by an app for the user
328
-	 *
329
-	 * @param string $userId the userId of the user that we want to store the value under
330
-	 * @param string $appName the appName that we stored the value under
331
-	 * @return string[]
332
-	 */
333
-	public function getUserKeys($userId, $appName) {
334
-		$data = $this->getUserValues($userId);
335
-		if (isset($data[$appName])) {
336
-			return array_keys($data[$appName]);
337
-		} else {
338
-			return [];
339
-		}
340
-	}
341
-
342
-	/**
343
-	 * Delete a user value
344
-	 *
345
-	 * @param string $userId the userId of the user that we want to store the value under
346
-	 * @param string $appName the appName that we stored the value under
347
-	 * @param string $key the key under which the value is being stored
348
-	 */
349
-	public function deleteUserValue($userId, $appName, $key) {
350
-		// TODO - FIXME
351
-		$this->fixDIInit();
352
-
353
-		$sql  = 'DELETE FROM `*PREFIX*preferences` '.
354
-				'WHERE `userid` = ? AND `appid` = ? AND `configkey` = ?';
355
-		$this->connection->executeUpdate($sql, [$userId, $appName, $key]);
356
-
357
-		if (isset($this->userCache[$userId]) and isset($this->userCache[$userId][$appName])) {
358
-			unset($this->userCache[$userId][$appName][$key]);
359
-		}
360
-	}
361
-
362
-	/**
363
-	 * Delete all user values
364
-	 *
365
-	 * @param string $userId the userId of the user that we want to remove all values from
366
-	 */
367
-	public function deleteAllUserValues($userId) {
368
-		// TODO - FIXME
369
-		$this->fixDIInit();
370
-
371
-		$sql  = 'DELETE FROM `*PREFIX*preferences` '.
372
-			'WHERE `userid` = ?';
373
-		$this->connection->executeUpdate($sql, [$userId]);
374
-
375
-		unset($this->userCache[$userId]);
376
-	}
377
-
378
-	/**
379
-	 * Delete all user related values of one app
380
-	 *
381
-	 * @param string $appName the appName of the app that we want to remove all values from
382
-	 */
383
-	public function deleteAppFromAllUsers($appName) {
384
-		// TODO - FIXME
385
-		$this->fixDIInit();
386
-
387
-		$sql  = 'DELETE FROM `*PREFIX*preferences` '.
388
-				'WHERE `appid` = ?';
389
-		$this->connection->executeUpdate($sql, [$appName]);
390
-
391
-		foreach ($this->userCache as &$userCache) {
392
-			unset($userCache[$appName]);
393
-		}
394
-	}
395
-
396
-	/**
397
-	 * Returns all user configs sorted by app of one user
398
-	 *
399
-	 * @param string $userId the user ID to get the app configs from
400
-	 * @return array[] - 2 dimensional array with the following structure:
401
-	 *     [ $appId =>
402
-	 *         [ $key => $value ]
403
-	 *     ]
404
-	 */
405
-	private function getUserValues($userId) {
406
-		if (isset($this->userCache[$userId])) {
407
-			return $this->userCache[$userId];
408
-		}
409
-		if ($userId === null || $userId === '') {
410
-			$this->userCache[$userId]=[];
411
-			return $this->userCache[$userId];
412
-		}
413
-
414
-		// TODO - FIXME
415
-		$this->fixDIInit();
416
-
417
-		$data = [];
418
-		$query = 'SELECT `appid`, `configkey`, `configvalue` FROM `*PREFIX*preferences` WHERE `userid` = ?';
419
-		$result = $this->connection->executeQuery($query, [$userId]);
420
-		while ($row = $result->fetch()) {
421
-			$appId = $row['appid'];
422
-			if (!isset($data[$appId])) {
423
-				$data[$appId] = [];
424
-			}
425
-			$data[$appId][$row['configkey']] = $row['configvalue'];
426
-		}
427
-		$this->userCache[$userId] = $data;
428
-		return $data;
429
-	}
430
-
431
-	/**
432
-	 * Fetches a mapped list of userId -> value, for a specified app and key and a list of user IDs.
433
-	 *
434
-	 * @param string $appName app to get the value for
435
-	 * @param string $key the key to get the value for
436
-	 * @param array $userIds the user IDs to fetch the values for
437
-	 * @return array Mapped values: userId => value
438
-	 */
439
-	public function getUserValueForUsers($appName, $key, $userIds) {
440
-		// TODO - FIXME
441
-		$this->fixDIInit();
442
-
443
-		if (empty($userIds) || !is_array($userIds)) {
444
-			return [];
445
-		}
446
-
447
-		$chunkedUsers = array_chunk($userIds, 50, true);
448
-		$placeholders50 = implode(',', array_fill(0, 50, '?'));
449
-
450
-		$userValues = [];
451
-		foreach ($chunkedUsers as $chunk) {
452
-			$queryParams = $chunk;
453
-			// create [$app, $key, $chunkedUsers]
454
-			array_unshift($queryParams, $key);
455
-			array_unshift($queryParams, $appName);
456
-
457
-			$placeholders = (count($chunk) === 50) ? $placeholders50 :  implode(',', array_fill(0, count($chunk), '?'));
458
-
459
-			$query    = 'SELECT `userid`, `configvalue` ' .
460
-						'FROM `*PREFIX*preferences` ' .
461
-						'WHERE `appid` = ? AND `configkey` = ? ' .
462
-						'AND `userid` IN (' . $placeholders . ')';
463
-			$result = $this->connection->executeQuery($query, $queryParams);
464
-
465
-			while ($row = $result->fetch()) {
466
-				$userValues[$row['userid']] = $row['configvalue'];
467
-			}
468
-		}
469
-
470
-		return $userValues;
471
-	}
472
-
473
-	/**
474
-	 * Determines the users that have the given value set for a specific app-key-pair
475
-	 *
476
-	 * @param string $appName the app to get the user for
477
-	 * @param string $key the key to get the user for
478
-	 * @param string $value the value to get the user for
479
-	 * @return array of user IDs
480
-	 */
481
-	public function getUsersForUserValue($appName, $key, $value) {
482
-		// TODO - FIXME
483
-		$this->fixDIInit();
484
-
485
-		$sql  = 'SELECT `userid` FROM `*PREFIX*preferences` ' .
486
-				'WHERE `appid` = ? AND `configkey` = ? ';
487
-
488
-		if ($this->getSystemValue('dbtype', 'sqlite') === 'oci') {
489
-			//oracle hack: need to explicitly cast CLOB to CHAR for comparison
490
-			$sql .= 'AND to_char(`configvalue`) = ?';
491
-		} else {
492
-			$sql .= 'AND `configvalue` = ?';
493
-		}
494
-
495
-		$result = $this->connection->executeQuery($sql, [$appName, $key, $value]);
496
-
497
-		$userIDs = [];
498
-		while ($row = $result->fetch()) {
499
-			$userIDs[] = $row['userid'];
500
-		}
501
-
502
-		return $userIDs;
503
-	}
504
-
505
-	/**
506
-	 * Determines the users that have the given value set for a specific app-key-pair
507
-	 *
508
-	 * @param string $appName the app to get the user for
509
-	 * @param string $key the key to get the user for
510
-	 * @param string $value the value to get the user for
511
-	 * @return array of user IDs
512
-	 */
513
-	public function getUsersForUserValueCaseInsensitive($appName, $key, $value) {
514
-		// TODO - FIXME
515
-		$this->fixDIInit();
516
-
517
-		$sql  = 'SELECT `userid` FROM `*PREFIX*preferences` ' .
518
-			'WHERE `appid` = ? AND `configkey` = ? ';
519
-
520
-		if ($this->getSystemValue('dbtype', 'sqlite') === 'oci') {
521
-			//oracle hack: need to explicitly cast CLOB to CHAR for comparison
522
-			$sql .= 'AND LOWER(to_char(`configvalue`)) = LOWER(?)';
523
-		} else {
524
-			$sql .= 'AND LOWER(`configvalue`) = LOWER(?)';
525
-		}
526
-
527
-		$result = $this->connection->executeQuery($sql, [$appName, $key, $value]);
528
-
529
-		$userIDs = [];
530
-		while ($row = $result->fetch()) {
531
-			$userIDs[] = $row['userid'];
532
-		}
533
-
534
-		return $userIDs;
535
-	}
536
-
537
-	public function getSystemConfig() {
538
-		return $this->systemConfig;
539
-	}
43
+    /** @var SystemConfig */
44
+    private $systemConfig;
45
+
46
+    /** @var IDBConnection */
47
+    private $connection;
48
+
49
+    /**
50
+     * 3 dimensional array with the following structure:
51
+     * [ $userId =>
52
+     *     [ $appId =>
53
+     *         [ $key => $value ]
54
+     *     ]
55
+     * ]
56
+     *
57
+     * database table: preferences
58
+     *
59
+     * methods that use this:
60
+     *   - setUserValue
61
+     *   - getUserValue
62
+     *   - getUserKeys
63
+     *   - deleteUserValue
64
+     *   - deleteAllUserValues
65
+     *   - deleteAppFromAllUsers
66
+     *
67
+     * @var CappedMemoryCache $userCache
68
+     */
69
+    private $userCache;
70
+
71
+    /**
72
+     * @param SystemConfig $systemConfig
73
+     */
74
+    public function __construct(SystemConfig $systemConfig) {
75
+        $this->userCache = new CappedMemoryCache();
76
+        $this->systemConfig = $systemConfig;
77
+    }
78
+
79
+    /**
80
+     * TODO - FIXME This fixes an issue with base.php that cause cyclic
81
+     * dependencies, especially with autoconfig setup
82
+     *
83
+     * Replace this by properly injected database connection. Currently the
84
+     * base.php triggers the getDatabaseConnection too early which causes in
85
+     * autoconfig setup case a too early distributed database connection and
86
+     * the autoconfig then needs to reinit all already initialized dependencies
87
+     * that use the database connection.
88
+     *
89
+     * otherwise a SQLite database is created in the wrong directory
90
+     * because the database connection was created with an uninitialized config
91
+     */
92
+    private function fixDIInit() {
93
+        if ($this->connection === null) {
94
+            $this->connection = \OC::$server->getDatabaseConnection();
95
+        }
96
+    }
97
+
98
+    /**
99
+     * Sets and deletes system wide values
100
+     *
101
+     * @param array $configs Associative array with `key => value` pairs
102
+     *                       If value is null, the config key will be deleted
103
+     */
104
+    public function setSystemValues(array $configs) {
105
+        $this->systemConfig->setValues($configs);
106
+    }
107
+
108
+    /**
109
+     * Sets a new system wide value
110
+     *
111
+     * @param string $key the key of the value, under which will be saved
112
+     * @param mixed $value the value that should be stored
113
+     */
114
+    public function setSystemValue($key, $value) {
115
+        $this->systemConfig->setValue($key, $value);
116
+    }
117
+
118
+    /**
119
+     * Looks up a system wide defined value
120
+     *
121
+     * @param string $key the key of the value, under which it was saved
122
+     * @param mixed $default the default value to be returned if the value isn't set
123
+     * @return mixed the value or $default
124
+     */
125
+    public function getSystemValue($key, $default = '') {
126
+        return $this->systemConfig->getValue($key, $default);
127
+    }
128
+
129
+    /**
130
+     * Looks up a boolean system wide defined value
131
+     *
132
+     * @param string $key the key of the value, under which it was saved
133
+     * @param bool $default the default value to be returned if the value isn't set
134
+     *
135
+     * @return bool
136
+     *
137
+     * @since 16.0.0
138
+     */
139
+    public function getSystemValueBool(string $key, bool $default = false): bool {
140
+        return (bool) $this->getSystemValue($key, $default);
141
+    }
142
+
143
+    /**
144
+     * Looks up an integer system wide defined value
145
+     *
146
+     * @param string $key the key of the value, under which it was saved
147
+     * @param int $default the default value to be returned if the value isn't set
148
+     *
149
+     * @return int
150
+     *
151
+     * @since 16.0.0
152
+     */
153
+    public function getSystemValueInt(string $key, int $default = 0): int {
154
+        return (int) $this->getSystemValue($key, $default);
155
+    }
156
+
157
+    /**
158
+     * Looks up a string system wide defined value
159
+     *
160
+     * @param string $key the key of the value, under which it was saved
161
+     * @param string $default the default value to be returned if the value isn't set
162
+     *
163
+     * @return string
164
+     *
165
+     * @since 16.0.0
166
+     */
167
+    public function getSystemValueString(string $key, string $default = ''): string {
168
+        return (string) $this->getSystemValue($key, $default);
169
+    }
170
+
171
+    /**
172
+     * Looks up a system wide defined value and filters out sensitive data
173
+     *
174
+     * @param string $key the key of the value, under which it was saved
175
+     * @param mixed $default the default value to be returned if the value isn't set
176
+     * @return mixed the value or $default
177
+     */
178
+    public function getFilteredSystemValue($key, $default = '') {
179
+        return $this->systemConfig->getFilteredValue($key, $default);
180
+    }
181
+
182
+    /**
183
+     * Delete a system wide defined value
184
+     *
185
+     * @param string $key the key of the value, under which it was saved
186
+     */
187
+    public function deleteSystemValue($key) {
188
+        $this->systemConfig->deleteValue($key);
189
+    }
190
+
191
+    /**
192
+     * Get all keys stored for an app
193
+     *
194
+     * @param string $appName the appName that we stored the value under
195
+     * @return string[] the keys stored for the app
196
+     */
197
+    public function getAppKeys($appName) {
198
+        return \OC::$server->query(\OC\AppConfig::class)->getKeys($appName);
199
+    }
200
+
201
+    /**
202
+     * Writes a new app wide value
203
+     *
204
+     * @param string $appName the appName that we want to store the value under
205
+     * @param string $key the key of the value, under which will be saved
206
+     * @param string|float|int $value the value that should be stored
207
+     */
208
+    public function setAppValue($appName, $key, $value) {
209
+        \OC::$server->query(\OC\AppConfig::class)->setValue($appName, $key, $value);
210
+    }
211
+
212
+    /**
213
+     * Looks up an app wide defined value
214
+     *
215
+     * @param string $appName the appName that we stored the value under
216
+     * @param string $key the key of the value, under which it was saved
217
+     * @param string $default the default value to be returned if the value isn't set
218
+     * @return string the saved value
219
+     */
220
+    public function getAppValue($appName, $key, $default = '') {
221
+        return \OC::$server->query(\OC\AppConfig::class)->getValue($appName, $key, $default);
222
+    }
223
+
224
+    /**
225
+     * Delete an app wide defined value
226
+     *
227
+     * @param string $appName the appName that we stored the value under
228
+     * @param string $key the key of the value, under which it was saved
229
+     */
230
+    public function deleteAppValue($appName, $key) {
231
+        \OC::$server->query(\OC\AppConfig::class)->deleteKey($appName, $key);
232
+    }
233
+
234
+    /**
235
+     * Removes all keys in appconfig belonging to the app
236
+     *
237
+     * @param string $appName the appName the configs are stored under
238
+     */
239
+    public function deleteAppValues($appName) {
240
+        \OC::$server->query(\OC\AppConfig::class)->deleteApp($appName);
241
+    }
242
+
243
+
244
+    /**
245
+     * Set a user defined value
246
+     *
247
+     * @param string $userId the userId of the user that we want to store the value under
248
+     * @param string $appName the appName that we want to store the value under
249
+     * @param string $key the key under which the value is being stored
250
+     * @param string|float|int $value the value that you want to store
251
+     * @param string $preCondition only update if the config value was previously the value passed as $preCondition
252
+     * @throws \OCP\PreConditionNotMetException if a precondition is specified and is not met
253
+     * @throws \UnexpectedValueException when trying to store an unexpected value
254
+     */
255
+    public function setUserValue($userId, $appName, $key, $value, $preCondition = null) {
256
+        if (!is_int($value) && !is_float($value) && !is_string($value)) {
257
+            throw new \UnexpectedValueException('Only integers, floats and strings are allowed as value');
258
+        }
259
+
260
+        // TODO - FIXME
261
+        $this->fixDIInit();
262
+
263
+        $prevValue = $this->getUserValue($userId, $appName, $key, null);
264
+
265
+        if ($prevValue !== null) {
266
+            if ($prevValue === (string)$value) {
267
+                return;
268
+            } elseif ($preCondition !== null && $prevValue !== (string)$preCondition) {
269
+                throw new PreConditionNotMetException();
270
+            } else {
271
+                $qb = $this->connection->getQueryBuilder();
272
+                $qb->update('preferences')
273
+                    ->set('configvalue', $qb->createNamedParameter($value))
274
+                    ->where($qb->expr()->eq('userid', $qb->createNamedParameter($userId)))
275
+                    ->andWhere($qb->expr()->eq('appid', $qb->createNamedParameter($appName)))
276
+                    ->andWhere($qb->expr()->eq('configkey', $qb->createNamedParameter($key)));
277
+                $qb->execute();
278
+
279
+                $this->userCache[$userId][$appName][$key] = (string)$value;
280
+                return;
281
+            }
282
+        }
283
+
284
+        $preconditionArray = [];
285
+        if (isset($preCondition)) {
286
+            $preconditionArray = [
287
+                'configvalue' => $preCondition,
288
+            ];
289
+        }
290
+
291
+        $this->connection->setValues('preferences', [
292
+            'userid' => $userId,
293
+            'appid' => $appName,
294
+            'configkey' => $key,
295
+        ], [
296
+            'configvalue' => $value,
297
+        ], $preconditionArray);
298
+
299
+        // only add to the cache if we already loaded data for the user
300
+        if (isset($this->userCache[$userId])) {
301
+            if (!isset($this->userCache[$userId][$appName])) {
302
+                $this->userCache[$userId][$appName] = [];
303
+            }
304
+            $this->userCache[$userId][$appName][$key] = (string)$value;
305
+        }
306
+    }
307
+
308
+    /**
309
+     * Getting a user defined value
310
+     *
311
+     * @param string $userId the userId of the user that we want to store the value under
312
+     * @param string $appName the appName that we stored the value under
313
+     * @param string $key the key under which the value is being stored
314
+     * @param mixed $default the default value to be returned if the value isn't set
315
+     * @return string
316
+     */
317
+    public function getUserValue($userId, $appName, $key, $default = '') {
318
+        $data = $this->getUserValues($userId);
319
+        if (isset($data[$appName]) and isset($data[$appName][$key])) {
320
+            return $data[$appName][$key];
321
+        } else {
322
+            return $default;
323
+        }
324
+    }
325
+
326
+    /**
327
+     * Get the keys of all stored by an app for the user
328
+     *
329
+     * @param string $userId the userId of the user that we want to store the value under
330
+     * @param string $appName the appName that we stored the value under
331
+     * @return string[]
332
+     */
333
+    public function getUserKeys($userId, $appName) {
334
+        $data = $this->getUserValues($userId);
335
+        if (isset($data[$appName])) {
336
+            return array_keys($data[$appName]);
337
+        } else {
338
+            return [];
339
+        }
340
+    }
341
+
342
+    /**
343
+     * Delete a user value
344
+     *
345
+     * @param string $userId the userId of the user that we want to store the value under
346
+     * @param string $appName the appName that we stored the value under
347
+     * @param string $key the key under which the value is being stored
348
+     */
349
+    public function deleteUserValue($userId, $appName, $key) {
350
+        // TODO - FIXME
351
+        $this->fixDIInit();
352
+
353
+        $sql  = 'DELETE FROM `*PREFIX*preferences` '.
354
+                'WHERE `userid` = ? AND `appid` = ? AND `configkey` = ?';
355
+        $this->connection->executeUpdate($sql, [$userId, $appName, $key]);
356
+
357
+        if (isset($this->userCache[$userId]) and isset($this->userCache[$userId][$appName])) {
358
+            unset($this->userCache[$userId][$appName][$key]);
359
+        }
360
+    }
361
+
362
+    /**
363
+     * Delete all user values
364
+     *
365
+     * @param string $userId the userId of the user that we want to remove all values from
366
+     */
367
+    public function deleteAllUserValues($userId) {
368
+        // TODO - FIXME
369
+        $this->fixDIInit();
370
+
371
+        $sql  = 'DELETE FROM `*PREFIX*preferences` '.
372
+            'WHERE `userid` = ?';
373
+        $this->connection->executeUpdate($sql, [$userId]);
374
+
375
+        unset($this->userCache[$userId]);
376
+    }
377
+
378
+    /**
379
+     * Delete all user related values of one app
380
+     *
381
+     * @param string $appName the appName of the app that we want to remove all values from
382
+     */
383
+    public function deleteAppFromAllUsers($appName) {
384
+        // TODO - FIXME
385
+        $this->fixDIInit();
386
+
387
+        $sql  = 'DELETE FROM `*PREFIX*preferences` '.
388
+                'WHERE `appid` = ?';
389
+        $this->connection->executeUpdate($sql, [$appName]);
390
+
391
+        foreach ($this->userCache as &$userCache) {
392
+            unset($userCache[$appName]);
393
+        }
394
+    }
395
+
396
+    /**
397
+     * Returns all user configs sorted by app of one user
398
+     *
399
+     * @param string $userId the user ID to get the app configs from
400
+     * @return array[] - 2 dimensional array with the following structure:
401
+     *     [ $appId =>
402
+     *         [ $key => $value ]
403
+     *     ]
404
+     */
405
+    private function getUserValues($userId) {
406
+        if (isset($this->userCache[$userId])) {
407
+            return $this->userCache[$userId];
408
+        }
409
+        if ($userId === null || $userId === '') {
410
+            $this->userCache[$userId]=[];
411
+            return $this->userCache[$userId];
412
+        }
413
+
414
+        // TODO - FIXME
415
+        $this->fixDIInit();
416
+
417
+        $data = [];
418
+        $query = 'SELECT `appid`, `configkey`, `configvalue` FROM `*PREFIX*preferences` WHERE `userid` = ?';
419
+        $result = $this->connection->executeQuery($query, [$userId]);
420
+        while ($row = $result->fetch()) {
421
+            $appId = $row['appid'];
422
+            if (!isset($data[$appId])) {
423
+                $data[$appId] = [];
424
+            }
425
+            $data[$appId][$row['configkey']] = $row['configvalue'];
426
+        }
427
+        $this->userCache[$userId] = $data;
428
+        return $data;
429
+    }
430
+
431
+    /**
432
+     * Fetches a mapped list of userId -> value, for a specified app and key and a list of user IDs.
433
+     *
434
+     * @param string $appName app to get the value for
435
+     * @param string $key the key to get the value for
436
+     * @param array $userIds the user IDs to fetch the values for
437
+     * @return array Mapped values: userId => value
438
+     */
439
+    public function getUserValueForUsers($appName, $key, $userIds) {
440
+        // TODO - FIXME
441
+        $this->fixDIInit();
442
+
443
+        if (empty($userIds) || !is_array($userIds)) {
444
+            return [];
445
+        }
446
+
447
+        $chunkedUsers = array_chunk($userIds, 50, true);
448
+        $placeholders50 = implode(',', array_fill(0, 50, '?'));
449
+
450
+        $userValues = [];
451
+        foreach ($chunkedUsers as $chunk) {
452
+            $queryParams = $chunk;
453
+            // create [$app, $key, $chunkedUsers]
454
+            array_unshift($queryParams, $key);
455
+            array_unshift($queryParams, $appName);
456
+
457
+            $placeholders = (count($chunk) === 50) ? $placeholders50 :  implode(',', array_fill(0, count($chunk), '?'));
458
+
459
+            $query    = 'SELECT `userid`, `configvalue` ' .
460
+                        'FROM `*PREFIX*preferences` ' .
461
+                        'WHERE `appid` = ? AND `configkey` = ? ' .
462
+                        'AND `userid` IN (' . $placeholders . ')';
463
+            $result = $this->connection->executeQuery($query, $queryParams);
464
+
465
+            while ($row = $result->fetch()) {
466
+                $userValues[$row['userid']] = $row['configvalue'];
467
+            }
468
+        }
469
+
470
+        return $userValues;
471
+    }
472
+
473
+    /**
474
+     * Determines the users that have the given value set for a specific app-key-pair
475
+     *
476
+     * @param string $appName the app to get the user for
477
+     * @param string $key the key to get the user for
478
+     * @param string $value the value to get the user for
479
+     * @return array of user IDs
480
+     */
481
+    public function getUsersForUserValue($appName, $key, $value) {
482
+        // TODO - FIXME
483
+        $this->fixDIInit();
484
+
485
+        $sql  = 'SELECT `userid` FROM `*PREFIX*preferences` ' .
486
+                'WHERE `appid` = ? AND `configkey` = ? ';
487
+
488
+        if ($this->getSystemValue('dbtype', 'sqlite') === 'oci') {
489
+            //oracle hack: need to explicitly cast CLOB to CHAR for comparison
490
+            $sql .= 'AND to_char(`configvalue`) = ?';
491
+        } else {
492
+            $sql .= 'AND `configvalue` = ?';
493
+        }
494
+
495
+        $result = $this->connection->executeQuery($sql, [$appName, $key, $value]);
496
+
497
+        $userIDs = [];
498
+        while ($row = $result->fetch()) {
499
+            $userIDs[] = $row['userid'];
500
+        }
501
+
502
+        return $userIDs;
503
+    }
504
+
505
+    /**
506
+     * Determines the users that have the given value set for a specific app-key-pair
507
+     *
508
+     * @param string $appName the app to get the user for
509
+     * @param string $key the key to get the user for
510
+     * @param string $value the value to get the user for
511
+     * @return array of user IDs
512
+     */
513
+    public function getUsersForUserValueCaseInsensitive($appName, $key, $value) {
514
+        // TODO - FIXME
515
+        $this->fixDIInit();
516
+
517
+        $sql  = 'SELECT `userid` FROM `*PREFIX*preferences` ' .
518
+            'WHERE `appid` = ? AND `configkey` = ? ';
519
+
520
+        if ($this->getSystemValue('dbtype', 'sqlite') === 'oci') {
521
+            //oracle hack: need to explicitly cast CLOB to CHAR for comparison
522
+            $sql .= 'AND LOWER(to_char(`configvalue`)) = LOWER(?)';
523
+        } else {
524
+            $sql .= 'AND LOWER(`configvalue`) = LOWER(?)';
525
+        }
526
+
527
+        $result = $this->connection->executeQuery($sql, [$appName, $key, $value]);
528
+
529
+        $userIDs = [];
530
+        while ($row = $result->fetch()) {
531
+            $userIDs[] = $row['userid'];
532
+        }
533
+
534
+        return $userIDs;
535
+    }
536
+
537
+    public function getSystemConfig() {
538
+        return $this->systemConfig;
539
+    }
540 540
 }
Please login to merge, or discard this patch.