Add PHP5-style constructor
[squirrelmail.git] / functions / db_prefs.php
1 <?php
2
3 /**
4 * db_prefs.php
5 *
6 * This contains functions for manipulating user preferences
7 * stored in a database, accessed through the Pear DB layer
8 * or PDO, the latter taking precedence if available.
9 *
10 * Database:
11 *
12 * The preferences table should have three columns:
13 * user char \ primary
14 * prefkey char / key
15 * prefval blob
16 *
17 * CREATE TABLE userprefs (user CHAR(128) NOT NULL DEFAULT '',
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
23 * by using conf.pl or the administrator plugin
24 *
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
51 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
52 * @version $Id$
53 * @package squirrelmail
54 * @subpackage prefs
55 * @since 1.1.3
56 */
57
58 /** @ignore */
59 if (!defined('SM_PATH')) define('SM_PATH','../');
60
61 /** Unknown database */
62 define('SMDB_UNKNOWN', 0);
63 /** MySQL */
64 define('SMDB_MYSQL', 1);
65 /** PostgreSQL */
66 define('SMDB_PGSQL', 2);
67
68 /**
69 * Needs either PDO or the DB functions
70 * Don't display errors here. (no code execution in functions/*.php).
71 * will handle error in dbPrefs class.
72 */
73 global $use_pdo, $disable_pdo;
74 if (empty($disable_pdo) && class_exists('PDO'))
75 $use_pdo = TRUE;
76 else
77 $use_pdo = FALSE;
78
79 if (!$use_pdo)
80 @include_once('DB.php');
81
82 global $prefs_are_cached, $prefs_cache;
83
84 /**
85 * @ignore
86 */
87 function cachePrefValues($username) {
88 global $prefs_are_cached, $prefs_cache;
89
90 sqgetGlobalVar('prefs_are_cached', $prefs_are_cached, SQ_SESSION );
91 if ($prefs_are_cached) {
92 sqgetGlobalVar('prefs_cache', $prefs_cache, SQ_SESSION );
93 return;
94 }
95
96 sqsession_unregister('prefs_cache');
97 sqsession_unregister('prefs_are_cached');
98
99 $db = new dbPrefs;
100 if(isset($db->error)) {
101 printf( _("Preference database error (%s). Exiting abnormally"),
102 $db->error);
103 exit;
104 }
105
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
115 sqsession_register($prefs_cache, 'prefs_cache');
116 sqsession_register($prefs_are_cached, 'prefs_are_cached');
117 }
118
119 /**
120 * Class used to handle connections to prefs database and operations with preferences
121 *
122 * @package squirrelmail
123 * @subpackage prefs
124 * @since 1.1.3
125 *
126 */
127 class dbPrefs {
128 /**
129 * Table used to store preferences
130 * @var string
131 */
132 var $table = 'userprefs';
133
134 /**
135 * Field used to store owner of preference
136 * @var string
137 */
138 var $user_field = 'user';
139
140 /**
141 * Field used to store preference name
142 * @var string
143 */
144 var $key_field = 'prefkey';
145
146 /**
147 * Field used to store preference value
148 * @var string
149 */
150 var $val_field = 'prefval';
151
152 /**
153 * Database connection object
154 * @var object
155 */
156 var $dbh = NULL;
157
158 /**
159 * Error messages
160 * @var string
161 */
162 var $error = NULL;
163
164 /**
165 * Database type (SMDB_* constants)
166 * Is used in setKey().
167 * @var integer
168 */
169 var $db_type = SMDB_UNKNOWN;
170
171 /**
172 * Character used to quote database table
173 * and field names
174 * @var string
175 */
176 var $identifier_quote_char = '';
177
178 /**
179 * Default preferences
180 * @var array
181 */
182 var $default = Array('theme_default' => 0,
183 'include_self_reply_all' => '0',
184 'do_not_reply_to_self' => '1',
185 'show_html_default' => '0');
186
187 /**
188 * Preference owner field size
189 * @var integer
190 * @since 1.5.1
191 */
192 var $user_size = 128;
193
194 /**
195 * Preference key field size
196 * @var integer
197 * @since 1.5.1
198 */
199 var $key_size = 64;
200
201 /**
202 * Preference value field size
203 * @var integer
204 * @since 1.5.1
205 */
206 var $val_size = 65536;
207
208
209
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
231 /**
232 * initialize DB connection object
233 *
234 * @return boolean true, if object is initialized
235 *
236 */
237 function open() {
238 global $prefs_dsn, $prefs_table, $use_pdo, $pdo_identifier_quote_char;
239 global $prefs_user_field, $prefs_key_field, $prefs_val_field;
240 global $prefs_user_size, $prefs_key_size, $prefs_val_size;
241
242 /* test if PDO or Pear DB classes are available and freak out if necessary */
243 if (!$use_pdo && !class_exists('DB')) {
244 // same error also in abook_database.php
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.");
248 return false;
249 }
250
251 if(isset($this->dbh)) {
252 return true;
253 }
254
255 if (strpos($prefs_dsn, 'mysql') === 0) {
256 $this->db_type = SMDB_MYSQL;
257 } else if (strpos($prefs_dsn, 'pgsql') === 0) {
258 $this->db_type = SMDB_PGSQL;
259 }
260
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
272 if (!empty($prefs_table)) {
273 $this->table = $prefs_table;
274 }
275 if (!empty($prefs_user_field)) {
276 $this->user_field = $prefs_user_field;
277 }
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
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 }
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 }
301
302 // connect, create database connection object
303 //
304 if ($use_pdo) {
305 // parse and convert DSN to PDO style
306 // Pear's full DSN syntax is one of the following:
307 // phptype(dbsyntax)://username:password@protocol+hostspec/database?option=value
308 // phptype(syntax)://user:pass@protocol(proto_opts)/database
309 //
310 // $matches will contain:
311 // 1: database type
312 // 2: username
313 // 3: password
314 // 4: hostname (and possible port number) OR protocol (and possible protocol options)
315 // 5: database name (and possible options)
316 // 6: port number (moved from match number 4)
317 // 7: options (moved from match number 5)
318 // 8: protocol (instead of hostname)
319 // 9: protocol options (moved from match number 4/8)
320 //TODO: do we care about supporting cases where no password is given? (this is a legal DSN, but causes an error below)
321 if (!preg_match('|^(.+)://(.+):(.+)@(.+)/(.+)$|i', $prefs_dsn, $matches)) {
322 $this->error = _("Could not parse prefs DSN");
323 return false;
324 }
325 $matches[6] = NULL;
326 $matches[7] = NULL;
327 $matches[8] = NULL;
328 $matches[9] = NULL;
329 if (preg_match('|^(.+):(\d+)$|', $matches[4], $host_port_matches)) {
330 $matches[4] = $host_port_matches[1];
331 $matches[6] = $host_port_matches[2];
332 }
333 if (preg_match('|^(.+?)\((.+)\)$|', $matches[4], $protocol_matches)) {
334 $matches[8] = $protocol_matches[1];
335 $matches[9] = $protocol_matches[2];
336 $matches[4] = NULL;
337 $matches[6] = NULL;
338 }
339 //TODO: currently we just ignore options specified on the end of the DSN
340 if (preg_match('|^(.+?)\?(.+)$|', $matches[5], $database_name_options_matches)) {
341 $matches[5] = $database_name_options_matches[1];
342 $matches[7] = $database_name_options_matches[2];
343 }
344 if ($matches[8] === 'unix' && !empty($matches[9]))
345 $pdo_prefs_dsn = $matches[1] . ':unix_socket=' . $matches[9] . ';dbname=' . $matches[5];
346 else
347 $pdo_prefs_dsn = $matches[1] . ':host=' . $matches[4] . (!empty($matches[6]) ? ';port=' . $matches[6] : '') . ';dbname=' . $matches[5];
348 try {
349 $dbh = new PDO($pdo_prefs_dsn, $matches[2], $matches[3]);
350 } catch (Exception $e) {
351 $this->error = $e->getMessage();
352 return false;
353 }
354 } else {
355 $dbh = DB::connect($prefs_dsn, true);
356
357 if(DB::isError($dbh)) {
358 $this->error = DB::errorMessage($dbh);
359 return false;
360 }
361 }
362
363 $this->dbh = $dbh;
364 return true;
365 }
366
367 /**
368 * Function used to handle database connection errors
369 *
370 * @param object PEAR Error object
371 *
372 */
373 function failQuery($res = NULL) {
374 global $use_pdo;
375 if($res == NULL) {
376 printf(_("Preference database error (%s). Exiting abnormally"),
377 $this->error);
378 } else {
379 printf(_("Preference database error (%s). Exiting abnormally"),
380 ($use_pdo ? implode(' - ', $res->errorInfo()) : DB::errorMessage($res)));
381 }
382 exit;
383 }
384
385 /**
386 * Get user's prefs setting
387 *
388 * @param string $user user name
389 * @param string $key preference name
390 * @param mixed $default (since 1.2.5) default value
391 *
392 * @return mixed preference value
393 *
394 */
395 function getKey($user, $key, $default = '') {
396 global $prefs_cache;
397
398 $temp = array(&$user, &$key);
399 $result = do_hook('get_pref_override', $temp);
400 if (is_null($result)) {
401 cachePrefValues($user);
402
403 if (isset($prefs_cache[$key])) {
404 $result = $prefs_cache[$key];
405 } else {
406 //FIXME: is there a justification for having two prefs hooks so close? who uses them?
407 $temp = array(&$user, &$key);
408 $result = do_hook('get_pref', $temp);
409 if (is_null($result)) {
410 if (isset($this->default[$key])) {
411 $result = $this->default[$key];
412 } else {
413 $result = $default;
414 }
415 }
416 }
417 }
418 return $result;
419 }
420
421 /**
422 * Delete user's prefs setting
423 *
424 * @param string $user user name
425 * @param string $key preference name
426 *
427 * @return boolean
428 *
429 */
430 function deleteKey($user, $key) {
431 global $prefs_cache, $use_pdo, $pdo_show_sql_errors;
432
433 if (!$this->open()) {
434 return false;
435 }
436 if ($use_pdo) {
437 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 . ' = ?'))) {
438 if ($pdo_show_sql_errors)
439 $this->error = implode(' - ', $this->dbh->errorInfo());
440 else
441 $this->error = _("Could not prepare query");
442 $this->failQuery();
443 }
444 if (!($res = $sth->execute(array($user, $key)))) {
445 if ($pdo_show_sql_errors)
446 $this->error = implode(' - ', $sth->errorInfo());
447 else
448 $this->error = _("Could not execute query");
449 $this->failQuery();
450 }
451 } else {
452 $query = sprintf("DELETE FROM %s WHERE %s='%s' AND %s='%s'",
453 $this->table,
454 $this->user_field,
455 $this->dbh->quoteString($user),
456 $this->key_field,
457 $this->dbh->quoteString($key));
458
459 $res = $this->dbh->simpleQuery($query);
460 if(DB::isError($res)) {
461 $this->failQuery($res);
462 }
463 }
464
465 unset($prefs_cache[$key]);
466
467 return true;
468 }
469
470 /**
471 * Set user's preference
472 *
473 * @param string $user user name
474 * @param string $key preference name
475 * @param mixed $value preference value
476 *
477 * @return boolean
478 *
479 */
480 function setKey($user, $key, $value) {
481 global $use_pdo, $pdo_show_sql_errors;
482 if (!$this->open()) {
483 return false;
484 }
485
486 /**
487 * Check if username fits into db field
488 */
489 if (strlen($user) > $this->user_size) {
490 $this->error = "Oversized username value."
491 ." Your preferences can't be saved."
492 ." See the administrator's manual or contact your system administrator.";
493
494 /**
495 * Debugging function. Can be used to log all issues that trigger
496 * oversized field errors. Function should be enabled in all three
497 * strlen checks. See http://www.php.net/error-log
498 */
499 // error_log($user.'|'.$key.'|'.$value."\n",3,'/tmp/oversized_log');
500
501 // error is fatal
502 $this->failQuery(null);
503 }
504 /**
505 * Check if preference key fits into db field
506 */
507 if (strlen($key) > $this->key_size) {
508 $err_msg = "Oversized user's preference key."
509 ." Some preferences were not saved."
510 ." See the administrator's manual or contact your system administrator.";
511 // error is not fatal. Only some preference is not saved.
512 trigger_error($err_msg,E_USER_WARNING);
513 return false;
514 }
515 /**
516 * Check if preference value fits into db field
517 */
518 if (strlen($value) > $this->val_size) {
519 $err_msg = "Oversized user's preference value."
520 ." Some preferences were not saved."
521 ." See the administrator's manual or contact your system administrator.";
522 // error is not fatal. Only some preference is not saved.
523 trigger_error($err_msg,E_USER_WARNING);
524 return false;
525 }
526
527
528 if ($this->db_type == SMDB_MYSQL) {
529 if ($use_pdo) {
530 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 (?, ?, ?)'))) {
531 if ($pdo_show_sql_errors)
532 $this->error = implode(' - ', $this->dbh->errorInfo());
533 else
534 $this->error = _("Could not prepare query");
535 $this->failQuery();
536 }
537 if (!($res = $sth->execute(array($user, $key, $value)))) {
538 if ($pdo_show_sql_errors)
539 $this->error = implode(' - ', $sth->errorInfo());
540 else
541 $this->error = _("Could not execute query");
542 $this->failQuery();
543 }
544 } else {
545 $query = sprintf("REPLACE INTO %s (%s, %s, %s) ".
546 "VALUES('%s','%s','%s')",
547 $this->table,
548 $this->user_field,
549 $this->key_field,
550 $this->val_field,
551 $this->dbh->quoteString($user),
552 $this->dbh->quoteString($key),
553 $this->dbh->quoteString($value));
554
555 $res = $this->dbh->simpleQuery($query);
556 if(DB::isError($res)) {
557 $this->failQuery($res);
558 }
559 }
560 } elseif ($this->db_type == SMDB_PGSQL) {
561 if ($use_pdo) {
562 if ($this->dbh->exec('BEGIN TRANSACTION') === FALSE) {
563 if ($pdo_show_sql_errors)
564 $this->error = implode(' - ', $this->dbh->errorInfo());
565 else
566 $this->error = _("Could not execute query");
567 $this->failQuery();
568 }
569 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 . ' = ?'))) {
570 if ($pdo_show_sql_errors)
571 $this->error = implode(' - ', $this->dbh->errorInfo());
572 else
573 $this->error = _("Could not prepare query");
574 $this->failQuery();
575 }
576 if (!($res = $sth->execute(array($user, $key)))) {
577 if ($pdo_show_sql_errors)
578 $this->error = implode(' - ', $sth->errorInfo());
579 else
580 $this->error = _("Could not execute query");
581 $this->dbh->exec('ROLLBACK TRANSACTION');
582 $this->failQuery();
583 }
584 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 (?, ?, ?)'))) {
585 if ($pdo_show_sql_errors)
586 $this->error = implode(' - ', $this->dbh->errorInfo());
587 else
588 $this->error = _("Could not prepare query");
589 $this->failQuery();
590 }
591 if (!($res = $sth->execute(array($user, $key, $value)))) {
592 if ($pdo_show_sql_errors)
593 $this->error = implode(' - ', $sth->errorInfo());
594 else
595 $this->error = _("Could not execute query");
596 $this->dbh->exec('ROLLBACK TRANSACTION');
597 $this->failQuery();
598 }
599 if ($this->dbh->exec('COMMIT TRANSACTION') === FALSE) {
600 if ($pdo_show_sql_errors)
601 $this->error = implode(' - ', $this->dbh->errorInfo());
602 else
603 $this->error = _("Could not execute query");
604 $this->failQuery();
605 }
606 } else {
607 $this->dbh->simpleQuery("BEGIN TRANSACTION");
608 $query = sprintf("DELETE FROM %s WHERE %s='%s' AND %s='%s'",
609 $this->table,
610 $this->user_field,
611 $this->dbh->quoteString($user),
612 $this->key_field,
613 $this->dbh->quoteString($key));
614 $res = $this->dbh->simpleQuery($query);
615 if (DB::isError($res)) {
616 $this->dbh->simpleQuery("ROLLBACK TRANSACTION");
617 $this->failQuery($res);
618 }
619 $query = sprintf("INSERT INTO %s (%s, %s, %s) VALUES ('%s', '%s', '%s')",
620 $this->table,
621 $this->user_field,
622 $this->key_field,
623 $this->val_field,
624 $this->dbh->quoteString($user),
625 $this->dbh->quoteString($key),
626 $this->dbh->quoteString($value));
627 $res = $this->dbh->simpleQuery($query);
628 if (DB::isError($res)) {
629 $this->dbh->simpleQuery("ROLLBACK TRANSACTION");
630 $this->failQuery($res);
631 }
632 $this->dbh->simpleQuery("COMMIT TRANSACTION");
633 }
634 } else {
635 if ($use_pdo) {
636 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 . ' = ?'))) {
637 if ($pdo_show_sql_errors)
638 $this->error = implode(' - ', $this->dbh->errorInfo());
639 else
640 $this->error = _("Could not prepare query");
641 $this->failQuery();
642 }
643 if (!($res = $sth->execute(array($user, $key)))) {
644 if ($pdo_show_sql_errors)
645 $this->error = implode(' - ', $sth->errorInfo());
646 else
647 $this->error = _("Could not execute query");
648 $this->failQuery();
649 }
650 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 (?, ?, ?)'))) {
651 if ($pdo_show_sql_errors)
652 $this->error = implode(' - ', $this->dbh->errorInfo());
653 else
654 $this->error = _("Could not prepare query");
655 $this->failQuery();
656 }
657 if (!($res = $sth->execute(array($user, $key, $value)))) {
658 if ($pdo_show_sql_errors)
659 $this->error = implode(' - ', $sth->errorInfo());
660 else
661 $this->error = _("Could not execute query");
662 $this->failQuery();
663 }
664 } else {
665 $query = sprintf("DELETE FROM %s WHERE %s='%s' AND %s='%s'",
666 $this->table,
667 $this->user_field,
668 $this->dbh->quoteString($user),
669 $this->key_field,
670 $this->dbh->quoteString($key));
671 $res = $this->dbh->simpleQuery($query);
672 if (DB::isError($res)) {
673 $this->failQuery($res);
674 }
675 $query = sprintf("INSERT INTO %s (%s, %s, %s) VALUES ('%s', '%s', '%s')",
676 $this->table,
677 $this->user_field,
678 $this->key_field,
679 $this->val_field,
680 $this->dbh->quoteString($user),
681 $this->dbh->quoteString($key),
682 $this->dbh->quoteString($value));
683 $res = $this->dbh->simpleQuery($query);
684 if (DB::isError($res)) {
685 $this->failQuery($res);
686 }
687 }
688 }
689
690 return true;
691 }
692
693 /**
694 * Fill preference cache array
695 *
696 * @param string $user user name
697 *
698 * @since 1.2.3
699 *
700 */
701 function fillPrefsCache($user) {
702 global $prefs_cache, $use_pdo, $pdo_show_sql_errors;
703
704 if (!$this->open()) {
705 return;
706 }
707
708 $prefs_cache = array();
709 if ($use_pdo) {
710 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 . ' = ?'))) {
711 if ($pdo_show_sql_errors)
712 $this->error = implode(' - ', $this->dbh->errorInfo());
713 else
714 $this->error = _("Could not prepare query");
715 $this->failQuery();
716 }
717 if (!($res = $sth->execute(array($user)))) {
718 if ($pdo_show_sql_errors)
719 $this->error = implode(' - ', $sth->errorInfo());
720 else
721 $this->error = _("Could not execute query");
722 $this->failQuery();
723 }
724
725 while ($row = $sth->fetch(PDO::FETCH_ASSOC)) {
726 $prefs_cache[$row['prefkey']] = $row['prefval'];
727 }
728 } else {
729 $query = sprintf("SELECT %s as prefkey, %s as prefval FROM %s ".
730 "WHERE %s = '%s'",
731 $this->key_field,
732 $this->val_field,
733 $this->table,
734 $this->user_field,
735 $this->dbh->quoteString($user));
736 $res = $this->dbh->query($query);
737 if (DB::isError($res)) {
738 $this->failQuery($res);
739 }
740
741 while ($row = $res->fetchRow(DB_FETCHMODE_ASSOC)) {
742 $prefs_cache[$row['prefkey']] = $row['prefval'];
743 }
744 }
745 }
746
747 } /* end class dbPrefs */
748
749
750 /**
751 * Returns the value for the requested preference
752 * @ignore
753 */
754 function getPref($data_dir, $username, $pref_name, $default = '') {
755 $db = new dbPrefs;
756 if(isset($db->error)) {
757 printf( _("Preference database error (%s). Exiting abnormally"),
758 $db->error);
759 exit;
760 }
761
762 return $db->getKey($username, $pref_name, $default);
763 }
764
765 /**
766 * Remove the desired preference setting ($pref_name)
767 * @ignore
768 */
769 function removePref($data_dir, $username, $pref_name) {
770 global $prefs_cache;
771 $db = new dbPrefs;
772 if(isset($db->error)) {
773 $db->failQuery();
774 }
775
776 $db->deleteKey($username, $pref_name);
777
778 if (isset($prefs_cache[$pref_name])) {
779 unset($prefs_cache[$pref_name]);
780 }
781
782 sqsession_register($prefs_cache , 'prefs_cache');
783 return;
784 }
785
786 /**
787 * Sets the desired preference setting ($pref_name) to whatever is in $value
788 * @ignore
789 */
790 function setPref($data_dir, $username, $pref_name, $value) {
791 global $prefs_cache;
792
793 if (isset($prefs_cache[$pref_name]) && ($prefs_cache[$pref_name] == $value)) {
794 return;
795 }
796
797 if ($value === '') {
798 removePref($data_dir, $username, $pref_name);
799 return;
800 }
801
802 $db = new dbPrefs;
803 if(isset($db->error)) {
804 $db->failQuery();
805 }
806
807 $db->setKey($username, $pref_name, $value);
808 $prefs_cache[$pref_name] = $value;
809 assert_options(ASSERT_ACTIVE, 1);
810 assert_options(ASSERT_BAIL, 1);
811 assert ('$value == $prefs_cache[$pref_name]');
812 sqsession_register($prefs_cache , 'prefs_cache');
813 return;
814 }
815
816 /**
817 * This checks if the prefs are available
818 * @ignore
819 */
820 function checkForPrefs($data_dir, $username) {
821 $db = new dbPrefs;
822 if(isset($db->error)) {
823 $db->failQuery();
824 }
825 }
826
827 /**
828 * Writes the Signature
829 * @ignore
830 */
831 function setSig($data_dir, $username, $number, $value) {
832 if ($number == "g") {
833 $key = '___signature___';
834 } else {
835 $key = sprintf('___sig%s___', $number);
836 }
837 setPref($data_dir, $username, $key, $value);
838 return;
839 }
840
841 /**
842 * Gets the signature
843 * @ignore
844 */
845 function getSig($data_dir, $username, $number) {
846 if ($number == "g") {
847 $key = '___signature___';
848 } else {
849 $key = sprintf('___sig%d___', $number);
850 }
851 return getPref($data_dir, $username, $key);
852 }