comma in wrong place.
[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
259 /* look in $_GET array for 'switch' */
260 if ( sqgetGlobalVar('switch', $switch, SQ_GET) ) {
261 if ( $colapse[$switch] == 'on' ) {
262 $colapse[$switch] = 'off';
263 } else {
264 $colapse[$switch] = 'on';
265 }
266 setPref($data_dir, $username, "adm_$switch", $colapse[$switch] );
267 }
268
269 echo '<form action="options.php" method="post" name="options">' .
270 '<center><table width="95%" bgcolor="'.$color[5].'"><tr><td>'.
271 '<table width="100%" cellspacing="0" bgcolor="'.$color[4].'">'.
272 '<tr bgcolor="'.$color[5].'"><th colspan="2">'.
273 _("Configuration Administrator").'</th></tr>'.
274 '<tr bgcolor="'.$color[5].'"><td colspan="2" align="center"><small>'.
275 _("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.").
276 '<br />'.
277 _("Run or consult conf.pl should you run into difficulty with your configuration.").
278 '</small></td></tr>';
279
280
281 $act_grp = 'Titles'; /* Active group */
282
283 foreach ( $newcfg as $k => $v ) {
284 $l = strtolower( $v );
285 $type = SMOPT_TYPE_UNDEFINED;
286 $n = substr( $k, 1 );
287 $n = str_replace( '[', '_', $n );
288 $n = str_replace( ']', '_', $n );
289 $e = 'adm_' . $n;
290 $name = $k;
291 $size = 50;
292 if ( isset( $defcfg[$k] ) ) {
293 $name = $defcfg[$k]['name'];
294 $type = $defcfg[$k]['type'];
295 if ( isset( $defcfg[$k]['size'] ) ) {
296 $size = $defcfg[$k]['size'];
297 } else {
298 $size = 40;
299 }
300 } else if ( $l == 'true' ) {
301 $v = 'TRUE';
302 $type = SMOPT_TYPE_BOOLEAN;
303 } else if ( $l == 'false' ) {
304 $v = 'FALSE';
305 $type = SMOPT_TYPE_BOOLEAN;
306 } else if ( $v{0} == "'" ) {
307 $type = SMOPT_TYPE_STRING;
308 } else if ( $v{0} == '"' ) {
309 $type = SMOPT_TYPE_STRING;
310 }
311
312 if ( substr( $k, 0, 7 ) == '$theme[' ) {
313 $type = SMOPT_TYPE_THEME;
314 } else if ( substr( $k, 0, 9 ) == '$plugins[' ) {
315 $type = SMOPT_TYPE_PLUGINS;
316 } else if ( substr( $k, 0, 13 ) == '$ldap_server[' ) {
317 $type = SMOPT_TYPE_LDAP;
318 }
319
320 if ( $type == SMOPT_TYPE_TITLE || $colapse[$act_grp] == 'off' ) {
321
322 switch ( $type ) {
323 case SMOPT_TYPE_LDAP:
324 case SMOPT_TYPE_PLUGINS:
325 case SMOPT_TYPE_THEME:
326 case SMOPT_TYPE_HIDDEN:
327 break;
328 case SMOPT_TYPE_EXTERNAL:
329 echo "<tr><td>$name</td><td><b>" .
330 $defcfg[$k]['value'] .
331 '</b></td></tr>';
332 break;
333 case SMOPT_TYPE_TITLE:
334 if ( $colapse[$k] == 'on' ) {
335 $sw = '(+)';
336 } else {
337 $sw = '(-)';
338 }
339 echo '<tr bgcolor="'.$color[0].'"><th colspan="2">'.
340 "<a href=\"options.php?switch=$k\" style=\"text-decoration:none\">".
341 '<b>'.$sw.'</b></a> '.$name.'</th></tr>';
342 $act_grp = $k;
343 break;
344 case SMOPT_TYPE_COMMENT:
345 $v = substr( $v, 1, strlen( $v ) - 2 );
346 echo "<tr><td>$name</td><td>".
347 "<b>$v</b>";
348 $newcfg[$k] = "'$v'";
349 if ( isset( $defcfg[$k]['comment'] ) ) {
350 echo ' &nbsp; ' . $defcfg[$k]['comment'];
351 }
352 echo "</td></tr>\n";
353 break;
354 case SMOPT_TYPE_INTEGER:
355 /* look for variable $e in POST, fill into $v */
356 if ( sqgetGlobalVar($e, $v, SQ_POST) ) {
357 $v = intval( $v );
358 $newcfg[$k] = $v;
359 }
360 echo "<tr><td>$name</td><td>".
361 "<input size=\"10\" name=\"adm_$n\" value=\"$v\" />";
362 if ( isset( $defcfg[$k]['comment'] ) ) {
363 echo ' &nbsp; ' . $defcfg[$k]['comment'];
364 }
365 echo "</td></tr>\n";
366 break;
367 case SMOPT_TYPE_NUMLIST:
368 if ( sqgetGlobalVar($e, $v, SQ_POST) ) {
369 $newcfg[$k] = $v;
370 }
371 echo "<tr><td>$name</td><td>";
372 echo "<select name=\"adm_$n\">";
373 foreach ( $defcfg[$k]['posvals'] as $kp => $vp ) {
374 echo "<option value=\"$kp\"";
375 if ( $kp == $v ) {
376 echo ' selected="selected"';
377 }
378 echo ">$vp</option>";
379 }
380 echo '</select>';
381 if ( isset( $defcfg[$k]['comment'] ) ) {
382 echo ' &nbsp; ' . $defcfg[$k]['comment'];
383 }
384 echo "</td></tr>\n";
385 break;
386 case SMOPT_TYPE_STRLIST:
387 if ( sqgetGlobalVar($e, $v, SQ_POST) ) {
388 $v = '"' . $v . '"';
389 $newcfg[$k] = $v;
390 }
391 echo "<tr><td>$name</td><td>".
392 "<select name=\"adm_$n\">";
393 foreach ( $defcfg[$k]['posvals'] as $kp => $vp ) {
394 echo "<option value=\"$kp\"";
395 if ( $kp == substr( $v, 1, strlen( $v ) - 2 ) ) {
396 echo ' selected="selected"';
397 }
398 echo ">$vp</option>";
399 }
400 echo '</select>';
401 if ( isset( $defcfg[$k]['comment'] ) ) {
402 echo ' &nbsp; ' . $defcfg[$k]['comment'];
403 }
404 echo "</td></tr>\n";
405 break;
406
407 case SMOPT_TYPE_TEXTAREA:
408 if ( sqgetGlobalVar($e, $v, SQ_POST) ) {
409 $v = '"' . $v . '"';
410 $newcfg[$k] = str_replace( "\n", '', $v );
411 }
412 echo "<tr><td valign=\"top\">$name</td><td>".
413 "<textarea cols=\"$size\" rows=\"4\" name=\"adm_$n\">" . substr( $v, 1, strlen( $v ) - 2 ) . "</textarea>";
414 if ( isset( $defcfg[$k]['comment'] ) ) {
415 echo ' &nbsp; ' . $defcfg[$k]['comment'];
416 }
417 echo "</td></tr>\n";
418 break;
419 case SMOPT_TYPE_STRING:
420 if ( sqgetGlobalVar($e, $v, SQ_POST) ) {
421 $v = '"' . $v . '"';
422 $newcfg[$k] = $v;
423 }
424 if ( $v == '""' && isset( $defcfg[$k]['default'] ) ) {
425 $v = "'" . $defcfg[$k]['default'] . "'";
426 $newcfg[$k] = $v;
427 }
428 echo "<tr><td>$name</td><td>".
429 "<input size=\"$size\" name=\"adm_$n\" value=\"" . substr( $v, 1, strlen( $v ) - 2 ) . '" />';
430 if ( isset( $defcfg[$k]['comment'] ) ) {
431 echo ' &nbsp; ' . $defcfg[$k]['comment'];
432 }
433 echo "</td></tr>\n";
434 break;
435 case SMOPT_TYPE_BOOLEAN:
436 if ( sqgetGlobalVar($e, $v, SQ_POST) ) {
437 $newcfg[$k] = $v;
438 } else {
439 $v = strtoupper( $v );
440 }
441 if ( $v == 'TRUE' ) {
442 $ct = ' checked="checked"';
443 $cf = '';
444 } else {
445 $ct = '';
446 $cf = ' checked="checked"';
447 }
448 echo "<tr><td>$name</td><td>" .
449 "<input$ct type=\"radio\" name=\"adm_$n\" value=\"TRUE\" />" . _("Yes") .
450 "<input$cf type=\"radio\" name=\"adm_$n\" value=\"FALSE\" />" . _("No");
451 if ( isset( $defcfg[$k]['comment'] ) ) {
452 echo ' &nbsp; ' . $defcfg[$k]['comment'];
453 }
454 echo "</td></tr>\n";
455 break;
456 case SMOPT_TYPE_PATH:
457 if ( sqgetGlobalVar($e, $v, SQ_POST) ) {
458 $v = change_to_sm_path($v);
459 $newcfg[$k] = $v;
460 }
461 if ( $v == "''" && isset( $defcfg[$k]['default'] ) ) {
462 $v = change_to_sm_path($defcfg[$k]['default']);
463 $newcfg[$k] = $v;
464 }
465 echo "<tr><td>$name</td><td>".
466 "<input size=\"$size\" name=\"adm_$n\" value=\"" . change_to_rel_path($v) . '" />';
467 if ( isset( $defcfg[$k]['comment'] ) ) {
468 echo ' &nbsp; ' . $defcfg[$k]['comment'];
469 }
470 echo "</td></tr>\n";
471 break;
472 default:
473 echo "<tr><td>$name</td><td>" .
474 "<b><i>$v</i></b>";
475 if ( isset( $defcfg[$k]['comment'] ) ) {
476 echo ' &nbsp; ' . $defcfg[$k]['comment'];
477 }
478 echo "</td></tr>\n";
479 }
480 }
481 }
482
483 /* Special Themes Block */
484 if ( $colapse['Group7'] == 'off' ) {
485 $i = 0;
486 echo '<tr><th>' . _("Theme Name") .
487 '</th><th>' . _("Theme Path") .
488 '</th></tr>';
489 while ( isset( $newcfg["\$theme[$i]['NAME']"] ) ) {
490 $k1 = "\$theme[$i]['NAME']";
491 $e1 = "theme_name_$i";
492 if ( sqgetGlobalVar($e, $v1, SQ_POST) ) {
493 $v1 = '"' . str_replace( '\"', '"', $v1 ) . '"';
494 $v1 = '"' . str_replace( '"', '\"', $v1 ) . '"';
495 $newcfg[$k1] = $v1;
496 } else {
497 $v1 = $newcfg[$k1];
498 }
499 $k2 = "\$theme[$i]['PATH']";
500 $e2 = "theme_path_$i";
501 if ( sqgetGlobalVar($e, $v2, SQ_POST) ) {
502 $v2 = change_to_sm_path($v2);
503 $newcfg[$k2] = $v2;
504 } else {
505 $v2 = $newcfg[$k2];
506 }
507 $name = substr( $v1, 1, strlen( $v1 ) - 2 );
508 $path = change_to_rel_path($v2);
509 echo '<tr>'.
510 "<td align=\"right\">$i. <input name=\"$e1\" value=\"$name\" size=\"30\" /></td>".
511 "<td><input name=\"$e2\" value=\"$path\" size=\"40\" /></td>".
512 "</tr>\n";
513 $i++;
514
515 }
516 }
517
518 /* Special Plugins Block */
519 if ( $colapse['Group8'] == 'on' ) {
520 $sw = '(+)';
521 } else {
522 $sw = '(-)';
523 }
524 echo '<tr bgcolor="'.$color[0].'"><th colspan="2">'.
525 '<a href="options.php?switch=Group8" style="text-decoration:none"><b>'.
526 $sw.'</b></a> '._("Plugins").'</th></tr>';
527
528 if ( $colapse['Group8'] == 'off' ) {
529
530 $plugpath = SM_PATH . 'plugins/';
531 if ( file_exists($plugpath) ) {
532 $fd = opendir( $plugpath );
533 $op_plugin = array();
534 $p_count = 0;
535 while (false !== ($file = readdir($fd))) {
536 if ($file != '.' && $file != '..' && $file != 'CVS' && is_dir($plugpath . $file) ) {
537 $op_plugin[] = $file;
538 $p_count++;
539 }
540 }
541 closedir($fd);
542 asort( $op_plugin );
543
544 /* Lets get the plugins that are active */
545 $plugins = array();
546 if ( sqgetGlobalVar('plg', $v, SQ_POST) ) {
547 foreach ( $op_plugin as $plg ) {
548 if ( sqgetGlobalVar("plgs_$plg", $v, SQ_POST) && $v == 'on' ) {
549 $plugins[] = $plg;
550 }
551 }
552 $i = 0;
553 foreach ( $plugins as $plg ) {
554 $k = "\$plugins[$i]";
555 $newcfg[$k] = "'$plg'";
556 $i++;
557 }
558 while ( isset( $newcfg["\$plugins[$i]"] ) ) {
559 $k = "\$plugins[$i]";
560 $newcfg[$k] = '';
561 $i++;
562 }
563 } else {
564 $i = 0;
565 while ( isset( $newcfg["\$plugins[$i]"] ) ) {
566 $k = "\$plugins[$i]";
567 $v = $newcfg[$k];
568 $plugins[] = substr( $v, 1, strlen( $v ) - 2 );
569 $i++;
570 }
571 }
572 echo '<tr><td colspan="2"><input type="hidden" name="plg" value="on" /><center><table>';
573 foreach ( $op_plugin as $plg ) {
574 if ( in_array( $plg, $plugins ) ) {
575 $sw = ' checked="checked"';
576 } else {
577 $sw = '';
578 }
579 echo '<tr><td>';
580 if (file_exists(SM_PATH . "plugins/$plg/README")) {
581 echo "<a href=\"../$plg/README\" target=\"_blank\">$plg</a>";
582 } else {
583 echo $plg;
584 }
585 echo "</td>\n".
586 "<td><input$sw type=\"checkbox\" name=\"plgs_$plg\" /></td>".
587 "</tr>\n";
588 }
589 echo '</table></center></td></tr>';
590 } else {
591 echo '<tr><td colspan="2" align="center">'.
592 sprintf(_("Plugin directory could not be found: %s"), $plugpath).
593 "</td></tr>\n";
594 }
595 }
596 echo '<tr bgcolor="'.$color[5].'"><th colspan="2"><input value="'.
597 _("Change Settings").'" type="submit" /><br />'.
598 '<a href="'.SM_PATH.'src/configtest.php" target="_blank">'.
599 _("Test Configuration")."</a></th></tr>\n".
600 '</table></td></tr></table></center></form>';
601
602 /*
603 Write the options to the file.
604 */
605
606 if ( $fp = @fopen( $cfgfile, 'w' ) ) {
607 fwrite( $fp, "<?php\n".
608 "/**\n".
609 " * SquirrelMail Configuration File\n".
610 " * Created using the Administrator Plugin\n".
611 " */\n".
612 "\n".
613 "global \$version;\n" );
614
615 foreach ( $newcfg as $k => $v ) {
616 if ( $k{0} == '$' && $v <> '' || is_int($v)) {
617 if ( substr( $k, 1, 11 ) == 'ldap_server' ) {
618 $v = substr( $v, 0, strlen( $v ) - 1 ) . "\n)";
619 $v = str_replace( 'array(', "array(\n\t", $v );
620 $v = str_replace( "',", "',\n\t", $v );
621 }
622 fwrite( $fp, "$k = $v;\n" );
623 }
624 }
625 fwrite( $fp, '?>' );
626 fclose( $fp );
627 } else {
628 echo '<br /><p align="center"><big>'.
629 _("Config file can't be opened. Please check config.php.").
630 '</big></p>';
631 }
632 ?>
633 </body></html>