New config_local settings
[squirrelmail.git] / functions / db_prefs.php
CommitLineData
82474746 1<?php
15e6162e 2
d6c32258 3/**
35586184 4 * db_prefs.php
5 *
35586184 6 * This contains functions for manipulating user preferences
21ddfbc3 7 * stored in a database, accessed through the Pear DB layer
8 * or PDO, the latter taking precedence if available.
35586184 9 *
35586184 10 * Database:
35586184 11 *
99a6c222 12 * The preferences table should have three columns:
13 * user char \ primary
35586184 14 * prefkey char / key
15 * prefval blob
16 *
4b7dd3d9 17 * CREATE TABLE userprefs (user CHAR(128) NOT NULL DEFAULT '',
35586184 18 * prefkey CHAR(64) NOT NULL DEFAULT '',
19 * prefval BLOB NOT NULL DEFAULT '',
20 * primary key (user,prefkey));
21 *
22 * Configuration of databasename, username and password is done
3499f99f 23 * by using conf.pl or the administrator plugin
35586184 24 *
21ddfbc3 25 * Three settings that control PDO behavior can be specified in
26 * config/config_local.php if needed:
27 * boolean $disable_pdo SquirrelMail uses PDO by default to access the
28 * user preferences and address book databases, but
29 * setting this to TRUE will cause SquirrelMail to
30 * fall back to using Pear DB instead.
31 * boolean $pdo_show_sql_errors When database errors are encountered,
32 * setting this to TRUE causes the actual
33 * database error to be displayed, otherwise
34 * generic errors are displayed, preventing
35 * internal database information from being
36 * exposed. This should be enabled only for
37 * debugging purposes.
38 * string $pdo_identifier_quote_char By default, SquirrelMail will quote
39 * table and field names in database
40 * queries with what it thinks is the
41 * appropriate quote character for the
42 * database type being used (backtick
43 * for MySQL (and thus MariaDB), double
44 * quotes for all others), but you can
45 * override the character used by
46 * putting it here, or tell SquirrelMail
47 * NOT to quote identifiers by setting
48 * this to "none"
49 *
50 * @copyright 1999-2015 The SquirrelMail Project Team
4b4abf93 51 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
31841a9e 52 * @version $Id$
d6c32258 53 * @package squirrelmail
ace4c62c 54 * @subpackage prefs
55 * @since 1.1.3
35586184 56 */
57
ace4c62c 58/** @ignore */
59if (!defined('SM_PATH')) define('SM_PATH','../');
60
d6c32258 61/** Unknown database */
98749983 62define('SMDB_UNKNOWN', 0);
d6c32258 63/** MySQL */
98749983 64define('SMDB_MYSQL', 1);
d6c32258 65/** PostgreSQL */
98749983 66define('SMDB_PGSQL', 2);
67
099fea11 68/**
21ddfbc3 69 * Needs either PDO or the DB functions
70 * Don't display errors here. (no code execution in functions/*.php).
099fea11 71 * will handle error in dbPrefs class.
72 */
21ddfbc3 73global $use_pdo, $disable_pdo;
74if (empty($disable_pdo) && class_exists('PDO'))
75 $use_pdo = TRUE;
76else
77 $use_pdo = FALSE;
78
79if (!$use_pdo)
80 @include_once('DB.php');
35586184 81
370059dd 82global $prefs_are_cached, $prefs_cache;
2d367c68 83
4d30c1b7 84/**
85 * @ignore
86 */
370059dd 87function cachePrefValues($username) {
88 global $prefs_are_cached, $prefs_cache;
89
37d5278d 90 sqgetGlobalVar('prefs_are_cached', $prefs_are_cached, SQ_SESSION );
370059dd 91 if ($prefs_are_cached) {
37d5278d 92 sqgetGlobalVar('prefs_cache', $prefs_cache, SQ_SESSION );
370059dd 93 return;
94 }
2d367c68 95
9eb0fbd4 96 sqsession_unregister('prefs_cache');
97 sqsession_unregister('prefs_are_cached');
370059dd 98
99 $db = new dbPrefs;
100 if(isset($db->error)) {
101 printf( _("Preference database error (%s). Exiting abnormally"),
102 $db->error);
103 exit;
104 }
2d367c68 105
370059dd 106 $db->fillPrefsCache($username);
107 if (isset($db->error)) {
108 printf( _("Preference database error (%s). Exiting abnormally"),
109 $db->error);
110 exit;
111 }
112
113 $prefs_are_cached = true;
114
9eb0fbd4 115 sqsession_register($prefs_cache, 'prefs_cache');
116 sqsession_register($prefs_are_cached, 'prefs_are_cached');
370059dd 117}
118
d6c32258 119/**
ace4c62c 120 * Class used to handle connections to prefs database and operations with preferences
37b11ab0 121 *
d6c32258 122 * @package squirrelmail
ace4c62c 123 * @subpackage prefs
124 * @since 1.1.3
37b11ab0 125 *
d6c32258 126 */
370059dd 127class dbPrefs {
ace4c62c 128 /**
129 * Table used to store preferences
130 * @var string
131 */
370059dd 132 var $table = 'userprefs';
37b11ab0 133
ace4c62c 134 /**
135 * Field used to store owner of preference
136 * @var string
137 */
99a6c222 138 var $user_field = 'user';
37b11ab0 139
ace4c62c 140 /**
141 * Field used to store preference name
142 * @var string
143 */
99a6c222 144 var $key_field = 'prefkey';
37b11ab0 145
ace4c62c 146 /**
147 * Field used to store preference value
148 * @var string
149 */
99a6c222 150 var $val_field = 'prefval';
370059dd 151
ace4c62c 152 /**
153 * Database connection object
154 * @var object
155 */
370059dd 156 var $dbh = NULL;
37b11ab0 157
ace4c62c 158 /**
159 * Error messages
160 * @var string
161 */
370059dd 162 var $error = NULL;
37b11ab0 163
ace4c62c 164 /**
165 * Database type (SMDB_* constants)
166 * Is used in setKey().
167 * @var integer
168 */
98749983 169 var $db_type = SMDB_UNKNOWN;
370059dd 170
21ddfbc3 171 /**
172 * Character used to quote database table
173 * and field names
174 * @var string
175 */
176 var $identifier_quote_char = '';
177
ace4c62c 178 /**
179 * Default preferences
180 * @var array
181 */
2ea6df85 182 var $default = Array('theme_default' => 0,
102b278b 183 'include_self_reply_all' => '0',
184 'do_not_reply_to_self' => '1',
370059dd 185 'show_html_default' => '0');
186
06316c07 187 /**
188 * Preference owner field size
189 * @var integer
190 * @since 1.5.1
191 */
192 var $user_size = 128;
37b11ab0 193
06316c07 194 /**
195 * Preference key field size
196 * @var integer
197 * @since 1.5.1
198 */
199 var $key_size = 64;
37b11ab0 200
06316c07 201 /**
202 * Preference value field size
203 * @var integer
204 * @since 1.5.1
205 */
206 var $val_size = 65536;
207
37b11ab0 208
209
3ec364a4 210 /**
211 * initialize the default preferences array.
212 *
213 */
214 function dbPrefs() {
215 // Try and read the default preferences file.
216 $default_pref = SM_PATH . 'config/default_pref';
217 if (@file_exists($default_pref)) {
218 if ($file = @fopen($default_pref, 'r')) {
219 while (!feof($file)) {
220 $pref = fgets($file, 1024);
221 $i = strpos($pref, '=');
222 if ($i > 0) {
223 $this->default[trim(substr($pref, 0, $i))] = trim(substr($pref, $i + 1));
224 }
225 }
226 fclose($file);
227 }
228 }
229 }
230
ace4c62c 231 /**
232 * initialize DB connection object
37b11ab0 233 *
ace4c62c 234 * @return boolean true, if object is initialized
37b11ab0 235 *
ace4c62c 236 */
370059dd 237 function open() {
21ddfbc3 238 global $prefs_dsn, $prefs_table, $use_pdo, $pdo_identifier_quote_char;
98749983 239 global $prefs_user_field, $prefs_key_field, $prefs_val_field;
06316c07 240 global $prefs_user_size, $prefs_key_size, $prefs_val_size;
3499f99f 241
21ddfbc3 242 /* test if PDO or Pear DB classes are available and freak out if necessary */
243 if (!$use_pdo && !class_exists('DB')) {
099fea11 244 // same error also in abook_database.php
21ddfbc3 245 $error = _("Could not find or include PHP PDO or PEAR database functions required for the database backend.") . "\n";
246 $error .= sprintf(_("PDO should come preinstalled with PHP version 5.1 or higher. Otherwise, is PEAR installed, and is the include path set correctly to find %s?"), 'DB.php') . "\n";
247 $error .= _("Please contact your system administrator and report this error.");
099fea11 248 return false;
249 }
250
370059dd 251 if(isset($this->dbh)) {
252 return true;
253 }
3499f99f 254
21ddfbc3 255 if (strpos($prefs_dsn, 'mysql') === 0) {
98749983 256 $this->db_type = SMDB_MYSQL;
21ddfbc3 257 } else if (strpos($prefs_dsn, 'pgsql') === 0) {
98749983 258 $this->db_type = SMDB_PGSQL;
259 }
260
21ddfbc3 261 // figure out identifier quoting (only used for PDO, though we could change that)
262 if (empty($pdo_identifier_quote_char)) {
263 if ($this->db_type == SMDB_MYSQL)
264 $this->identifier_quote_char = '`';
265 else
266 $this->identifier_quote_char = '"';
267 } else if ($pdo_identifier_quote_char === 'none')
268 $this->identifier_quote_char = '';
269 else
270 $this->identifier_quote_char = $pdo_identifier_quote_char;
271
3499f99f 272 if (!empty($prefs_table)) {
273 $this->table = $prefs_table;
274 }
99a6c222 275 if (!empty($prefs_user_field)) {
276 $this->user_field = $prefs_user_field;
277 }
865050ce 278
279 // the default user field is "user", which in PostgreSQL
280 // is an identifier and causes errors if not escaped
281 //
282 if ($this->db_type == SMDB_PGSQL) {
283 $this->user_field = '"' . $this->user_field . '"';
284 }
285
99a6c222 286 if (!empty($prefs_key_field)) {
287 $this->key_field = $prefs_key_field;
288 }
289 if (!empty($prefs_val_field)) {
290 $this->val_field = $prefs_val_field;
291 }
06316c07 292 if (!empty($prefs_user_size)) {
293 $this->user_size = (int) $prefs_user_size;
294 }
295 if (!empty($prefs_key_size)) {
296 $this->key_size = (int) $prefs_key_size;
297 }
298 if (!empty($prefs_val_size)) {
299 $this->val_size = (int) $prefs_val_size;
300 }
2d367c68 301
21ddfbc3 302 // connect, create database connection object
303 //
304 if ($use_pdo) {
305 // parse and convert DSN to PDO style
306 // $matches will contain:
307 // 1: database type
308 // 2: username
309 // 3: password
310 // 4: hostname
311 // 5: database name
312//TODO: add support for unix_socket and charset
313 if (!preg_match('|^(.+)://(.+):(.+)@(.+)/(.+)$|i', $prefs_dsn, $matches)) {
314 $this->error = _("Could not parse prefs DSN");
315 return false;
316 }
317 if (preg_match('|^(.+):(\d+)$|', $matches[4], $host_port_matches)) {
318 $matches[4] = $host_port_matches[1];
319 $matches[6] = $host_port_matches[2];
320 } else
321 $matches[6] = NULL;
322 $pdo_prefs_dsn = $matches[1] . ':host=' . $matches[4] . (!empty($matches[6]) ? ';port=' . $matches[6] : '') . ';dbname=' . $matches[5];
323 try {
324 $dbh = new PDO($pdo_prefs_dsn, $matches[2], $matches[3]);
325 } catch (Exception $e) {
326 $this->error = $e->getMessage();
327 return false;
328 }
329 } else {
330 $dbh = DB::connect($prefs_dsn, true);
331
332 if(DB::isError($dbh)) {
333 $this->error = DB::errorMessage($dbh);
334 return false;
335 }
2d367c68 336 }
337
338 $this->dbh = $dbh;
339 return true;
370059dd 340 }
82474746 341
ace4c62c 342 /**
343 * Function used to handle database connection errors
37b11ab0 344 *
202bcbcc 345 * @param object PEAR Error object
37b11ab0 346 *
ace4c62c 347 */
370059dd 348 function failQuery($res = NULL) {
21ddfbc3 349 global $use_pdo;
2d367c68 350 if($res == NULL) {
351 printf(_("Preference database error (%s). Exiting abnormally"),
370059dd 352 $this->error);
2d367c68 353 } else {
354 printf(_("Preference database error (%s). Exiting abnormally"),
21ddfbc3 355 ($use_pdo ? implode(' - ', $res->errorInfo()) : DB::errorMessage($res)));
2d367c68 356 }
357 exit;
370059dd 358 }
82474746 359
ace4c62c 360 /**
361 * Get user's prefs setting
37b11ab0 362 *
ace4c62c 363 * @param string $user user name
364 * @param string $key preference name
365 * @param mixed $default (since 1.2.5) default value
37b11ab0 366 *
ace4c62c 367 * @return mixed preference value
37b11ab0 368 *
ace4c62c 369 */
370059dd 370 function getKey($user, $key, $default = '') {
371 global $prefs_cache;
2d367c68 372
971c7b1a 373 $temp = array(&$user, &$key);
374 $result = do_hook('get_pref_override', $temp);
375 if (is_null($result)) {
376 cachePrefValues($user);
2d367c68 377
971c7b1a 378 if (isset($prefs_cache[$key])) {
379 $result = $prefs_cache[$key];
62337234 380 } else {
971c7b1a 381//FIXME: is there a justification for having two prefs hooks so close? who uses them?
382 $temp = array(&$user, &$key);
383 $result = do_hook('get_pref', $temp);
384 if (is_null($result)) {
385 if (isset($this->default[$key])) {
386 $result = $this->default[$key];
387 } else {
388 $result = $default;
389 }
390 }
62337234 391 }
2d367c68 392 }
971c7b1a 393 return $result;
370059dd 394 }
2d367c68 395
ace4c62c 396 /**
397 * Delete user's prefs setting
37b11ab0 398 *
202bcbcc 399 * @param string $user user name
37b11ab0 400 * @param string $key preference name
401 *
ace4c62c 402 * @return boolean
37b11ab0 403 *
ace4c62c 404 */
370059dd 405 function deleteKey($user, $key) {
21ddfbc3 406 global $prefs_cache, $use_pdo, $pdo_show_sql_errors;
82474746 407
b279d7f4 408 if (!$this->open()) {
409 return false;
410 }
21ddfbc3 411 if ($use_pdo) {
412 if (!($sth = $this->dbh->prepare('DELETE FROM ' . $this->identifier_quote_char . $this->table . $this->identifier_quote_char . ' WHERE ' . $this->identifier_quote_char . $this->user_field . $this->identifier_quote_char . ' = ? AND ' . $this->identifier_quote_char . $this->key_field . $this->identifier_quote_char . ' = ?'))) {
413 if ($pdo_show_sql_errors)
414 $this->error = implode(' - ', $this->dbh->errorInfo());
415 else
416 $this->error = _("Could not prepare query");
417 $this->failQuery();
418 }
419 if (!($res = $sth->execute(array($user, $key)))) {
420 if ($pdo_show_sql_errors)
421 $this->error = implode(' - ', $sth->errorInfo());
422 else
423 $this->error = _("Could not execute query");
424 $this->failQuery();
425 }
426 } else {
427 $query = sprintf("DELETE FROM %s WHERE %s='%s' AND %s='%s'",
428 $this->table,
429 $this->user_field,
430 $this->dbh->quoteString($user),
431 $this->key_field,
432 $this->dbh->quoteString($key));
433
434 $res = $this->dbh->simpleQuery($query);
435 if(DB::isError($res)) {
436 $this->failQuery($res);
437 }
370059dd 438 }
439
440 unset($prefs_cache[$key]);
82474746 441
2d367c68 442 return true;
370059dd 443 }
82474746 444
ace4c62c 445 /**
446 * Set user's preference
37b11ab0 447 *
448 * @param string $user user name
449 * @param string $key preference name
450 * @param mixed $value preference value
451 *
ace4c62c 452 * @return boolean
37b11ab0 453 *
ace4c62c 454 */
370059dd 455 function setKey($user, $key, $value) {
21ddfbc3 456 global $use_pdo, $pdo_show_sql_errors;
b279d7f4 457 if (!$this->open()) {
458 return false;
459 }
06316c07 460
461 /**
462 * Check if username fits into db field
463 */
464 if (strlen($user) > $this->user_size) {
465 $this->error = "Oversized username value."
5e07597f 466 ." Your preferences can't be saved."
6f4c512c 467 ." See the administrator's manual or contact your system administrator.";
06316c07 468
469 /**
202bcbcc 470 * Debugging function. Can be used to log all issues that trigger
471 * oversized field errors. Function should be enabled in all three
06316c07 472 * strlen checks. See http://www.php.net/error-log
473 */
474 // error_log($user.'|'.$key.'|'.$value."\n",3,'/tmp/oversized_log');
475
476 // error is fatal
477 $this->failQuery(null);
478 }
479 /**
480 * Check if preference key fits into db field
481 */
482 if (strlen($key) > $this->key_size) {
483 $err_msg = "Oversized user's preference key."
5e07597f 484 ." Some preferences were not saved."
6f4c512c 485 ." See the administrator's manual or contact your system administrator.";
06316c07 486 // error is not fatal. Only some preference is not saved.
487 trigger_error($err_msg,E_USER_WARNING);
488 return false;
489 }
490 /**
491 * Check if preference value fits into db field
492 */
493 if (strlen($value) > $this->val_size) {
494 $err_msg = "Oversized user's preference value."
5e07597f 495 ." Some preferences were not saved."
6f4c512c 496 ." See the administrator's manual or contact your system administrator.";
06316c07 497 // error is not fatal. Only some preference is not saved.
498 trigger_error($err_msg,E_USER_WARNING);
499 return false;
500 }
501
502
98749983 503 if ($this->db_type == SMDB_MYSQL) {
21ddfbc3 504 if ($use_pdo) {
505 if (!($sth = $this->dbh->prepare('REPLACE INTO ' . $this->identifier_quote_char . $this->table . $this->identifier_quote_char . ' (' . $this->identifier_quote_char . $this->user_field . $this->identifier_quote_char . ', ' . $this->identifier_quote_char . $this->key_field . $this->identifier_quote_char . ', ' . $this->identifier_quote_char . $this->val_field . $this->identifier_quote_char . ') VALUES (?, ?, ?)'))) {
506 if ($pdo_show_sql_errors)
507 $this->error = implode(' - ', $this->dbh->errorInfo());
508 else
509 $this->error = _("Could not prepare query");
510 $this->failQuery();
511 }
512 if (!($res = $sth->execute(array($user, $key, $value)))) {
513 if ($pdo_show_sql_errors)
514 $this->error = implode(' - ', $sth->errorInfo());
515 else
516 $this->error = _("Could not execute query");
517 $this->failQuery();
518 }
519 } else {
520 $query = sprintf("REPLACE INTO %s (%s, %s, %s) ".
521 "VALUES('%s','%s','%s')",
522 $this->table,
523 $this->user_field,
524 $this->key_field,
525 $this->val_field,
526 $this->dbh->quoteString($user),
527 $this->dbh->quoteString($key),
528 $this->dbh->quoteString($value));
529
530 $res = $this->dbh->simpleQuery($query);
531 if(DB::isError($res)) {
532 $this->failQuery($res);
533 }
98749983 534 }
535 } elseif ($this->db_type == SMDB_PGSQL) {
21ddfbc3 536 if ($use_pdo) {
537 if ($this->dbh->exec('BEGIN TRANSACTION') === FALSE) {
538 if ($pdo_show_sql_errors)
539 $this->error = implode(' - ', $this->dbh->errorInfo());
540 else
541 $this->error = _("Could not execute query");
542 $this->failQuery();
543 }
544 if (!($sth = $this->dbh->prepare('DELETE FROM ' . $this->identifier_quote_char . $this->table . $this->identifier_quote_char . ' WHERE ' . $this->identifier_quote_char . $this->user_field . $this->identifier_quote_char . ' = ? AND ' . $this->identifier_quote_char . $this->key_field . $this->identifier_quote_char . ' = ?'))) {
545 if ($pdo_show_sql_errors)
546 $this->error = implode(' - ', $this->dbh->errorInfo());
547 else
548 $this->error = _("Could not prepare query");
549 $this->failQuery();
550 }
551 if (!($res = $sth->execute(array($user, $key)))) {
552 if ($pdo_show_sql_errors)
553 $this->error = implode(' - ', $sth->errorInfo());
554 else
555 $this->error = _("Could not execute query");
556 $this->dbh->exec('ROLLBACK TRANSACTION');
557 $this->failQuery();
558 }
559 if (!($sth = $this->dbh->prepare('INSERT INTO ' . $this->identifier_quote_char . $this->table . $this->identifier_quote_char . ' (' . $this->identifier_quote_char . $this->user_field . $this->identifier_quote_char . ', ' . $this->identifier_quote_char . $this->key_field . $this->identifier_quote_char . ', ' . $this->identifier_quote_char . $this->val_field . $this->identifier_quote_char . ') VALUES (?, ?, ?)'))) {
560 if ($pdo_show_sql_errors)
561 $this->error = implode(' - ', $this->dbh->errorInfo());
562 else
563 $this->error = _("Could not prepare query");
564 $this->failQuery();
565 }
566 if (!($res = $sth->execute(array($user, $key, $value)))) {
567 if ($pdo_show_sql_errors)
568 $this->error = implode(' - ', $sth->errorInfo());
569 else
570 $this->error = _("Could not execute query");
571 $this->dbh->exec('ROLLBACK TRANSACTION');
572 $this->failQuery();
573 }
574 if ($this->dbh->exec('COMMIT TRANSACTION') === FALSE) {
575 if ($pdo_show_sql_errors)
576 $this->error = implode(' - ', $this->dbh->errorInfo());
577 else
578 $this->error = _("Could not execute query");
579 $this->failQuery();
580 }
581 } else {
582 $this->dbh->simpleQuery("BEGIN TRANSACTION");
583 $query = sprintf("DELETE FROM %s WHERE %s='%s' AND %s='%s'",
584 $this->table,
585 $this->user_field,
586 $this->dbh->quoteString($user),
587 $this->key_field,
588 $this->dbh->quoteString($key));
589 $res = $this->dbh->simpleQuery($query);
590 if (DB::isError($res)) {
591 $this->dbh->simpleQuery("ROLLBACK TRANSACTION");
592 $this->failQuery($res);
593 }
594 $query = sprintf("INSERT INTO %s (%s, %s, %s) VALUES ('%s', '%s', '%s')",
595 $this->table,
596 $this->user_field,
597 $this->key_field,
598 $this->val_field,
599 $this->dbh->quoteString($user),
600 $this->dbh->quoteString($key),
601 $this->dbh->quoteString($value));
602 $res = $this->dbh->simpleQuery($query);
603 if (DB::isError($res)) {
604 $this->dbh->simpleQuery("ROLLBACK TRANSACTION");
605 $this->failQuery($res);
606 }
607 $this->dbh->simpleQuery("COMMIT TRANSACTION");
98749983 608 }
98749983 609 } else {
21ddfbc3 610 if ($use_pdo) {
611 if (!($sth = $this->dbh->prepare('DELETE FROM ' . $this->identifier_quote_char . $this->table . $this->identifier_quote_char . ' WHERE ' . $this->identifier_quote_char . $this->user_field . $this->identifier_quote_char . ' = ? AND ' . $this->identifier_quote_char . $this->key_field . $this->identifier_quote_char . ' = ?'))) {
612 if ($pdo_show_sql_errors)
613 $this->error = implode(' - ', $this->dbh->errorInfo());
614 else
615 $this->error = _("Could not prepare query");
616 $this->failQuery();
617 }
618 if (!($res = $sth->execute(array($user, $key)))) {
619 if ($pdo_show_sql_errors)
620 $this->error = implode(' - ', $sth->errorInfo());
621 else
622 $this->error = _("Could not execute query");
623 $this->failQuery();
624 }
625 if (!($sth = $this->dbh->prepare('INSERT INTO ' . $this->identifier_quote_char . $this->table . $this->identifier_quote_char . ' (' . $this->identifier_quote_char . $this->user_field . $this->identifier_quote_char . ', ' . $this->identifier_quote_char . $this->key_field . $this->identifier_quote_char . ', ' . $this->identifier_quote_char . $this->val_field . $this->identifier_quote_char . ') VALUES (?, ?, ?)'))) {
626 if ($pdo_show_sql_errors)
627 $this->error = implode(' - ', $this->dbh->errorInfo());
628 else
629 $this->error = _("Could not prepare query");
630 $this->failQuery();
631 }
632 if (!($res = $sth->execute(array($user, $key, $value)))) {
633 if ($pdo_show_sql_errors)
634 $this->error = implode(' - ', $sth->errorInfo());
635 else
636 $this->error = _("Could not execute query");
637 $this->failQuery();
638 }
639 } else {
640 $query = sprintf("DELETE FROM %s WHERE %s='%s' AND %s='%s'",
641 $this->table,
642 $this->user_field,
643 $this->dbh->quoteString($user),
644 $this->key_field,
645 $this->dbh->quoteString($key));
646 $res = $this->dbh->simpleQuery($query);
647 if (DB::isError($res)) {
648 $this->failQuery($res);
649 }
650 $query = sprintf("INSERT INTO %s (%s, %s, %s) VALUES ('%s', '%s', '%s')",
651 $this->table,
652 $this->user_field,
653 $this->key_field,
654 $this->val_field,
655 $this->dbh->quoteString($user),
656 $this->dbh->quoteString($key),
657 $this->dbh->quoteString($value));
658 $res = $this->dbh->simpleQuery($query);
659 if (DB::isError($res)) {
660 $this->failQuery($res);
661 }
98749983 662 }
370059dd 663 }
2d367c68 664
665 return true;
370059dd 666 }
82474746 667
ace4c62c 668 /**
669 * Fill preference cache array
37b11ab0 670 *
ace4c62c 671 * @param string $user user name
37b11ab0 672 *
ace4c62c 673 * @since 1.2.3
37b11ab0 674 *
ace4c62c 675 */
370059dd 676 function fillPrefsCache($user) {
21ddfbc3 677 global $prefs_cache, $use_pdo, $pdo_show_sql_errors;
2d367c68 678
b279d7f4 679 if (!$this->open()) {
680 return;
681 }
370059dd 682
683 $prefs_cache = array();
21ddfbc3 684 if ($use_pdo) {
685 if (!($sth = $this->dbh->prepare('SELECT ' . $this->identifier_quote_char . $this->key_field . $this->identifier_quote_char . ' AS prefkey, ' . $this->identifier_quote_char . $this->val_field . $this->identifier_quote_char . ' AS prefval FROM ' . $this->identifier_quote_char . $this->table . $this->identifier_quote_char . ' WHERE ' . $this->identifier_quote_char . $this->user_field . $this->identifier_quote_char . ' = ?'))) {
686 if ($pdo_show_sql_errors)
687 $this->error = implode(' - ', $this->dbh->errorInfo());
688 else
689 $this->error = _("Could not prepare query");
690 $this->failQuery();
691 }
692 if (!($res = $sth->execute(array($user)))) {
693 if ($pdo_show_sql_errors)
694 $this->error = implode(' - ', $sth->errorInfo());
695 else
696 $this->error = _("Could not execute query");
697 $this->failQuery();
698 }
370059dd 699
21ddfbc3 700 while ($row = $sth->fetch(PDO::FETCH_ASSOC)) {
701 $prefs_cache[$row['prefkey']] = $row['prefval'];
702 }
703 } else {
704 $query = sprintf("SELECT %s as prefkey, %s as prefval FROM %s ".
705 "WHERE %s = '%s'",
706 $this->key_field,
707 $this->val_field,
708 $this->table,
709 $this->user_field,
710 $this->dbh->quoteString($user));
711 $res = $this->dbh->query($query);
712 if (DB::isError($res)) {
713 $this->failQuery($res);
714 }
715
716 while ($row = $res->fetchRow(DB_FETCHMODE_ASSOC)) {
717 $prefs_cache[$row['prefkey']] = $row['prefval'];
718 }
370059dd 719 }
720 }
721
370059dd 722} /* end class dbPrefs */
82474746 723
724
4d30c1b7 725/**
37b11ab0 726 * Returns the value for the requested preference
4d30c1b7 727 * @ignore
728 */
37b11ab0 729function getPref($data_dir, $username, $pref_name, $default = '') {
370059dd 730 $db = new dbPrefs;
731 if(isset($db->error)) {
2d367c68 732 printf( _("Preference database error (%s). Exiting abnormally"),
370059dd 733 $db->error);
2d367c68 734 exit;
370059dd 735 }
736
37b11ab0 737 return $db->getKey($username, $pref_name, $default);
370059dd 738}
739
4d30c1b7 740/**
37b11ab0 741 * Remove the desired preference setting ($pref_name)
4d30c1b7 742 * @ignore
743 */
37b11ab0 744function removePref($data_dir, $username, $pref_name) {
1fa62ab9 745 global $prefs_cache;
370059dd 746 $db = new dbPrefs;
747 if(isset($db->error)) {
748 $db->failQuery();
749 }
750
37b11ab0 751 $db->deleteKey($username, $pref_name);
88a99543 752
37b11ab0 753 if (isset($prefs_cache[$pref_name])) {
754 unset($prefs_cache[$pref_name]);
88a99543 755 }
756
757 sqsession_register($prefs_cache , 'prefs_cache');
370059dd 758 return;
759}
760
4d30c1b7 761/**
37b11ab0 762 * Sets the desired preference setting ($pref_name) to whatever is in $value
4d30c1b7 763 * @ignore
764 */
37b11ab0 765function setPref($data_dir, $username, $pref_name, $value) {
370059dd 766 global $prefs_cache;
767
37b11ab0 768 if (isset($prefs_cache[$pref_name]) && ($prefs_cache[$pref_name] == $value)) {
1fa62ab9 769 return;
370059dd 770 }
771
37b11ab0 772 if ($value === '') {
773 removePref($data_dir, $username, $pref_name);
370059dd 774 return;
775 }
776
777 $db = new dbPrefs;
778 if(isset($db->error)) {
779 $db->failQuery();
780 }
781
37b11ab0 782 $db->setKey($username, $pref_name, $value);
783 $prefs_cache[$pref_name] = $value;
370059dd 784 assert_options(ASSERT_ACTIVE, 1);
785 assert_options(ASSERT_BAIL, 1);
37b11ab0 786 assert ('$value == $prefs_cache[$pref_name]');
88a99543 787 sqsession_register($prefs_cache , 'prefs_cache');
370059dd 788 return;
789}
790
4d30c1b7 791/**
792 * This checks if the prefs are available
793 * @ignore
794 */
370059dd 795function checkForPrefs($data_dir, $username) {
796 $db = new dbPrefs;
797 if(isset($db->error)) {
798 $db->failQuery();
799 }
800}
801
4d30c1b7 802/**
803 * Writes the Signature
804 * @ignore
805 */
37b11ab0 806function setSig($data_dir, $username, $number, $value) {
16e5635d 807 if ($number == "g") {
808 $key = '___signature___';
809 } else {
810 $key = sprintf('___sig%s___', $number);
811 }
37b11ab0 812 setPref($data_dir, $username, $key, $value);
370059dd 813 return;
814}
815
4d30c1b7 816/**
817 * Gets the signature
818 * @ignore
819 */
16e5635d 820function getSig($data_dir, $username, $number) {
16e5635d 821 if ($number == "g") {
822 $key = '___signature___';
823 } else {
824 $key = sprintf('___sig%d___', $number);
825 }
57f1d1c1 826 return getPref($data_dir, $username, $key);
370059dd 827}