Passed
Push — master ( 8b4d49...014a63 )
by Joas
14:50 queued 13s
created
lib/private/AppConfig.php 1 patch
Indentation   +387 added lines, -387 removed lines patch added patch discarded remove patch
@@ -43,400 +43,400 @@
 block discarded – undo
43 43
  * database.
44 44
  */
45 45
 class AppConfig implements IAppConfig {
46
-	/** @var array[] */
47
-	protected $sensitiveValues = [
48
-		'circles' => [
49
-			'/^key_pairs$/',
50
-			'/^local_gskey$/',
51
-		],
52
-		'external' => [
53
-			'/^sites$/',
54
-		],
55
-		'integration_discourse' => [
56
-			'/^private_key$/',
57
-			'/^public_key$/',
58
-		],
59
-		'integration_dropbox' => [
60
-			'/^client_id$/',
61
-			'/^client_secret$/',
62
-		],
63
-		'integration_github' => [
64
-			'/^client_id$/',
65
-			'/^client_secret$/',
66
-		],
67
-		'integration_gitlab' => [
68
-			'/^client_id$/',
69
-			'/^client_secret$/',
70
-			'/^oauth_instance_url$/',
71
-		],
72
-		'integration_google' => [
73
-			'/^client_id$/',
74
-			'/^client_secret$/',
75
-		],
76
-		'integration_jira' => [
77
-			'/^client_id$/',
78
-			'/^client_secret$/',
79
-			'/^forced_instance_url$/',
80
-		],
81
-		'integration_onedrive' => [
82
-			'/^client_id$/',
83
-			'/^client_secret$/',
84
-		],
85
-		'integration_openproject' => [
86
-			'/^client_id$/',
87
-			'/^client_secret$/',
88
-			'/^oauth_instance_url$/',
89
-		],
90
-		'integration_reddit' => [
91
-			'/^client_id$/',
92
-			'/^client_secret$/',
93
-		],
94
-		'integration_suitecrm' => [
95
-			'/^client_id$/',
96
-			'/^client_secret$/',
97
-			'/^oauth_instance_url$/',
98
-		],
99
-		'integration_twitter' => [
100
-			'/^consumer_key$/',
101
-			'/^consumer_secret$/',
102
-			'/^followed_user$/',
103
-		],
104
-		'integration_zammad' => [
105
-			'/^client_id$/',
106
-			'/^client_secret$/',
107
-			'/^oauth_instance_url$/',
108
-		],
109
-		'notify_push' => [
110
-			'/^cookie$/',
111
-		],
112
-		'spreed' => [
113
-			'/^bridge_bot_password$/',
114
-			'/^hosted-signaling-server-(.*)$/',
115
-			'/^recording_servers$/',
116
-			'/^signaling_servers$/',
117
-			'/^signaling_ticket_secret$/',
118
-			'/^signaling_token_privkey_(.*)$/',
119
-			'/^signaling_token_pubkey_(.*)$/',
120
-			'/^sip_bridge_dialin_info$/',
121
-			'/^sip_bridge_shared_secret$/',
122
-			'/^stun_servers$/',
123
-			'/^turn_servers$/',
124
-			'/^turn_server_secret$/',
125
-		],
126
-		'support' => [
127
-			'/^last_response$/',
128
-			'/^potential_subscription_key$/',
129
-			'/^subscription_key$/',
130
-		],
131
-		'theming' => [
132
-			'/^imprintUrl$/',
133
-			'/^privacyUrl$/',
134
-			'/^slogan$/',
135
-			'/^url$/',
136
-		],
137
-		'user_ldap' => [
138
-			'/^(s..)?ldap_agent_password$/',
139
-		],
140
-		'user_saml' => [
141
-			'/^idp-x509cert$/',
142
-		],
143
-	];
144
-
145
-	/** @var Connection */
146
-	protected $conn;
147
-
148
-	/** @var array[] */
149
-	private $cache = [];
150
-
151
-	/** @var bool */
152
-	private $configLoaded = false;
153
-
154
-	/**
155
-	 * @param Connection $conn
156
-	 */
157
-	public function __construct(Connection $conn) {
158
-		$this->conn = $conn;
159
-	}
160
-
161
-	/**
162
-	 * @param string $app
163
-	 * @return array
164
-	 */
165
-	private function getAppValues($app) {
166
-		$this->loadConfigValues();
167
-
168
-		if (isset($this->cache[$app])) {
169
-			return $this->cache[$app];
170
-		}
171
-
172
-		return [];
173
-	}
174
-
175
-	/**
176
-	 * Get all apps using the config
177
-	 *
178
-	 * @return array an array of app ids
179
-	 *
180
-	 * This function returns a list of all apps that have at least one
181
-	 * entry in the appconfig table.
182
-	 */
183
-	public function getApps() {
184
-		$this->loadConfigValues();
185
-
186
-		return $this->getSortedKeys($this->cache);
187
-	}
188
-
189
-	/**
190
-	 * Get the available keys for an app
191
-	 *
192
-	 * @param string $app the app we are looking for
193
-	 * @return array an array of key names
194
-	 *
195
-	 * This function gets all keys of an app. Please note that the values are
196
-	 * not returned.
197
-	 */
198
-	public function getKeys($app) {
199
-		$this->loadConfigValues();
200
-
201
-		if (isset($this->cache[$app])) {
202
-			return $this->getSortedKeys($this->cache[$app]);
203
-		}
204
-
205
-		return [];
206
-	}
207
-
208
-	public function getSortedKeys($data) {
209
-		$keys = array_keys($data);
210
-		sort($keys);
211
-		return $keys;
212
-	}
213
-
214
-	/**
215
-	 * Gets the config value
216
-	 *
217
-	 * @param string $app app
218
-	 * @param string $key key
219
-	 * @param string $default = null, default value if the key does not exist
220
-	 * @return string the value or $default
221
-	 *
222
-	 * This function gets a value from the appconfig table. If the key does
223
-	 * not exist the default value will be returned
224
-	 */
225
-	public function getValue($app, $key, $default = null) {
226
-		$this->loadConfigValues();
227
-
228
-		if ($this->hasKey($app, $key)) {
229
-			return $this->cache[$app][$key];
230
-		}
231
-
232
-		return $default;
233
-	}
234
-
235
-	/**
236
-	 * check if a key is set in the appconfig
237
-	 *
238
-	 * @param string $app
239
-	 * @param string $key
240
-	 * @return bool
241
-	 */
242
-	public function hasKey($app, $key) {
243
-		$this->loadConfigValues();
244
-
245
-		return isset($this->cache[$app][$key]);
246
-	}
247
-
248
-	/**
249
-	 * Sets a value. If the key did not exist before it will be created.
250
-	 *
251
-	 * @param string $app app
252
-	 * @param string $key key
253
-	 * @param string|float|int $value value
254
-	 * @return bool True if the value was inserted or updated, false if the value was the same
255
-	 */
256
-	public function setValue($app, $key, $value) {
257
-		if (!$this->hasKey($app, $key)) {
258
-			$inserted = (bool) $this->conn->insertIfNotExist('*PREFIX*appconfig', [
259
-				'appid' => $app,
260
-				'configkey' => $key,
261
-				'configvalue' => $value,
262
-			], [
263
-				'appid',
264
-				'configkey',
265
-			]);
266
-
267
-			if ($inserted) {
268
-				if (!isset($this->cache[$app])) {
269
-					$this->cache[$app] = [];
270
-				}
271
-
272
-				$this->cache[$app][$key] = $value;
273
-				return true;
274
-			}
275
-		}
276
-
277
-		$sql = $this->conn->getQueryBuilder();
278
-		$sql->update('appconfig')
279
-			->set('configvalue', $sql->createNamedParameter($value))
280
-			->where($sql->expr()->eq('appid', $sql->createNamedParameter($app)))
281
-			->andWhere($sql->expr()->eq('configkey', $sql->createNamedParameter($key)));
282
-
283
-		/*
46
+    /** @var array[] */
47
+    protected $sensitiveValues = [
48
+        'circles' => [
49
+            '/^key_pairs$/',
50
+            '/^local_gskey$/',
51
+        ],
52
+        'external' => [
53
+            '/^sites$/',
54
+        ],
55
+        'integration_discourse' => [
56
+            '/^private_key$/',
57
+            '/^public_key$/',
58
+        ],
59
+        'integration_dropbox' => [
60
+            '/^client_id$/',
61
+            '/^client_secret$/',
62
+        ],
63
+        'integration_github' => [
64
+            '/^client_id$/',
65
+            '/^client_secret$/',
66
+        ],
67
+        'integration_gitlab' => [
68
+            '/^client_id$/',
69
+            '/^client_secret$/',
70
+            '/^oauth_instance_url$/',
71
+        ],
72
+        'integration_google' => [
73
+            '/^client_id$/',
74
+            '/^client_secret$/',
75
+        ],
76
+        'integration_jira' => [
77
+            '/^client_id$/',
78
+            '/^client_secret$/',
79
+            '/^forced_instance_url$/',
80
+        ],
81
+        'integration_onedrive' => [
82
+            '/^client_id$/',
83
+            '/^client_secret$/',
84
+        ],
85
+        'integration_openproject' => [
86
+            '/^client_id$/',
87
+            '/^client_secret$/',
88
+            '/^oauth_instance_url$/',
89
+        ],
90
+        'integration_reddit' => [
91
+            '/^client_id$/',
92
+            '/^client_secret$/',
93
+        ],
94
+        'integration_suitecrm' => [
95
+            '/^client_id$/',
96
+            '/^client_secret$/',
97
+            '/^oauth_instance_url$/',
98
+        ],
99
+        'integration_twitter' => [
100
+            '/^consumer_key$/',
101
+            '/^consumer_secret$/',
102
+            '/^followed_user$/',
103
+        ],
104
+        'integration_zammad' => [
105
+            '/^client_id$/',
106
+            '/^client_secret$/',
107
+            '/^oauth_instance_url$/',
108
+        ],
109
+        'notify_push' => [
110
+            '/^cookie$/',
111
+        ],
112
+        'spreed' => [
113
+            '/^bridge_bot_password$/',
114
+            '/^hosted-signaling-server-(.*)$/',
115
+            '/^recording_servers$/',
116
+            '/^signaling_servers$/',
117
+            '/^signaling_ticket_secret$/',
118
+            '/^signaling_token_privkey_(.*)$/',
119
+            '/^signaling_token_pubkey_(.*)$/',
120
+            '/^sip_bridge_dialin_info$/',
121
+            '/^sip_bridge_shared_secret$/',
122
+            '/^stun_servers$/',
123
+            '/^turn_servers$/',
124
+            '/^turn_server_secret$/',
125
+        ],
126
+        'support' => [
127
+            '/^last_response$/',
128
+            '/^potential_subscription_key$/',
129
+            '/^subscription_key$/',
130
+        ],
131
+        'theming' => [
132
+            '/^imprintUrl$/',
133
+            '/^privacyUrl$/',
134
+            '/^slogan$/',
135
+            '/^url$/',
136
+        ],
137
+        'user_ldap' => [
138
+            '/^(s..)?ldap_agent_password$/',
139
+        ],
140
+        'user_saml' => [
141
+            '/^idp-x509cert$/',
142
+        ],
143
+    ];
144
+
145
+    /** @var Connection */
146
+    protected $conn;
147
+
148
+    /** @var array[] */
149
+    private $cache = [];
150
+
151
+    /** @var bool */
152
+    private $configLoaded = false;
153
+
154
+    /**
155
+     * @param Connection $conn
156
+     */
157
+    public function __construct(Connection $conn) {
158
+        $this->conn = $conn;
159
+    }
160
+
161
+    /**
162
+     * @param string $app
163
+     * @return array
164
+     */
165
+    private function getAppValues($app) {
166
+        $this->loadConfigValues();
167
+
168
+        if (isset($this->cache[$app])) {
169
+            return $this->cache[$app];
170
+        }
171
+
172
+        return [];
173
+    }
174
+
175
+    /**
176
+     * Get all apps using the config
177
+     *
178
+     * @return array an array of app ids
179
+     *
180
+     * This function returns a list of all apps that have at least one
181
+     * entry in the appconfig table.
182
+     */
183
+    public function getApps() {
184
+        $this->loadConfigValues();
185
+
186
+        return $this->getSortedKeys($this->cache);
187
+    }
188
+
189
+    /**
190
+     * Get the available keys for an app
191
+     *
192
+     * @param string $app the app we are looking for
193
+     * @return array an array of key names
194
+     *
195
+     * This function gets all keys of an app. Please note that the values are
196
+     * not returned.
197
+     */
198
+    public function getKeys($app) {
199
+        $this->loadConfigValues();
200
+
201
+        if (isset($this->cache[$app])) {
202
+            return $this->getSortedKeys($this->cache[$app]);
203
+        }
204
+
205
+        return [];
206
+    }
207
+
208
+    public function getSortedKeys($data) {
209
+        $keys = array_keys($data);
210
+        sort($keys);
211
+        return $keys;
212
+    }
213
+
214
+    /**
215
+     * Gets the config value
216
+     *
217
+     * @param string $app app
218
+     * @param string $key key
219
+     * @param string $default = null, default value if the key does not exist
220
+     * @return string the value or $default
221
+     *
222
+     * This function gets a value from the appconfig table. If the key does
223
+     * not exist the default value will be returned
224
+     */
225
+    public function getValue($app, $key, $default = null) {
226
+        $this->loadConfigValues();
227
+
228
+        if ($this->hasKey($app, $key)) {
229
+            return $this->cache[$app][$key];
230
+        }
231
+
232
+        return $default;
233
+    }
234
+
235
+    /**
236
+     * check if a key is set in the appconfig
237
+     *
238
+     * @param string $app
239
+     * @param string $key
240
+     * @return bool
241
+     */
242
+    public function hasKey($app, $key) {
243
+        $this->loadConfigValues();
244
+
245
+        return isset($this->cache[$app][$key]);
246
+    }
247
+
248
+    /**
249
+     * Sets a value. If the key did not exist before it will be created.
250
+     *
251
+     * @param string $app app
252
+     * @param string $key key
253
+     * @param string|float|int $value value
254
+     * @return bool True if the value was inserted or updated, false if the value was the same
255
+     */
256
+    public function setValue($app, $key, $value) {
257
+        if (!$this->hasKey($app, $key)) {
258
+            $inserted = (bool) $this->conn->insertIfNotExist('*PREFIX*appconfig', [
259
+                'appid' => $app,
260
+                'configkey' => $key,
261
+                'configvalue' => $value,
262
+            ], [
263
+                'appid',
264
+                'configkey',
265
+            ]);
266
+
267
+            if ($inserted) {
268
+                if (!isset($this->cache[$app])) {
269
+                    $this->cache[$app] = [];
270
+                }
271
+
272
+                $this->cache[$app][$key] = $value;
273
+                return true;
274
+            }
275
+        }
276
+
277
+        $sql = $this->conn->getQueryBuilder();
278
+        $sql->update('appconfig')
279
+            ->set('configvalue', $sql->createNamedParameter($value))
280
+            ->where($sql->expr()->eq('appid', $sql->createNamedParameter($app)))
281
+            ->andWhere($sql->expr()->eq('configkey', $sql->createNamedParameter($key)));
282
+
283
+        /*
284 284
 		 * Only limit to the existing value for non-Oracle DBs:
285 285
 		 * http://docs.oracle.com/cd/E11882_01/server.112/e26088/conditions002.htm#i1033286
286 286
 		 * > Large objects (LOBs) are not supported in comparison conditions.
287 287
 		 */
288
-		if (!($this->conn instanceof OracleConnection)) {
289
-			/*
288
+        if (!($this->conn instanceof OracleConnection)) {
289
+            /*
290 290
 			 * Only update the value when it is not the same
291 291
 			 * Note that NULL requires some special handling. Since comparing
292 292
 			 * against null can have special results.
293 293
 			 */
294 294
 
295
-			if ($value === null) {
296
-				$sql->andWhere(
297
-					$sql->expr()->isNotNull('configvalue')
298
-				);
299
-			} else {
300
-				$sql->andWhere(
301
-					$sql->expr()->orX(
302
-						$sql->expr()->isNull('configvalue'),
303
-						$sql->expr()->neq('configvalue', $sql->createNamedParameter($value), IQueryBuilder::PARAM_STR)
304
-					)
305
-				);
306
-			}
307
-		}
308
-
309
-		$changedRow = (bool) $sql->execute();
310
-
311
-		$this->cache[$app][$key] = $value;
312
-
313
-		return $changedRow;
314
-	}
315
-
316
-	/**
317
-	 * Deletes a key
318
-	 *
319
-	 * @param string $app app
320
-	 * @param string $key key
321
-	 * @return boolean
322
-	 */
323
-	public function deleteKey($app, $key) {
324
-		$this->loadConfigValues();
325
-
326
-		$sql = $this->conn->getQueryBuilder();
327
-		$sql->delete('appconfig')
328
-			->where($sql->expr()->eq('appid', $sql->createParameter('app')))
329
-			->andWhere($sql->expr()->eq('configkey', $sql->createParameter('configkey')))
330
-			->setParameter('app', $app)
331
-			->setParameter('configkey', $key);
332
-		$sql->execute();
333
-
334
-		unset($this->cache[$app][$key]);
335
-		return false;
336
-	}
337
-
338
-	/**
339
-	 * Remove app from appconfig
340
-	 *
341
-	 * @param string $app app
342
-	 * @return boolean
343
-	 *
344
-	 * Removes all keys in appconfig belonging to the app.
345
-	 */
346
-	public function deleteApp($app) {
347
-		$this->loadConfigValues();
348
-
349
-		$sql = $this->conn->getQueryBuilder();
350
-		$sql->delete('appconfig')
351
-			->where($sql->expr()->eq('appid', $sql->createParameter('app')))
352
-			->setParameter('app', $app);
353
-		$sql->execute();
354
-
355
-		unset($this->cache[$app]);
356
-		return false;
357
-	}
358
-
359
-	/**
360
-	 * get multiple values, either the app or key can be used as wildcard by setting it to false
361
-	 *
362
-	 * @param string|false $app
363
-	 * @param string|false $key
364
-	 * @return array|false
365
-	 */
366
-	public function getValues($app, $key) {
367
-		if (($app !== false) === ($key !== false)) {
368
-			return false;
369
-		}
370
-
371
-		if ($key === false) {
372
-			return $this->getAppValues($app);
373
-		} else {
374
-			$appIds = $this->getApps();
375
-			$values = array_map(function ($appId) use ($key) {
376
-				return isset($this->cache[$appId][$key]) ? $this->cache[$appId][$key] : null;
377
-			}, $appIds);
378
-			$result = array_combine($appIds, $values);
379
-
380
-			return array_filter($result);
381
-		}
382
-	}
383
-
384
-	/**
385
-	 * get all values of the app or and filters out sensitive data
386
-	 *
387
-	 * @param string $app
388
-	 * @return array
389
-	 */
390
-	public function getFilteredValues($app) {
391
-		$values = $this->getValues($app, false);
392
-
393
-		if (isset($this->sensitiveValues[$app])) {
394
-			foreach ($this->sensitiveValues[$app] as $sensitiveKeyExp) {
395
-				$sensitiveKeys = preg_grep($sensitiveKeyExp, array_keys($values));
396
-				foreach ($sensitiveKeys as $sensitiveKey) {
397
-					$values[$sensitiveKey] = IConfig::SENSITIVE_VALUE;
398
-				}
399
-			}
400
-		}
401
-
402
-		return $values;
403
-	}
404
-
405
-	/**
406
-	 * Load all the app config values
407
-	 */
408
-	protected function loadConfigValues() {
409
-		if ($this->configLoaded) {
410
-			return;
411
-		}
412
-
413
-		$this->cache = [];
414
-
415
-		$sql = $this->conn->getQueryBuilder();
416
-		$sql->select('*')
417
-			->from('appconfig');
418
-		$result = $sql->execute();
419
-
420
-		// we are going to store the result in memory anyway
421
-		$rows = $result->fetchAll();
422
-		foreach ($rows as $row) {
423
-			if (!isset($this->cache[$row['appid']])) {
424
-				$this->cache[(string)$row['appid']] = [];
425
-			}
426
-
427
-			$this->cache[(string)$row['appid']][(string)$row['configkey']] = (string)$row['configvalue'];
428
-		}
429
-		$result->closeCursor();
430
-
431
-		$this->configLoaded = true;
432
-	}
433
-
434
-
435
-	/**
436
-	 * Clear all the cached app config values
437
-	 * New cache will be generated next time a config value is retrieved
438
-	 */
439
-	public function clearCachedConfig(): void {
440
-		$this->configLoaded = false;
441
-	}
295
+            if ($value === null) {
296
+                $sql->andWhere(
297
+                    $sql->expr()->isNotNull('configvalue')
298
+                );
299
+            } else {
300
+                $sql->andWhere(
301
+                    $sql->expr()->orX(
302
+                        $sql->expr()->isNull('configvalue'),
303
+                        $sql->expr()->neq('configvalue', $sql->createNamedParameter($value), IQueryBuilder::PARAM_STR)
304
+                    )
305
+                );
306
+            }
307
+        }
308
+
309
+        $changedRow = (bool) $sql->execute();
310
+
311
+        $this->cache[$app][$key] = $value;
312
+
313
+        return $changedRow;
314
+    }
315
+
316
+    /**
317
+     * Deletes a key
318
+     *
319
+     * @param string $app app
320
+     * @param string $key key
321
+     * @return boolean
322
+     */
323
+    public function deleteKey($app, $key) {
324
+        $this->loadConfigValues();
325
+
326
+        $sql = $this->conn->getQueryBuilder();
327
+        $sql->delete('appconfig')
328
+            ->where($sql->expr()->eq('appid', $sql->createParameter('app')))
329
+            ->andWhere($sql->expr()->eq('configkey', $sql->createParameter('configkey')))
330
+            ->setParameter('app', $app)
331
+            ->setParameter('configkey', $key);
332
+        $sql->execute();
333
+
334
+        unset($this->cache[$app][$key]);
335
+        return false;
336
+    }
337
+
338
+    /**
339
+     * Remove app from appconfig
340
+     *
341
+     * @param string $app app
342
+     * @return boolean
343
+     *
344
+     * Removes all keys in appconfig belonging to the app.
345
+     */
346
+    public function deleteApp($app) {
347
+        $this->loadConfigValues();
348
+
349
+        $sql = $this->conn->getQueryBuilder();
350
+        $sql->delete('appconfig')
351
+            ->where($sql->expr()->eq('appid', $sql->createParameter('app')))
352
+            ->setParameter('app', $app);
353
+        $sql->execute();
354
+
355
+        unset($this->cache[$app]);
356
+        return false;
357
+    }
358
+
359
+    /**
360
+     * get multiple values, either the app or key can be used as wildcard by setting it to false
361
+     *
362
+     * @param string|false $app
363
+     * @param string|false $key
364
+     * @return array|false
365
+     */
366
+    public function getValues($app, $key) {
367
+        if (($app !== false) === ($key !== false)) {
368
+            return false;
369
+        }
370
+
371
+        if ($key === false) {
372
+            return $this->getAppValues($app);
373
+        } else {
374
+            $appIds = $this->getApps();
375
+            $values = array_map(function ($appId) use ($key) {
376
+                return isset($this->cache[$appId][$key]) ? $this->cache[$appId][$key] : null;
377
+            }, $appIds);
378
+            $result = array_combine($appIds, $values);
379
+
380
+            return array_filter($result);
381
+        }
382
+    }
383
+
384
+    /**
385
+     * get all values of the app or and filters out sensitive data
386
+     *
387
+     * @param string $app
388
+     * @return array
389
+     */
390
+    public function getFilteredValues($app) {
391
+        $values = $this->getValues($app, false);
392
+
393
+        if (isset($this->sensitiveValues[$app])) {
394
+            foreach ($this->sensitiveValues[$app] as $sensitiveKeyExp) {
395
+                $sensitiveKeys = preg_grep($sensitiveKeyExp, array_keys($values));
396
+                foreach ($sensitiveKeys as $sensitiveKey) {
397
+                    $values[$sensitiveKey] = IConfig::SENSITIVE_VALUE;
398
+                }
399
+            }
400
+        }
401
+
402
+        return $values;
403
+    }
404
+
405
+    /**
406
+     * Load all the app config values
407
+     */
408
+    protected function loadConfigValues() {
409
+        if ($this->configLoaded) {
410
+            return;
411
+        }
412
+
413
+        $this->cache = [];
414
+
415
+        $sql = $this->conn->getQueryBuilder();
416
+        $sql->select('*')
417
+            ->from('appconfig');
418
+        $result = $sql->execute();
419
+
420
+        // we are going to store the result in memory anyway
421
+        $rows = $result->fetchAll();
422
+        foreach ($rows as $row) {
423
+            if (!isset($this->cache[$row['appid']])) {
424
+                $this->cache[(string)$row['appid']] = [];
425
+            }
426
+
427
+            $this->cache[(string)$row['appid']][(string)$row['configkey']] = (string)$row['configvalue'];
428
+        }
429
+        $result->closeCursor();
430
+
431
+        $this->configLoaded = true;
432
+    }
433
+
434
+
435
+    /**
436
+     * Clear all the cached app config values
437
+     * New cache will be generated next time a config value is retrieved
438
+     */
439
+    public function clearCachedConfig(): void {
440
+        $this->configLoaded = false;
441
+    }
442 442
 }
Please login to merge, or discard this patch.