adding address book block
[squirrelmail.git] / plugins / administrator / options.php
1 <?php
2
3 /**
4 * Administrator Plugin - Options Page
5 *
6 * This script creates separate page, that allows to review and modify
7 * SquirrelMail configuration file.
8 *
9 * @version $Id$
10 * @author Philippe Mingo
11 * @copyright (c) 1999-2004 The SquirrelMail Project Team
12 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
13 * @package plugins
14 * @subpackage administrator
15 */
16
17 /**
18 * parse the config file
19 *
20 * @param string $cfg_file
21 * @access private
22 */
23 function parseConfig( $cfg_file ) {
24
25 global $newcfg;
26
27 $cfg = file( $cfg_file );
28 $mode = '';
29 $l = count( $cfg );
30 $modifier = FALSE;
31
32 for ($i=0;$i<$l;$i++) {
33 $line = trim( $cfg[$i] );
34 $s = strlen( $line );
35 for ($j=0;$j<$s;$j++) {
36 switch ( $mode ) {
37 case '=':
38 if ( $line{$j} == '=' ) {
39 // Ok, we've got a right value, lets detect what type
40 $mode = 'D';
41 } else if ( $line{$j} == ';' ) {
42 // hu! end of command
43 $key = $mode = '';
44 }
45 break;
46 case 'K':
47 // Key detect
48 if ( $line{$j} == ' ' ) {
49 $mode = '=';
50 } else {
51 $key .= $line{$j};
52 }
53 break;
54 case ';':
55 // Skip until next ;
56 if ( $line{$j} == ';' ) {
57 $mode = '';
58 }
59 break;
60 case 'S':
61 if ( $line{$j} == '\\' ) {
62 $value .= $line{$j};
63 $modifier = TRUE;
64 } else if ( $line{$j} == $delimiter && $modifier === FALSE ) {
65 // End of string;
66 $newcfg[$key] = $value . $delimiter;
67 $key = $value = '';
68 $mode = ';';
69 } else {
70 $value .= $line{$j};
71 $modifier = FALSE;
72 }
73 break;
74 case 'N':
75 if ( $line{$j} == ';' ) {
76 $newcfg{$key} = $value;
77 $key = $mode = '';
78 } else {
79 $value .= $line{$j};
80 }
81 break;
82 case 'C':
83 // Comments
84 if ( $s > $j + 1 &&
85 $line{$j}.$line{$j+1} == '*/' ) {
86 $mode = '';
87 $j++;
88 }
89 break;
90 case 'D':
91 // Delimiter detect
92 switch ( $line{$j} ) {
93 case '"':
94 case "'":
95 // Double quote string
96 $delimiter = $value = $line{$j};
97 $mode = 'S';
98 break;
99 case ' ':
100 // Nothing yet
101 break;
102 default:
103 if ( strtoupper( substr( $line, $j, 4 ) ) == 'TRUE' ) {
104 // Boolean TRUE
105 $newcfg{$key} = 'TRUE';
106 $key = '';
107 $mode = ';';
108 } else if ( strtoupper( substr( $line, $j, 5 ) ) == 'FALSE' ) {
109 $newcfg{$key} = 'FALSE';
110 $key = '';
111 $mode = ';';
112 } else {
113 // Number or function call
114 $mode = 'N';
115 $value = $line{$j};
116 }
117 }
118 break;
119 default:
120 if ( $line{$j} == '$' ) {
121 // We must detect $key name
122 $mode = 'K';
123 $key = '$';
124 } else if ( $s < $j + 2 ) {
125 } else if ( strtoupper( substr( $line, $j, 7 ) ) == 'GLOBAL ' ) {
126 // Skip untill next ;
127 $mode = ';';
128 $j += 6;
129 } else if ( $line{$j}.$line{$j+1} == '/*' ) {
130 $mode = 'C';
131 $j++;
132 } else if ( $line{$j} == '#' || $line{$j}.$line{$j+1} == '//' ) {
133 // Delete till the end of the line
134 $j = $s;
135 }
136 }
137 }
138 }
139 }
140
141 /**
142 * Change paths containing SM_PATH to admin-friendly paths
143 * relative to the config dir, i.e.:
144 * '' --> <empty string>
145 * SM_PATH . 'images/logo.gif' --> ../images/logo.gif
146 * '/absolute/path/logo.gif' --> /absolute/path/logo.gif
147 * 'http://whatever/' --> http://whatever
148 * Note removal of quotes in returned value
149 *
150 * @param string $old_path path that has to be converted
151 * @return string new path
152 * @access private
153 */
154 function change_to_rel_path($old_path) {
155 $new_path = str_replace("SM_PATH . '", "../", $old_path);
156 $new_path = str_replace("../config/","", $new_path);
157 $new_path = str_replace("'","", $new_path);
158 return $new_path;
159 }
160
161 /**
162 * Change relative path (relative to config dir) to
163 * internal SM_PATH, i.e.:
164 * empty_string --> ''
165 * ../images/logo.gif --> SM_PATH . 'images/logo.gif'
166 * images/logo.gif --> SM_PATH . 'config/images/logo.gif'
167 * /absolute/path/logo.gif --> '/absolute/path/logo.gif'
168 * http://whatever/ --> 'http://whatever'
169 *
170 * @param string $old_path path that has to be converted
171 * @return string new path
172 * @access private
173 */
174 function change_to_sm_path($old_path) {
175 if ( $old_path === '' || $old_path == "''" ) {
176 return "''";
177 } elseif ( preg_match("/^(\/|http)/", $old_path) ) {
178 return "'" . $old_path . "'";
179 } elseif ( preg_match("/^(\$|SM_PATH)/", $old_path) ) {
180 return $old_path;
181 }
182
183 $new_path = '';
184 $rel_path = explode("../", $old_path);
185 if ( count($rel_path) > 2 ) {
186 // Since we're relative to the config dir,
187 // more than 1 ../ puts us OUTSIDE the SM tree.
188 // get full path to config.php, then pop the filename
189 $abs_path = explode('/', realpath (SM_PATH . 'config/config.php'));
190 array_pop ($abs_path);
191 foreach ( $rel_path as $subdir ) {
192 if ( $subdir === '' ) {
193 array_pop ($abs_path);
194 } else {
195 array_push($abs_path, $subdir);
196 }
197 }
198 foreach ($abs_path as $subdir) {
199 $new_path .= $subdir . '/';
200 }
201 $new_path = "'$new_path'";
202 } elseif ( count($rel_path) > 1 ) {
203 // we're within the SM tree, prepend SM_PATH
204 $new_path = str_replace('../',"SM_PATH . '", $old_path . "'");
205 } else {
206 // Last, if it's a relative path without a .. prefix,
207 // we're somewhere within the config dir, so prepend
208 // SM_PATH . 'config/
209 $new_path = "SM_PATH . 'config/" . $old_path . "'";
210 }
211 return $new_path;
212 }
213
214
215 /* ---------------------- main -------------------------- */
216
217 /** @ignore */
218 define('SM_PATH','../../');
219
220 /* SquirrelMail required files. */
221 require_once(SM_PATH . 'include/validate.php');
222 require_once(SM_PATH . 'functions/page_header.php');
223 require_once(SM_PATH . 'functions/imap.php');
224 require_once(SM_PATH . 'include/load_prefs.php');
225 require_once(SM_PATH . 'plugins/administrator/defines.php');
226 require_once(SM_PATH . 'plugins/administrator/auth.php');
227
228 global $data_dir, $username;
229
230 if ( !adm_check_user() ) {
231 header('Location: ' . SM_PATH . 'src/options.php') ;
232 exit;
233 }
234
235 displayPageHeader($color, 'None');
236
237 $newcfg = array( );
238
239 foreach ( $defcfg as $key => $def ) {
240 $newcfg[$key] = '';
241 }
242
243 $cfgfile = SM_PATH . 'config/config.php';
244 parseConfig( SM_PATH . 'config/config_default.php' );
245 parseConfig( $cfgfile );
246
247 $colapse = array( 'Titles' => 'off',
248 'Group1' => getPref($data_dir, $username, 'adm_Group1', 'off' ),
249 'Group2' => getPref($data_dir, $username, 'adm_Group2', 'on' ),
250 'Group3' => getPref($data_dir, $username, 'adm_Group3', 'on' ),
251 'Group4' => getPref($data_dir, $username, 'adm_Group4', 'on' ),
252 'Group5' => getPref($data_dir, $username, 'adm_Group5', 'on' ),
253 'Group6' => getPref($data_dir, $username, 'adm_Group6', 'on' ),
254 'Group7' => getPref($data_dir, $username, 'adm_Group7', 'on' ),
255 'Group8' => getPref($data_dir, $username, 'adm_Group8', 'on' ),
256 'Group9' => getPref($data_dir, $username, 'adm_Group9', 'on' ),
257 'Group10' => getPref($data_dir, $username, 'adm_Group10', 'on' ),
258 'Group11' => getPref($data_dir, $username, 'adm_Group10', 'on' ) );
259
260 /* look in $_GET array for 'switch' */
261 if ( sqgetGlobalVar('switch', $switch, SQ_GET) ) {
262 if ( $colapse[$switch] == 'on' ) {
263 $colapse[$switch] = 'off';
264 } else {
265 $colapse[$switch] = 'on';
266 }
267 setPref($data_dir, $username, "adm_$switch", $colapse[$switch] );
268 }
269
270 echo '<form action="options.php" method="post" name="options">' .
271 '<center><table width="95%" bgcolor="'.$color[5].'"><tr><td>'.
272 '<table width="100%" cellspacing="0" bgcolor="'.$color[4].'">'.
273 '<tr bgcolor="'.$color[5].'"><th colspan="2">'.
274 _("Configuration Administrator").'</th></tr>'.
275 '<tr bgcolor="'.$color[5].'"><td colspan="2" align="center"><small>'.
276 _("Note: it is recommended that you configure your system using conf.pl, and not this plugin. conf.pl contains additional information regarding the purpose of variables and appropriate values, as well as additional verification steps.").
277 '<br />'.
278 _("Run or consult conf.pl should you run into difficulty with your configuration.").
279 '</small></td></tr>';
280
281
282 $act_grp = 'Titles'; /* Active group */
283
284 foreach ( $newcfg as $k => $v ) {
285 $l = strtolower( $v );
286 $type = SMOPT_TYPE_UNDEFINED;
287 $n = substr( $k, 1 );
288 $n = str_replace( '[', '_', $n );
289 $n = str_replace( ']', '_', $n );
290 $e = 'adm_' . $n;
291 $name = $k;
292 $size = 50;
293 if ( isset( $defcfg[$k] ) ) {
294 $name = $defcfg[$k]['name'];
295 $type = $defcfg[$k]['type'];
296 if ( isset( $defcfg[$k]['size'] ) ) {
297 $size = $defcfg[$k]['size'];
298 } else {
299 $size = 40;
300 }
301 } else if ( $l == 'true' ) {
302 $v = 'TRUE';
303 $type = SMOPT_TYPE_BOOLEAN;
304 } else if ( $l == 'false' ) {
305 $v = 'FALSE';
306 $type = SMOPT_TYPE_BOOLEAN;
307 } else if ( $v{0} == "'" ) {
308 $type = SMOPT_TYPE_STRING;
309 } else if ( $v{0} == '"' ) {
310 $type = SMOPT_TYPE_STRING;
311 }
312
313 if ( substr( $k, 0, 7 ) == '$theme[' ) {
314 $type = SMOPT_TYPE_THEME;
315 } else if ( substr( $k, 0, 9 ) == '$plugins[' ) {
316 $type = SMOPT_TYPE_PLUGINS;
317 } else if ( substr( $k, 0, 13 ) == '$ldap_server[' ) {
318 $type = SMOPT_TYPE_LDAP;
319 }
320
321 if ( $type == SMOPT_TYPE_TITLE || $colapse[$act_grp] == 'off' ) {
322
323 switch ( $type ) {
324 case SMOPT_TYPE_LDAP:
325 case SMOPT_TYPE_PLUGINS:
326 case SMOPT_TYPE_THEME:
327 case SMOPT_TYPE_HIDDEN:
328 break;
329 case SMOPT_TYPE_EXTERNAL:
330 echo "<tr><td>$name</td><td><b>" .
331 $defcfg[$k]['value'] .
332 '</b></td></tr>';
333 break;
334 case SMOPT_TYPE_TITLE:
335 if ( $colapse[$k] == 'on' ) {
336 $sw = '(+)';
337 } else {
338 $sw = '(-)';
339 }
340 echo '<tr bgcolor="'.$color[0].'"><th colspan="2">'.
341 "<a href=\"options.php?switch=$k\" style=\"text-decoration:none\">".
342 '<b>'.$sw.'</b></a> '.$name.'</th></tr>';
343 $act_grp = $k;
344 break;
345 case SMOPT_TYPE_COMMENT:
346 $v = substr( $v, 1, strlen( $v ) - 2 );
347 echo "<tr><td>$name</td><td>".
348 "<b>$v</b>";
349 $newcfg[$k] = "'$v'";
350 if ( isset( $defcfg[$k]['comment'] ) ) {
351 echo ' &nbsp; ' . $defcfg[$k]['comment'];
352 }
353 echo "</td></tr>\n";
354 break;
355 case SMOPT_TYPE_INTEGER:
356 /* look for variable $e in POST, fill into $v */
357 if ( sqgetGlobalVar($e, $v, SQ_POST) ) {
358 $v = intval( $v );
359 $newcfg[$k] = $v;
360 }
361 echo "<tr><td>$name</td><td>".
362 "<input size=\"10\" name=\"adm_$n\" value=\"$v\" />";
363 if ( isset( $defcfg[$k]['comment'] ) ) {
364 echo ' &nbsp; ' . $defcfg[$k]['comment'];
365 }
366 echo "</td></tr>\n";
367 break;
368 case SMOPT_TYPE_NUMLIST:
369 if ( sqgetGlobalVar($e, $v, SQ_POST) ) {
370 $newcfg[$k] = $v;
371 }
372 echo "<tr><td>$name</td><td>";
373 echo "<select name=\"adm_$n\">";
374 foreach ( $defcfg[$k]['posvals'] as $kp => $vp ) {
375 echo "<option value=\"$kp\"";
376 if ( $kp == $v ) {
377 echo ' selected="selected"';
378 }
379 echo ">$vp</option>";
380 }
381 echo '</select>';
382 if ( isset( $defcfg[$k]['comment'] ) ) {
383 echo ' &nbsp; ' . $defcfg[$k]['comment'];
384 }
385 echo "</td></tr>\n";
386 break;
387 case SMOPT_TYPE_STRLIST:
388 if ( sqgetGlobalVar($e, $v, SQ_POST) ) {
389 $v = '"' . $v . '"';
390 $newcfg[$k] = $v;
391 }
392 echo "<tr><td>$name</td><td>".
393 "<select name=\"adm_$n\">";
394 foreach ( $defcfg[$k]['posvals'] as $kp => $vp ) {
395 echo "<option value=\"$kp\"";
396 if ( $kp == substr( $v, 1, strlen( $v ) - 2 ) ) {
397 echo ' selected="selected"';
398 }
399 echo ">$vp</option>";
400 }
401 echo '</select>';
402 if ( isset( $defcfg[$k]['comment'] ) ) {
403 echo ' &nbsp; ' . $defcfg[$k]['comment'];
404 }
405 echo "</td></tr>\n";
406 break;
407
408 case SMOPT_TYPE_TEXTAREA:
409 if ( sqgetGlobalVar($e, $v, SQ_POST) ) {
410 $v = '"' . $v . '"';
411 $newcfg[$k] = str_replace( "\n", '', $v );
412 }
413 echo "<tr><td valign=\"top\">$name</td><td>".
414 "<textarea cols=\"$size\" rows=\"4\" name=\"adm_$n\">" . substr( $v, 1, strlen( $v ) - 2 ) . "</textarea>";
415 if ( isset( $defcfg[$k]['comment'] ) ) {
416 echo ' &nbsp; ' . $defcfg[$k]['comment'];
417 }
418 echo "</td></tr>\n";
419 break;
420 case SMOPT_TYPE_STRING:
421 if ( sqgetGlobalVar($e, $v, SQ_POST) ) {
422 $v = '"' . $v . '"';
423 $newcfg[$k] = $v;
424 }
425 if ( $v == '""' && isset( $defcfg[$k]['default'] ) ) {
426 $v = "'" . $defcfg[$k]['default'] . "'";
427 $newcfg[$k] = $v;
428 }
429 echo "<tr><td>$name</td><td>".
430 "<input size=\"$size\" name=\"adm_$n\" value=\"" . substr( $v, 1, strlen( $v ) - 2 ) . '" />';
431 if ( isset( $defcfg[$k]['comment'] ) ) {
432 echo ' &nbsp; ' . $defcfg[$k]['comment'];
433 }
434 echo "</td></tr>\n";
435 break;
436 case SMOPT_TYPE_BOOLEAN:
437 if ( sqgetGlobalVar($e, $v, SQ_POST) ) {
438 $newcfg[$k] = $v;
439 } else {
440 $v = strtoupper( $v );
441 }
442 if ( $v == 'TRUE' ) {
443 $ct = ' checked="checked"';
444 $cf = '';
445 } else {
446 $ct = '';
447 $cf = ' checked="checked"';
448 }
449 echo "<tr><td>$name</td><td>" .
450 "<input$ct type=\"radio\" name=\"adm_$n\" value=\"TRUE\" />" . _("Yes") .
451 "<input$cf type=\"radio\" name=\"adm_$n\" value=\"FALSE\" />" . _("No");
452 if ( isset( $defcfg[$k]['comment'] ) ) {
453 echo ' &nbsp; ' . $defcfg[$k]['comment'];
454 }
455 echo "</td></tr>\n";
456 break;
457 case SMOPT_TYPE_PATH:
458 if ( sqgetGlobalVar($e, $v, SQ_POST) ) {
459 $v = change_to_sm_path($v);
460 $newcfg[$k] = $v;
461 }
462 if ( $v == "''" && isset( $defcfg[$k]['default'] ) ) {
463 $v = change_to_sm_path($defcfg[$k]['default']);
464 $newcfg[$k] = $v;
465 }
466 echo "<tr><td>$name</td><td>".
467 "<input size=\"$size\" name=\"adm_$n\" value=\"" . change_to_rel_path($v) . '" />';
468 if ( isset( $defcfg[$k]['comment'] ) ) {
469 echo ' &nbsp; ' . $defcfg[$k]['comment'];
470 }
471 echo "</td></tr>\n";
472 break;
473 default:
474 echo "<tr><td>$name</td><td>" .
475 "<b><i>$v</i></b>";
476 if ( isset( $defcfg[$k]['comment'] ) ) {
477 echo ' &nbsp; ' . $defcfg[$k]['comment'];
478 }
479 echo "</td></tr>\n";
480 }
481 }
482 }
483
484 /* Special Themes Block */
485 if ( $colapse['Group7'] == 'off' ) {
486 $i = 0;
487 echo '<tr><th>' . _("Theme Name") .
488 '</th><th>' . _("Theme Path") .
489 '</th></tr>';
490 while ( isset( $newcfg["\$theme[$i]['NAME']"] ) ) {
491 $k1 = "\$theme[$i]['NAME']";
492 $e1 = "theme_name_$i";
493 if ( sqgetGlobalVar($e, $v1, SQ_POST) ) {
494 $v1 = '"' . str_replace( '\"', '"', $v1 ) . '"';
495 $v1 = '"' . str_replace( '"', '\"', $v1 ) . '"';
496 $newcfg[$k1] = $v1;
497 } else {
498 $v1 = $newcfg[$k1];
499 }
500 $k2 = "\$theme[$i]['PATH']";
501 $e2 = "theme_path_$i";
502 if ( sqgetGlobalVar($e, $v2, SQ_POST) ) {
503 $v2 = change_to_sm_path($v2);
504 $newcfg[$k2] = $v2;
505 } else {
506 $v2 = $newcfg[$k2];
507 }
508 $name = substr( $v1, 1, strlen( $v1 ) - 2 );
509 $path = change_to_rel_path($v2);
510 echo '<tr>'.
511 "<td align=\"right\">$i. <input name=\"$e1\" value=\"$name\" size=\"30\" /></td>".
512 "<td><input name=\"$e2\" value=\"$path\" size=\"40\" /></td>".
513 "</tr>\n";
514 $i++;
515
516 }
517 }
518
519 /* Special Plugins Block */
520 if ( $colapse['Group8'] == 'on' ) {
521 $sw = '(+)';
522 } else {
523 $sw = '(-)';
524 }
525 echo '<tr bgcolor="'.$color[0].'"><th colspan="2">'.
526 '<a href="options.php?switch=Group8" style="text-decoration:none"><b>'.
527 $sw.'</b></a> '._("Plugins").'</th></tr>';
528
529 if ( $colapse['Group8'] == 'off' ) {
530
531 $plugpath = SM_PATH . 'plugins/';
532 if ( file_exists($plugpath) ) {
533 $fd = opendir( $plugpath );
534 $op_plugin = array();
535 $p_count = 0;
536 while (false !== ($file = readdir($fd))) {
537 if ($file != '.' && $file != '..' && $file != 'CVS' && is_dir($plugpath . $file) ) {
538 $op_plugin[] = $file;
539 $p_count++;
540 }
541 }
542 closedir($fd);
543 asort( $op_plugin );
544
545 /* Lets get the plugins that are active */
546 $plugins = array();
547 if ( sqgetGlobalVar('plg', $v, SQ_POST) ) {
548 foreach ( $op_plugin as $plg ) {
549 if ( sqgetGlobalVar("plgs_$plg", $v, SQ_POST) && $v == 'on' ) {
550 $plugins[] = $plg;
551 }
552 }
553 $i = 0;
554 foreach ( $plugins as $plg ) {
555 $k = "\$plugins[$i]";
556 $newcfg[$k] = "'$plg'";
557 $i++;
558 }
559 while ( isset( $newcfg["\$plugins[$i]"] ) ) {
560 $k = "\$plugins[$i]";
561 $newcfg[$k] = '';
562 $i++;
563 }
564 } else {
565 $i = 0;
566 while ( isset( $newcfg["\$plugins[$i]"] ) ) {
567 $k = "\$plugins[$i]";
568 $v = $newcfg[$k];
569 $plugins[] = substr( $v, 1, strlen( $v ) - 2 );
570 $i++;
571 }
572 }
573 echo '<tr><td colspan="2"><input type="hidden" name="plg" value="on" /><center><table>';
574 foreach ( $op_plugin as $plg ) {
575 if ( in_array( $plg, $plugins ) ) {
576 $sw = ' checked="checked"';
577 } else {
578 $sw = '';
579 }
580 echo '<tr><td>';
581 if (file_exists(SM_PATH . "plugins/$plg/README")) {
582 echo "<a href=\"../$plg/README\" target=\"_blank\">$plg</a>";
583 } else {
584 echo $plg;
585 }
586 echo "</td>\n".
587 "<td><input$sw type=\"checkbox\" name=\"plgs_$plg\" /></td>".
588 "</tr>\n";
589 }
590 echo '</table></center></td></tr>';
591 } else {
592 echo '<tr><td colspan="2" align="center">'.
593 sprintf(_("Plugin directory could not be found: %s"), $plugpath).
594 "</td></tr>\n";
595 }
596 }
597 echo '<tr bgcolor="'.$color[5].'"><th colspan="2"><input value="'.
598 _("Change Settings").'" type="submit" /><br />'.
599 '<a href="'.SM_PATH.'src/configtest.php" target="_blank">'.
600 _("Test Configuration")."</a></th></tr>\n".
601 '</table></td></tr></table></center></form>';
602
603 /*
604 Write the options to the file.
605 */
606
607 if ( $fp = @fopen( $cfgfile, 'w' ) ) {
608 fwrite( $fp, "<?php\n".
609 "/**\n".
610 " * SquirrelMail Configuration File\n".
611 " * Created using the Administrator Plugin\n".
612 " */\n".
613 "\n".
614 "global \$version;\n" );
615
616 foreach ( $newcfg as $k => $v ) {
617 if ( $k{0} == '$' && $v <> '' || is_int($v)) {
618 if ( substr( $k, 1, 11 ) == 'ldap_server' ) {
619 $v = substr( $v, 0, strlen( $v ) - 1 ) . "\n)";
620 $v = str_replace( 'array(', "array(\n\t", $v );
621 $v = str_replace( "',", "',\n\t", $v );
622 }
623 fwrite( $fp, "$k = $v;\n" );
624 }
625 }
626 fwrite( $fp, '?>' );
627 fclose( $fp );
628 } else {
629 echo '<br /><p align="center"><big>'.
630 _("Config file can't be opened. Please check config.php.").
631 '</big></p>';
632 }
633 ?>
634 </body></html>