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 | * |
24 | * CREATE TABLE userprefs (user CHAR(32) NOT NULL DEFAULT '', |
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 { |
370059dd |
122 | return $default; |
2d367c68 |
123 | } |
370059dd |
124 | } |
2d367c68 |
125 | |
370059dd |
126 | function deleteKey($user, $key) { |
127 | global $prefs_cache; |
82474746 |
128 | |
2d367c68 |
129 | $this->open(); |
130 | $query = sprintf("DELETE FROM %s WHERE user='%s' AND prefkey='%s'", |
370059dd |
131 | $this->table, |
132 | $this->dbh->quoteString($user), |
133 | $this->dbh->quoteString($key)); |
82474746 |
134 | |
2d367c68 |
135 | $res = $this->dbh->simpleQuery($query); |
370059dd |
136 | if(DB::isError($res)) { |
2d367c68 |
137 | $this->failQuery($res); |
370059dd |
138 | } |
139 | |
140 | unset($prefs_cache[$key]); |
82474746 |
141 | |
2d367c68 |
142 | if(substr($key, 0, 9) == 'highlight') { |
143 | $this->renumberHighlightList($user); |
144 | } |
82474746 |
145 | |
2d367c68 |
146 | return true; |
370059dd |
147 | } |
82474746 |
148 | |
370059dd |
149 | function setKey($user, $key, $value) { |
2d367c68 |
150 | $this->open(); |
151 | $query = sprintf("REPLACE INTO %s (user,prefkey,prefval) ". |
370059dd |
152 | "VALUES('%s','%s','%s')", |
153 | $this->table, |
154 | $this->dbh->quoteString($user), |
155 | $this->dbh->quoteString($key), |
156 | $this->dbh->quoteString($value)); |
157 | |
158 | $res = $this->dbh->simpleQuery($query); |
159 | if(DB::isError($res)) { |
2d367c68 |
160 | $this->failQuery($res); |
370059dd |
161 | } |
2d367c68 |
162 | |
163 | return true; |
370059dd |
164 | } |
82474746 |
165 | |
370059dd |
166 | function fillPrefsCache($user) { |
167 | global $prefs_cache; |
2d367c68 |
168 | |
370059dd |
169 | $this->open(); |
170 | |
171 | $prefs_cache = array(); |
172 | $query = sprintf("SELECT prefkey, prefval FROM %s ". |
173 | "WHERE user = '%s'", |
174 | $this->table, |
175 | $this->dbh->quoteString($user)); |
176 | $res = $this->dbh->query($query); |
177 | if (DB::isError($res)) { |
178 | $this->failQuery($res); |
179 | } |
180 | |
181 | while ($row = $res->fetchRow(DB_FETCHMODE_ASSOC)) { |
182 | $prefs_cache[$row['prefkey']] = $row['prefval']; |
183 | } |
184 | } |
185 | |
186 | /* |
187 | * When a highlight option is deleted the preferences module |
188 | * must renumber the list. This should be done somewhere else, |
189 | * but it is not, so.... |
190 | */ |
191 | function renumberHighlightList($user) { |
2d367c68 |
192 | $this->open(); |
193 | $query = sprintf("SELECT * FROM %s WHERE user='%s' ". |
370059dd |
194 | "AND prefkey LIKE 'highlight%%' ORDER BY prefkey", |
195 | $this->table, |
196 | $this->dbh->quoteString($user)); |
2d367c68 |
197 | |
198 | $res = $this->dbh->query($query); |
370059dd |
199 | if(DB::isError($res)) { |
2d367c68 |
200 | $this->failQuery($res); |
370059dd |
201 | } |
2d367c68 |
202 | |
370059dd |
203 | /* Store old data in array */ |
2d367c68 |
204 | $rows = Array(); |
370059dd |
205 | while($row = $res->fetchRow(DB_FETCHMODE_ASSOC)) { |
2d367c68 |
206 | $rows[] = $row; |
370059dd |
207 | } |
2d367c68 |
208 | |
370059dd |
209 | /* Renumber keys of old data */ |
2d367c68 |
210 | $hilinum = 0; |
211 | for($i = 0; $i < count($rows) ; $i++) { |
212 | $oldkey = $rows[$i]['prefkey']; |
213 | $newkey = substr($oldkey, 0, 9) . $hilinum; |
214 | $hilinum++; |
215 | |
216 | if($oldkey != $newkey) { |
370059dd |
217 | $query = sprintf("UPDATE %s SET prefkey='%s' ". |
218 | "WHERE user ='%s' AND prefkey='%s'", |
219 | $this->table, |
220 | $this->dbh->quoteString($newkey), |
221 | $this->dbh->quoteString($user), |
222 | $this->dbh->quoteString($oldkey)); |
223 | |
224 | $res = $this->dbh->simpleQuery($query); |
225 | if(DB::isError($res)) { |
226 | $this->failQuery($res); |
227 | } |
2d367c68 |
228 | } |
229 | } |
230 | |
231 | return; |
370059dd |
232 | } |
82474746 |
233 | |
370059dd |
234 | } /* end class dbPrefs */ |
82474746 |
235 | |
236 | |
370059dd |
237 | /* returns the value for the pref $string */ |
238 | function getPref($data_dir, $username, $string, $default = '') { |
239 | $db = new dbPrefs; |
240 | if(isset($db->error)) { |
2d367c68 |
241 | printf( _("Preference database error (%s). Exiting abnormally"), |
370059dd |
242 | $db->error); |
2d367c68 |
243 | exit; |
370059dd |
244 | } |
245 | |
246 | return $db->getKey($username, $string, $default); |
247 | } |
248 | |
249 | /* Remove the pref $string */ |
250 | function removePref($data_dir, $username, $string) { |
251 | $db = new dbPrefs; |
252 | if(isset($db->error)) { |
253 | $db->failQuery(); |
254 | } |
255 | |
256 | $db->deleteKey($username, $string); |
257 | return; |
258 | } |
259 | |
260 | /* sets the pref, $string, to $set_to */ |
261 | function setPref($data_dir, $username, $string, $set_to) { |
262 | global $prefs_cache; |
263 | |
264 | if (isset($prefs_cache[$string]) && ($prefs_cache[$string] == $value)) { |
265 | return; |
266 | } |
267 | |
268 | if ($set_to == '') { |
269 | removePref($data_dir, $username, $string); |
270 | return; |
271 | } |
272 | |
273 | $db = new dbPrefs; |
274 | if(isset($db->error)) { |
275 | $db->failQuery(); |
276 | } |
277 | |
278 | $db->setKey($username, $string, $set_to); |
279 | $prefs_cache[$string] = $set_to; |
280 | assert_options(ASSERT_ACTIVE, 1); |
281 | assert_options(ASSERT_BAIL, 1); |
282 | assert ('$set_to == $prefs_cache[$string]'); |
283 | |
284 | return; |
285 | } |
286 | |
287 | /* This checks if the prefs are available */ |
288 | function checkForPrefs($data_dir, $username) { |
289 | $db = new dbPrefs; |
290 | if(isset($db->error)) { |
291 | $db->failQuery(); |
292 | } |
293 | } |
294 | |
295 | /* Writes the Signature */ |
296 | function setSig($data_dir, $username, $string) { |
297 | $db = new dbPrefs; |
298 | if(isset($db->error)) { |
299 | $db->failQuery(); |
300 | } |
301 | |
302 | $db->setKey($username, '___signature___', $string); |
303 | return; |
304 | } |
305 | |
306 | /* Gets the signature */ |
307 | function getSig($data_dir, $username) { |
308 | $db = new dbPrefs; |
309 | if(isset($db->error)) { |
310 | $db->failQuery(); |
311 | } |
312 | |
313 | return $db->getKey($username, '___signature___'); |
314 | } |
315 | |
316 | /* Hashing functions */ |
317 | |
318 | function getHashedFile($username, $dir, $datafile, $hash_search = true) { |
319 | global $dir_hash_level; |
320 | |
321 | /* Remove trailing slash from $dir if found */ |
322 | if (substr($dir, -1) == '/') { |
323 | $dir = substr($dir, 0, strlen($dir) - 1); |
324 | } |
325 | |
326 | /* Compute the hash for this user and extract the hash directories. */ |
327 | $hash_dirs = computeHashDirs($username); |
328 | |
329 | /* First, get and make sure the full hash directory exists. */ |
330 | $real_hash_dir = getHashedDir($username, $dir, $hash_dirs); |
331 | |
332 | /* Set the value of our real data file. */ |
333 | $result = "$real_hash_dir/$datafile"; |
334 | |
335 | /* Check for this file in the real hash directory. */ |
336 | if ($hash_search && !@file_exists($result)) { |
337 | /* First check the base directory, the most common location. */ |
338 | if (@file_exists("$dir/$datafile")) { |
339 | rename("$dir/$datafile", $result); |
340 | |
341 | /* Then check the full range of possible hash directories. */ |
342 | } else { |
343 | $check_hash_dir = $dir; |
344 | for ($h = 0; $h < 4; ++$h) { |
345 | $check_hash_dir .= '/' . $hash_dirs[$h]; |
346 | if (@is_readable("$check_hash_dir/$datafile")) { |
347 | rename("$check_hash_dir/$datafile", $result); |
348 | break; |
349 | } |
350 | } |
351 | } |
352 | } |
353 | |
354 | /* Return the full hashed datafile path. */ |
355 | return ($result); |
356 | } |
357 | |
358 | function getHashedDir($username, $dir, $hash_dirs = '') { |
359 | global $dir_hash_level; |
360 | |
361 | /* Remove trailing slash from $dir if found */ |
362 | if (substr($dir, -1) == '/') { |
363 | $dir = substr($dir, 0, strlen($dir) - 1); |
364 | } |
365 | |
366 | /* If necessary, populate the hash dir variable. */ |
367 | if ($hash_dirs == '') { |
368 | $hash_dirs = computeHashDirs($username); |
369 | } |
370 | |
371 | /* Make sure the full hash directory exists. */ |
372 | $real_hash_dir = $dir; |
373 | for ($h = 0; $h < $dir_hash_level; ++$h) { |
374 | $real_hash_dir .= '/' . $hash_dirs[$h]; |
375 | if (!@is_dir($real_hash_dir)) { |
376 | if (!@mkdir($real_hash_dir, 0770)) { |
377 | echo sprintf(_("Error creating directory %s."), $real_hash_dir) . '<br>'; |
378 | echo _("Could not create hashed directory structure!") . "<br>\n"; |
379 | echo _("Please contact your system administrator and report this error.") . "<br>\n"; |
380 | exit; |
381 | } |
382 | } |
383 | } |
384 | |
385 | /* And return that directory. */ |
386 | return ($real_hash_dir); |
387 | } |
388 | |
389 | function computeHashDirs($username) { |
390 | /* Compute the hash for this user and extract the hash directories. */ |
391 | $hash = base_convert(crc32($username), 10, 16); |
392 | $hash_dirs = array(); |
393 | for ($h = 0; $h < 4; ++ $h) { |
394 | $hash_dirs[] = substr($hash, $h, 1); |
395 | } |
396 | |
397 | /* Return our array of hash directories. */ |
398 | return ($hash_dirs); |
399 | } |
82474746 |
400 | |
401 | ?> |