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