82474746 |
1 | <?php |
15e6162e |
2 | |
370059dd |
3 | /* |
35586184 |
4 | * db_prefs.php |
5 | * |
15e6162e |
6 | * Copyright (c) 1999-2002 The SquirrelMail Project Team |
35586184 |
7 | * Licensed under the GNU GPL. For full terms see the file COPYING. |
8 | * |
9 | * This contains functions for manipulating user preferences |
10 | * stored in a database, accessed though the Pear DB layer. |
11 | * |
12 | * To use this instead of the regular prefs.php, create a |
13 | * database as described below, and replace prefs.php |
14 | * with this file. |
15 | * |
16 | * Database: |
17 | * --------- |
18 | * |
19 | * The preferences table should have tree columns: |
20 | * username char \ primary |
21 | * prefkey char / key |
22 | * prefval blob |
23 | * |
4b7dd3d9 |
24 | * CREATE TABLE userprefs (user CHAR(128) NOT NULL DEFAULT '', |
35586184 |
25 | * prefkey CHAR(64) NOT NULL DEFAULT '', |
26 | * prefval BLOB NOT NULL DEFAULT '', |
27 | * primary key (user,prefkey)); |
28 | * |
29 | * Configuration of databasename, username and password is done |
30 | * by changing $DSN below. |
31 | * |
32 | * $Id$ |
33 | */ |
34 | |
35586184 |
35 | require_once('DB.php'); |
36 | |
370059dd |
37 | global $prefs_are_cached, $prefs_cache; |
2d367c68 |
38 | |
370059dd |
39 | if ( !session_is_registered('prefs_are_cached') || |
40 | !isset( $prefs_cache) || |
41 | !is_array( $prefs_cache) || |
2deab9a3 |
42 | substr( phpversion(), 0, 3 ) == '4.1' ) { |
370059dd |
43 | $prefs_are_cached = false; |
44 | $prefs_cache = array(); |
45 | } |
82474746 |
46 | |
370059dd |
47 | function cachePrefValues($username) { |
48 | global $prefs_are_cached, $prefs_cache; |
49 | |
50 | if ($prefs_are_cached) { |
51 | return; |
52 | } |
2d367c68 |
53 | |
370059dd |
54 | session_unregister('prefs_cache'); |
55 | session_unregister('prefs_are_cached'); |
56 | |
57 | $db = new dbPrefs; |
58 | if(isset($db->error)) { |
59 | printf( _("Preference database error (%s). Exiting abnormally"), |
60 | $db->error); |
61 | exit; |
62 | } |
2d367c68 |
63 | |
370059dd |
64 | $db->fillPrefsCache($username); |
65 | if (isset($db->error)) { |
66 | printf( _("Preference database error (%s). Exiting abnormally"), |
67 | $db->error); |
68 | exit; |
69 | } |
70 | |
71 | $prefs_are_cached = true; |
72 | |
73 | session_register('prefs_cache'); |
74 | session_register('prefs_are_cached'); |
75 | } |
76 | |
77 | class dbPrefs { |
78 | var $DSN = 'mysql://user:passwd@host/database'; |
79 | var $table = 'userprefs'; |
80 | |
81 | var $dbh = NULL; |
82 | var $error = NULL; |
83 | |
84 | var $default = Array('chosen_theme' => '../themes/default_theme.php', |
85 | 'show_html_default' => '0'); |
86 | |
87 | function open() { |
88 | if(isset($this->dbh)) { |
89 | return true; |
90 | } |
2d367c68 |
91 | $dbh = DB::connect($this->DSN, true); |
92 | |
93 | if(DB::isError($dbh) || DB::isWarning($dbh)) { |
94 | $this->error = DB::errorMessage($dbh); |
95 | return false; |
96 | } |
97 | |
98 | $this->dbh = $dbh; |
99 | return true; |
370059dd |
100 | } |
82474746 |
101 | |
370059dd |
102 | function failQuery($res = NULL) { |
2d367c68 |
103 | if($res == NULL) { |
104 | printf(_("Preference database error (%s). Exiting abnormally"), |
370059dd |
105 | $this->error); |
2d367c68 |
106 | } else { |
107 | printf(_("Preference database error (%s). Exiting abnormally"), |
370059dd |
108 | DB::errorMessage($res)); |
2d367c68 |
109 | } |
110 | exit; |
370059dd |
111 | } |
82474746 |
112 | |
113 | |
370059dd |
114 | function getKey($user, $key, $default = '') { |
115 | global $prefs_cache; |
2d367c68 |
116 | |
370059dd |
117 | cachePrefValues($user); |
2d367c68 |
118 | |
370059dd |
119 | if (isset($prefs_cache[$key])) { |
120 | return $prefs_cache[$key]; |
2d367c68 |
121 | } else { |
62337234 |
122 | if (isset($this->default[$key])) { |
123 | return $this->default[$key]; |
124 | } else { |
125 | return $default; |
126 | } |
2d367c68 |
127 | } |
370059dd |
128 | } |
2d367c68 |
129 | |
370059dd |
130 | function deleteKey($user, $key) { |
131 | global $prefs_cache; |
82474746 |
132 | |
2d367c68 |
133 | $this->open(); |
134 | $query = sprintf("DELETE FROM %s WHERE user='%s' AND prefkey='%s'", |
370059dd |
135 | $this->table, |
136 | $this->dbh->quoteString($user), |
137 | $this->dbh->quoteString($key)); |
82474746 |
138 | |
2d367c68 |
139 | $res = $this->dbh->simpleQuery($query); |
370059dd |
140 | if(DB::isError($res)) { |
2d367c68 |
141 | $this->failQuery($res); |
370059dd |
142 | } |
143 | |
144 | unset($prefs_cache[$key]); |
82474746 |
145 | |
2d367c68 |
146 | if(substr($key, 0, 9) == 'highlight') { |
147 | $this->renumberHighlightList($user); |
148 | } |
82474746 |
149 | |
2d367c68 |
150 | return true; |
370059dd |
151 | } |
82474746 |
152 | |
370059dd |
153 | function setKey($user, $key, $value) { |
2d367c68 |
154 | $this->open(); |
155 | $query = sprintf("REPLACE INTO %s (user,prefkey,prefval) ". |
370059dd |
156 | "VALUES('%s','%s','%s')", |
157 | $this->table, |
158 | $this->dbh->quoteString($user), |
159 | $this->dbh->quoteString($key), |
160 | $this->dbh->quoteString($value)); |
161 | |
162 | $res = $this->dbh->simpleQuery($query); |
163 | if(DB::isError($res)) { |
2d367c68 |
164 | $this->failQuery($res); |
370059dd |
165 | } |
2d367c68 |
166 | |
167 | return true; |
370059dd |
168 | } |
82474746 |
169 | |
370059dd |
170 | function fillPrefsCache($user) { |
171 | global $prefs_cache; |
2d367c68 |
172 | |
370059dd |
173 | $this->open(); |
174 | |
175 | $prefs_cache = array(); |
176 | $query = sprintf("SELECT prefkey, prefval FROM %s ". |
177 | "WHERE user = '%s'", |
178 | $this->table, |
179 | $this->dbh->quoteString($user)); |
180 | $res = $this->dbh->query($query); |
181 | if (DB::isError($res)) { |
182 | $this->failQuery($res); |
183 | } |
184 | |
185 | while ($row = $res->fetchRow(DB_FETCHMODE_ASSOC)) { |
186 | $prefs_cache[$row['prefkey']] = $row['prefval']; |
187 | } |
188 | } |
189 | |
190 | /* |
191 | * When a highlight option is deleted the preferences module |
192 | * must renumber the list. This should be done somewhere else, |
193 | * but it is not, so.... |
194 | */ |
195 | function renumberHighlightList($user) { |
2d367c68 |
196 | $this->open(); |
197 | $query = sprintf("SELECT * FROM %s WHERE user='%s' ". |
370059dd |
198 | "AND prefkey LIKE 'highlight%%' ORDER BY prefkey", |
199 | $this->table, |
200 | $this->dbh->quoteString($user)); |
2d367c68 |
201 | |
202 | $res = $this->dbh->query($query); |
370059dd |
203 | if(DB::isError($res)) { |
2d367c68 |
204 | $this->failQuery($res); |
370059dd |
205 | } |
2d367c68 |
206 | |
370059dd |
207 | /* Store old data in array */ |
2d367c68 |
208 | $rows = Array(); |
370059dd |
209 | while($row = $res->fetchRow(DB_FETCHMODE_ASSOC)) { |
2d367c68 |
210 | $rows[] = $row; |
370059dd |
211 | } |
2d367c68 |
212 | |
370059dd |
213 | /* Renumber keys of old data */ |
2d367c68 |
214 | $hilinum = 0; |
215 | for($i = 0; $i < count($rows) ; $i++) { |
216 | $oldkey = $rows[$i]['prefkey']; |
217 | $newkey = substr($oldkey, 0, 9) . $hilinum; |
218 | $hilinum++; |
219 | |
220 | if($oldkey != $newkey) { |
370059dd |
221 | $query = sprintf("UPDATE %s SET prefkey='%s' ". |
222 | "WHERE user ='%s' AND prefkey='%s'", |
223 | $this->table, |
224 | $this->dbh->quoteString($newkey), |
225 | $this->dbh->quoteString($user), |
226 | $this->dbh->quoteString($oldkey)); |
227 | |
228 | $res = $this->dbh->simpleQuery($query); |
229 | if(DB::isError($res)) { |
230 | $this->failQuery($res); |
231 | } |
2d367c68 |
232 | } |
233 | } |
234 | |
235 | return; |
370059dd |
236 | } |
82474746 |
237 | |
370059dd |
238 | } /* end class dbPrefs */ |
82474746 |
239 | |
240 | |
370059dd |
241 | /* returns the value for the pref $string */ |
242 | function getPref($data_dir, $username, $string, $default = '') { |
243 | $db = new dbPrefs; |
244 | if(isset($db->error)) { |
2d367c68 |
245 | printf( _("Preference database error (%s). Exiting abnormally"), |
370059dd |
246 | $db->error); |
2d367c68 |
247 | exit; |
370059dd |
248 | } |
249 | |
250 | return $db->getKey($username, $string, $default); |
251 | } |
252 | |
253 | /* Remove the pref $string */ |
254 | function removePref($data_dir, $username, $string) { |
255 | $db = new dbPrefs; |
256 | if(isset($db->error)) { |
257 | $db->failQuery(); |
258 | } |
259 | |
260 | $db->deleteKey($username, $string); |
261 | return; |
262 | } |
263 | |
264 | /* sets the pref, $string, to $set_to */ |
265 | function setPref($data_dir, $username, $string, $set_to) { |
266 | global $prefs_cache; |
267 | |
4b7dd3d9 |
268 | if (isset($prefs_cache[$string]) && ($prefs_cache[$string] == $set_to)) { |
370059dd |
269 | return; |
270 | } |
271 | |
272 | if ($set_to == '') { |
273 | removePref($data_dir, $username, $string); |
274 | return; |
275 | } |
276 | |
277 | $db = new dbPrefs; |
278 | if(isset($db->error)) { |
279 | $db->failQuery(); |
280 | } |
281 | |
282 | $db->setKey($username, $string, $set_to); |
283 | $prefs_cache[$string] = $set_to; |
284 | assert_options(ASSERT_ACTIVE, 1); |
285 | assert_options(ASSERT_BAIL, 1); |
286 | assert ('$set_to == $prefs_cache[$string]'); |
287 | |
288 | return; |
289 | } |
290 | |
291 | /* This checks if the prefs are available */ |
292 | function checkForPrefs($data_dir, $username) { |
293 | $db = new dbPrefs; |
294 | if(isset($db->error)) { |
295 | $db->failQuery(); |
296 | } |
297 | } |
298 | |
299 | /* Writes the Signature */ |
300 | function setSig($data_dir, $username, $string) { |
301 | $db = new dbPrefs; |
302 | if(isset($db->error)) { |
303 | $db->failQuery(); |
304 | } |
305 | |
306 | $db->setKey($username, '___signature___', $string); |
307 | return; |
308 | } |
309 | |
310 | /* Gets the signature */ |
311 | function getSig($data_dir, $username) { |
312 | $db = new dbPrefs; |
313 | if(isset($db->error)) { |
314 | $db->failQuery(); |
315 | } |
316 | |
317 | return $db->getKey($username, '___signature___'); |
318 | } |
319 | |
320 | /* Hashing functions */ |
321 | |
322 | function getHashedFile($username, $dir, $datafile, $hash_search = true) { |
323 | global $dir_hash_level; |
324 | |
325 | /* Remove trailing slash from $dir if found */ |
326 | if (substr($dir, -1) == '/') { |
327 | $dir = substr($dir, 0, strlen($dir) - 1); |
328 | } |
329 | |
330 | /* Compute the hash for this user and extract the hash directories. */ |
331 | $hash_dirs = computeHashDirs($username); |
332 | |
333 | /* First, get and make sure the full hash directory exists. */ |
334 | $real_hash_dir = getHashedDir($username, $dir, $hash_dirs); |
335 | |
336 | /* Set the value of our real data file. */ |
337 | $result = "$real_hash_dir/$datafile"; |
338 | |
339 | /* Check for this file in the real hash directory. */ |
340 | if ($hash_search && !@file_exists($result)) { |
341 | /* First check the base directory, the most common location. */ |
342 | if (@file_exists("$dir/$datafile")) { |
343 | rename("$dir/$datafile", $result); |
344 | |
345 | /* Then check the full range of possible hash directories. */ |
346 | } else { |
347 | $check_hash_dir = $dir; |
348 | for ($h = 0; $h < 4; ++$h) { |
349 | $check_hash_dir .= '/' . $hash_dirs[$h]; |
350 | if (@is_readable("$check_hash_dir/$datafile")) { |
351 | rename("$check_hash_dir/$datafile", $result); |
352 | break; |
353 | } |
354 | } |
355 | } |
356 | } |
357 | |
358 | /* Return the full hashed datafile path. */ |
359 | return ($result); |
360 | } |
361 | |
362 | function getHashedDir($username, $dir, $hash_dirs = '') { |
363 | global $dir_hash_level; |
364 | |
365 | /* Remove trailing slash from $dir if found */ |
366 | if (substr($dir, -1) == '/') { |
367 | $dir = substr($dir, 0, strlen($dir) - 1); |
368 | } |
369 | |
370 | /* If necessary, populate the hash dir variable. */ |
371 | if ($hash_dirs == '') { |
372 | $hash_dirs = computeHashDirs($username); |
373 | } |
374 | |
375 | /* Make sure the full hash directory exists. */ |
376 | $real_hash_dir = $dir; |
377 | for ($h = 0; $h < $dir_hash_level; ++$h) { |
378 | $real_hash_dir .= '/' . $hash_dirs[$h]; |
379 | if (!@is_dir($real_hash_dir)) { |
380 | if (!@mkdir($real_hash_dir, 0770)) { |
381 | echo sprintf(_("Error creating directory %s."), $real_hash_dir) . '<br>'; |
382 | echo _("Could not create hashed directory structure!") . "<br>\n"; |
383 | echo _("Please contact your system administrator and report this error.") . "<br>\n"; |
384 | exit; |
385 | } |
386 | } |
387 | } |
388 | |
389 | /* And return that directory. */ |
390 | return ($real_hash_dir); |
391 | } |
392 | |
393 | function computeHashDirs($username) { |
394 | /* Compute the hash for this user and extract the hash directories. */ |
395 | $hash = base_convert(crc32($username), 10, 16); |
396 | $hash_dirs = array(); |
397 | for ($h = 0; $h < 4; ++ $h) { |
398 | $hash_dirs[] = substr($hash, $h, 1); |
399 | } |
400 | |
401 | /* Return our array of hash directories. */ |
402 | return ($hash_dirs); |
403 | } |
82474746 |
404 | |
405 | ?> |