You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

287 lines
6.9 KiB

10 years ago
10 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
  1. <?php
  2. /**
  3. * @author Arthur Schiwon <blizzz@owncloud.com>
  4. * @author Bart Visscher <bartv@thisnet.nl>
  5. * @author Jakob Sack <mail@jakobsack.de>
  6. * @author Joas Schilling <nickvergessen@owncloud.com>
  7. * @author Jörn Friedrich Dreyer <jfd@butonic.de>
  8. * @author Morris Jobke <hey@morrisjobke.de>
  9. * @author Robin Appelman <icewind@owncloud.com>
  10. * @author Robin McCorkell <robin@mccorkell.me.uk>
  11. *
  12. * @copyright Copyright (c) 2016, ownCloud, Inc.
  13. * @license AGPL-3.0
  14. *
  15. * This code is free software: you can redistribute it and/or modify
  16. * it under the terms of the GNU Affero General Public License, version 3,
  17. * as published by the Free Software Foundation.
  18. *
  19. * This program is distributed in the hope that it will be useful,
  20. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22. * GNU Affero General Public License for more details.
  23. *
  24. * You should have received a copy of the GNU Affero General Public License, version 3,
  25. * along with this program. If not, see <http://www.gnu.org/licenses/>
  26. *
  27. */
  28. namespace OC;
  29. use OCP\IAppConfig;
  30. use OCP\IDBConnection;
  31. /**
  32. * This class provides an easy way for apps to store config values in the
  33. * database.
  34. */
  35. class AppConfig implements IAppConfig {
  36. /**
  37. * @var \OCP\IDBConnection $conn
  38. */
  39. protected $conn;
  40. private $cache = array();
  41. /**
  42. * @param IDBConnection $conn
  43. */
  44. public function __construct(IDBConnection $conn) {
  45. $this->conn = $conn;
  46. $this->configLoaded = false;
  47. }
  48. /**
  49. * @param string $app
  50. * @return array
  51. */
  52. private function getAppValues($app) {
  53. $this->loadConfigValues();
  54. if (isset($this->cache[$app])) {
  55. return $this->cache[$app];
  56. }
  57. return [];
  58. }
  59. /**
  60. * Get all apps using the config
  61. *
  62. * @return array an array of app ids
  63. *
  64. * This function returns a list of all apps that have at least one
  65. * entry in the appconfig table.
  66. */
  67. public function getApps() {
  68. $this->loadConfigValues();
  69. return $this->getSortedKeys($this->cache);
  70. }
  71. /**
  72. * Get the available keys for an app
  73. *
  74. * @param string $app the app we are looking for
  75. * @return array an array of key names
  76. *
  77. * This function gets all keys of an app. Please note that the values are
  78. * not returned.
  79. */
  80. public function getKeys($app) {
  81. $this->loadConfigValues();
  82. if (isset($this->cache[$app])) {
  83. return $this->getSortedKeys($this->cache[$app]);
  84. }
  85. return [];
  86. }
  87. public function getSortedKeys($data) {
  88. $keys = array_keys($data);
  89. sort($keys);
  90. return $keys;
  91. }
  92. /**
  93. * Gets the config value
  94. *
  95. * @param string $app app
  96. * @param string $key key
  97. * @param string $default = null, default value if the key does not exist
  98. * @return string the value or $default
  99. *
  100. * This function gets a value from the appconfig table. If the key does
  101. * not exist the default value will be returned
  102. */
  103. public function getValue($app, $key, $default = null) {
  104. $this->loadConfigValues();
  105. if ($this->hasKey($app, $key)) {
  106. return $this->cache[$app][$key];
  107. }
  108. return $default;
  109. }
  110. /**
  111. * check if a key is set in the appconfig
  112. *
  113. * @param string $app
  114. * @param string $key
  115. * @return bool
  116. */
  117. public function hasKey($app, $key) {
  118. $this->loadConfigValues();
  119. return isset($this->cache[$app][$key]);
  120. }
  121. /**
  122. * Sets a value. If the key did not exist before it will be created.
  123. *
  124. * @param string $app app
  125. * @param string $key key
  126. * @param string $value value
  127. * @return bool True if the value was inserted or updated, false if the value was the same
  128. */
  129. public function setValue($app, $key, $value) {
  130. if (!$this->hasKey($app, $key)) {
  131. $inserted = (bool) $this->conn->insertIfNotExist('*PREFIX*appconfig', [
  132. 'appid' => $app,
  133. 'configkey' => $key,
  134. 'configvalue' => $value,
  135. ], [
  136. 'appid',
  137. 'configkey',
  138. ]);
  139. if ($inserted) {
  140. if (!isset($this->cache[$app])) {
  141. $this->cache[$app] = [];
  142. }
  143. $this->cache[$app][$key] = $value;
  144. return true;
  145. }
  146. }
  147. $sql = $this->conn->getQueryBuilder();
  148. $sql->update('appconfig')
  149. ->set('configvalue', $sql->createParameter('configvalue'))
  150. ->where($sql->expr()->eq('appid', $sql->createParameter('app')))
  151. ->andWhere($sql->expr()->eq('configkey', $sql->createParameter('configkey')))
  152. ->setParameter('configvalue', $value)
  153. ->setParameter('app', $app)
  154. ->setParameter('configkey', $key);
  155. /*
  156. * Only limit to the existing value for non-Oracle DBs:
  157. * http://docs.oracle.com/cd/E11882_01/server.112/e26088/conditions002.htm#i1033286
  158. * > Large objects (LOBs) are not supported in comparison conditions.
  159. */
  160. if (!($this->conn instanceof \OC\DB\OracleConnection)) {
  161. // Only update the value when it is not the same
  162. $sql->andWhere($sql->expr()->neq('configvalue', $sql->createParameter('configvalue')))
  163. ->setParameter('configvalue', $value);
  164. }
  165. $changedRow = (bool) $sql->execute();
  166. $this->cache[$app][$key] = $value;
  167. return $changedRow;
  168. }
  169. /**
  170. * Deletes a key
  171. *
  172. * @param string $app app
  173. * @param string $key key
  174. * @return boolean|null
  175. */
  176. public function deleteKey($app, $key) {
  177. $this->loadConfigValues();
  178. $sql = $this->conn->getQueryBuilder();
  179. $sql->delete('appconfig')
  180. ->where($sql->expr()->eq('appid', $sql->createParameter('app')))
  181. ->andWhere($sql->expr()->eq('configkey', $sql->createParameter('configkey')))
  182. ->setParameter('app', $app)
  183. ->setParameter('configkey', $key);
  184. $sql->execute();
  185. unset($this->cache[$app][$key]);
  186. }
  187. /**
  188. * Remove app from appconfig
  189. *
  190. * @param string $app app
  191. * @return boolean|null
  192. *
  193. * Removes all keys in appconfig belonging to the app.
  194. */
  195. public function deleteApp($app) {
  196. $this->loadConfigValues();
  197. $sql = $this->conn->getQueryBuilder();
  198. $sql->delete('appconfig')
  199. ->where($sql->expr()->eq('appid', $sql->createParameter('app')))
  200. ->setParameter('app', $app);
  201. $sql->execute();
  202. unset($this->cache[$app]);
  203. }
  204. /**
  205. * get multiple values, either the app or key can be used as wildcard by setting it to false
  206. *
  207. * @param string|false $app
  208. * @param string|false $key
  209. * @return array|false
  210. */
  211. public function getValues($app, $key) {
  212. if (($app !== false) === ($key !== false)) {
  213. return false;
  214. }
  215. if ($key === false) {
  216. return $this->getAppValues($app);
  217. } else {
  218. $appIds = $this->getApps();
  219. $values = array_map(function($appId) use ($key) {
  220. return isset($this->cache[$appId][$key]) ? $this->cache[$appId][$key] : null;
  221. }, $appIds);
  222. $result = array_combine($appIds, $values);
  223. return array_filter($result);
  224. }
  225. }
  226. /**
  227. * Load all the app config values
  228. */
  229. protected function loadConfigValues() {
  230. if ($this->configLoaded) return;
  231. $this->cache = [];
  232. $sql = $this->conn->getQueryBuilder();
  233. $sql->select('*')
  234. ->from('appconfig');
  235. $result = $sql->execute();
  236. while ($row = $result->fetch()) {
  237. if (!isset($this->cache[$row['appid']])) {
  238. $this->cache[$row['appid']] = [];
  239. }
  240. $this->cache[$row['appid']][$row['configkey']] = $row['configvalue'];
  241. }
  242. $result->closeCursor();
  243. $this->configLoaded = true;
  244. }
  245. }