1 <?php // $Id: configurator.php,v 1.45 2006-12-23 16:12:16 rurban Exp $
3 * Copyright 2002,2003,2005 $ThePhpWikiProgrammingTeam
4 * Copyright 2002 Martin Geisler <gimpster@gimpster.com>
6 * This file is part of PhpWiki.
7 * Parts of this file were based on PHPWeather's configurator.php file.
8 * http://sourceforge.net/projects/phpweather/
10 * PhpWiki is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * PhpWiki is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with PhpWiki; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 * Starts automatically the first time by IniConfig("config/config.ini")
27 * if it doesn't exist.
30 * o Initial expand ?show=_part1 (the part id)
31 * o read config-default.ini and use this as default_values
32 * o commented / optional: non-default values should not be commented!
33 * default values if optional can be omitted.
34 * o validate input (fix javascript, add POST checks)
35 * o start this automatically the first time
38 * 1.3.11 TODO: (or 1.3.12?)
39 * o parse_ini_file("config-dist.ini") for the commented vars
40 * o check automatically for commented and optional vars
41 * o fix _optional, to ignore existing config.ini and only use config-default.ini values
42 * o mixin class for commented
43 * o fix SQL quotes, AUTH_ORDER quotes and file forward slashes
44 * o posted values validation, extend js validation for sane DB values
45 * o read config-dist.ini into sections, comments, and optional/required settings
47 * A file config/config.ini will be automatically generated, if writable.
49 * NOTE: If you have a starterscript outside PHPWIKI_DIR but no
50 * config/config.ini yet (very unlikely!), you must define DATA_PATH in the
51 * starterscript, otherwise the webpath to configurator is unknown, and
52 * subsequent requests will fail. (POST to save the INI)
55 global $HTTP_SERVER_VARS, $HTTP_POST_VARS, $tdwidth;
56 if (empty($_SERVER)) $_SERVER =& $GLOBALS['HTTP_SERVER_VARS'];
57 if (empty($_GET)) $_GET =& $GLOBALS['HTTP_GET_VARS'];
58 if (empty($_ENV)) $_ENV =& $GLOBALS['HTTP_ENV_VARS'];
59 if (empty($_POST)) $_POST =& $GLOBALS['HTTP_POST_VARS'];
61 if (empty($configurator))
62 $configurator = "configurator.php";
63 if (!strstr($_SERVER["SCRIPT_NAME"], $configurator) and defined('DATA_PATH'))
64 $configurator = DATA_PATH . "/" . $configurator;
65 $scriptname = str_replace('configurator.php', 'index.php', $_SERVER["SCRIPT_NAME"]);
66 if (strstr($_SERVER["SCRIPT_NAME"],"/php")) { // cgi got this different
67 if (defined('DATA_PATH'))
68 $scriptname = DATA_PATH . "/index.php";
70 $scriptname = str_replace('configurator.php', 'index.php', $_SERVER["PHP_SELF"]);
74 $config_file = (substr(PHP_OS,0,3) == 'WIN') ? 'config\\config.ini' : 'config/config.ini';
75 $fs_config_file = dirname(__FILE__) . (substr(PHP_OS,0,3) == 'WIN' ? '\\' : '/') . $config_file;
76 if (isset($_POST['create'])) header('Location: '.$configurator.'?show=_part1&create=1#create');
78 // helpers from lib/WikiUser/HttpAuth.php
79 if (!function_exists('_http_user')) {
80 function _http_user() {
82 $_SERVER = $GLOBALS['HTTP_SERVER_VARS'];
83 if (!empty($_SERVER['PHP_AUTH_USER']))
84 return array($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']);
85 if (!empty($_SERVER['REMOTE_USER']))
86 return array($_SERVER['REMOTE_USER'], $_SERVER['PHP_AUTH_PW']);
87 if (!empty($GLOBALS['HTTP_ENV_VARS']['REMOTE_USER']))
88 return array($GLOBALS['HTTP_ENV_VARS']['REMOTE_USER'],
89 $GLOBALS['HTTP_ENV_VARS']['PHP_AUTH_PW']);
90 if (!empty($GLOBALS['REMOTE_USER']))
91 return array($GLOBALS['REMOTE_USER'], $GLOBALS['PHP_AUTH_PW']);
94 if (!empty($_SERVER['HTTP_AUTHORIZATION'])) {
95 list($userid, $passwd) = explode(':', base64_decode(substr($_SERVER['HTTP_AUTHORIZATION'], 6)));
96 return array($userid, $passwd);
100 function _http_logout() {
101 if (!isset($_SERVER))
102 $_SERVER =& $GLOBALS['HTTP_SERVER_VARS'];
103 // maybe we should random the realm to really force a logout. but the next login will fail.
104 // better_srand(); $realm = microtime().rand();
105 header('WWW-Authenticate: Basic realm="'.WIKI_NAME.'"');
106 if (strstr(php_sapi_name(), 'apache'))
107 header('HTTP/1.0 401 Unauthorized');
109 header("Status: 401 Access Denied"); //IIS and CGI need that
110 unset($GLOBALS['REMOTE_USER']);
111 unset($_SERVER['PHP_AUTH_USER']);
112 unset($_SERVER['PHP_AUTH_PW']);
114 trigger_error("Permission denied. Require ADMIN_USER.", E_USER_ERROR);
119 // If config.ini exists, we require ADMIN_USER access by faking HttpAuth.
120 // So nobody can see or reset the password(s).
121 if (file_exists($fs_config_file)) {
122 // Require admin user
123 if (!defined('ADMIN_USER') or !defined('ADMIN_PASSWD')) {
124 if (!function_exists("IniConfig")) {
125 include_once("lib/prepend.php");
126 include_once("lib/IniConfig.php");
128 IniConfig($fs_config_file);
130 if (!defined('ADMIN_USER') or ADMIN_USER == '') {
131 trigger_error("Configuration problem:\nADMIN_USER not defined in \"$fs_config_file\".\n"
132 . "Cannot continue: You have to fix that manually.", E_USER_ERROR);
136 list($admin_user, $admin_pw) = _http_user();
137 //$required_user = ADMIN_USER;
138 if (empty($admin_user) or $admin_user != ADMIN_USER)
143 if (ENCRYPTED_PASSWD and function_exists('crypt')) {
144 if (crypt($admin_pw, ADMIN_PASSWD) != ADMIN_PASSWD)
146 } elseif ($admin_pw != ADMIN_PASSWD) {
150 if (!function_exists("IniConfig")) {
151 include_once("lib/prepend.php");
152 include_once("lib/IniConfig.php");
154 $def_file = (substr(PHP_OS,0,3) == 'WIN') ? 'config\\config-default.ini' : 'config/config-default.ini';
155 $fs_def_file = dirname(__FILE__) . (substr(PHP_OS,0,3) == 'WIN' ? '\\' : '/') . $def_file;
156 IniConfig($fs_def_file);
159 echo '<','?xml version="1.0" encoding="iso-8859-1"?',">\n";
161 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
162 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
163 <html xmlns="http://www.w3.org/1999/xhtml">
165 <!-- $Id: configurator.php,v 1.45 2006-12-23 16:12:16 rurban Exp $ -->
166 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
167 <title>Configuration tool for PhpWiki <?php echo $config_file ?></title>
168 <style type="text/css" media="screen">
170 /* TABLE { border: thin solid black } */
171 body { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 80%; }
172 pre { font-size: 120%; }
173 td { border: thin solid black }
175 div.hint { border: thin solid red, background-color: #eeeeee; }
176 tr.hidden { border: none; display: none; }
177 td.part { background-color: #eeeeee; color: inherit; }
178 td.instructions { background-color: #ffffee; width: <?php echo $tdwidth ?>px; color: inherit; }
179 td.unchangeable-variable-top { border-bottom: none; background-color: #ffffee; color:inherit; }
180 td.unchangeable-variable-left { border-top: none; background-color: #ffffee; color:inherit; }
183 <script language="JavaScript" type="text/javascript">
185 function update(accepted, error, value, output) {
186 var msg = document.getElementById(output);
188 /* MSIE 5.0 fails here */
189 if (msg && msg.innerHTML) { msg.innerHTML = "<font color=\"green\">Input accepted.</font>"; }
191 while ((index = error.indexOf("%s")) > -1) {
192 error = error.substring(0, index) + value + error.substring(index+2);
194 if (msg) { msg.innerHTML = "<font color=\"red\">" + error + "</font>"; }
196 if (submit = document.getElementById('submit')) submit.disabled = accepted ? false : true;
199 function validate(error, value, output, field) {
200 update(field.value == value, error, field.value, output);
203 function validate_ereg(error, ereg, output, field) {
204 regex = new RegExp(ereg);
205 update(regex.test(field.value), error, field.value, output);
208 function validate_range(error, low, high, empty_ok, output, field) {
209 update((empty_ok == 1 && field.value == "") ||
210 (field.value >= low && field.value <= high),
211 error, field.value, output);
214 function toggle_group(id) {
215 var text = document.getElementById(id + "_text");
217 if (text.innerHTML == "Hide options.") {
219 text.innerHTML = "Show options.";
221 text.innerHTML = "Hide options.";
224 var rows = document.getElementsByTagName('tr');
226 for (i = 0; i < rows.length; i++) {
228 if (tr.className == 'header' && tr.id == id) {
233 for (; i < rows.length; i++) {
235 if (tr.className == 'header')
237 tr.className = do_hide ? 'hidden': 'nonhidden';
242 // Hide all groups. We do this via JavaScript to avoid
243 // hiding the groups if JavaScript is not supported...
244 var rows = document.getElementsByTagName('tr');
245 var show = '<?php echo $_GET["show"] ?>';
246 for (var i = 0; i < rows.length; i++) {
248 if (tr.className == 'header')
249 if (!show || tr.id != show)
253 // Select text in textarea upon focus
254 var area = document.getElementById('config-output');
256 listener = { handleEvent: function (e) { area.select(); } };
257 area.addEventListener('focus', listener, false);
264 <body onload="do_init();">
266 <h1>Configuration for PhpWiki <?php echo $config_file ?></h1>
269 Using this configurator.php is experimental!<br>
270 On any configuration problems, please edit the resulting config.ini manually.
274 //define('DEBUG', 1);
276 * The Configurator is a php script to aid in the configuration of PhpWiki.
277 * Parts of this file were based on PHPWeather's configurator.php file.
278 * http://sourceforge.net/projects/phpweather/
280 * TO CHANGE THE CONFIGURATION OF YOUR PHPWIKI, DO *NOT* MODIFY THIS FILE!
281 * more instructions go here
285 * * eval config.ini to get the actual settings.
288 //////////////////////////////
289 // begin configuration options
292 * Notes for the description parameter of $property:
294 * - Descriptive text will be changed into comments (preceeded by ; )
295 * for the final output to config.ini.
297 * - Only a limited set of html is allowed: pre, dl dt dd; it will be
298 * stripped from the final output.
300 * - Line breaks and spacing will be preserved for the final output.
302 * - Double line breaks are automatically converted to paragraphs
303 * for the html version of the descriptive text.
305 * - Double-quotes and dollar signs in the descriptive text must be
306 * escaped: \" and \$. Instead of escaping double-quotes you can use
307 * single (') quotes for the enclosing quotes.
309 * - Special characters like < and > must use html entities,
310 * they will be converted back to characters for the final output.
313 $SEPARATOR = ";=========================================================================";
316 ; This is the main configuration file for PhpWiki in INI-style format.
317 ; Note that certain characters are used as comment char and therefore
318 ; these entries must be in double-quotes. Such as \":\", \";\", \",\" and \"|\"
319 ; Take special care for DBAUTH_ sql statements. (Part 3a)
321 ; This file is divided into several parts: Each one has different configuration
322 ; settings you can change; in all cases the default should work on your system,
323 ; however, we recommend you tailor things to your particular setting.
324 ; Here undefined definitions get defined by config-default.ini settings.
327 // Detect not here listed configs:
328 // for x in `perl -ne 'print $1,"\n" if /^;(\w+) =/' config/config-dist.ini`; do \
329 // grep \'$x\' configurator.php >/dev/null || echo $x ; done
331 $properties["Part Zero"] =
332 new part('_part0', $SEPARATOR."\n", "
333 Part Zero: (optional)
334 Latest Development and Tricky Options");
336 if (defined('INCLUDE_PATH'))
337 $include_path = INCLUDE_PATH;
339 if (substr(PHP_OS,0,3) == 'WIN') {
340 $include_path = dirname(__FILE__) . ';' . ini_get('include_path');
341 if (strchr(ini_get('include_path'),'/'))
342 $include_path = strtr($include_path,'\\','/');
344 $include_path = dirname(__FILE__) . ':' . ini_get('include_path');
348 $properties["PHP include_path"] =
349 new _define('INCLUDE_PATH', $include_path);
351 // TODO: convert this a checkbox row as in tests/unit/test.pgp
352 $properties["DEBUG"] =
353 new numeric_define_optional('DEBUG', DEBUG);
355 $properties["ENABLE_EDIT_TOOLBAR"] =
356 new boolean_define_commented_optional('ENABLE_EDIT_TOOLBAR');
358 $properties["JS_SEARCHREPLACE"] =
359 new boolean_define_commented_optional('JS_SEARCHREPLACE');
361 // TESTME: use config-default: = false
362 $properties["ENABLE_DOUBLECLICKEDIT"] =
363 new boolean_define_commented_optional('ENABLE_DOUBLECLICKEDIT');
365 $properties["ENABLE_WYSIWYG"] =
366 new boolean_define_commented_optional('ENABLE_WYSIWYG');
368 $properties["WYSIWYG_BACKEND"] =
369 new _define_selection(
371 array('Wikiwyg' => 'Wikiwyg',
372 'tinymce' => 'tinymce',
373 'FCKeditor' => 'FCKeditor',
375 'htmlarea3' => 'htmlarea3',
376 'htmlarea2' => 'htmlarea2',
379 $properties["WYSIWYG_DEFAULT_PAGETYPE_HTML"] =
380 new boolean_define_commented_optional('WYSIWYG_DEFAULT_PAGETYPE_HTML');
382 $properties["ENABLE_XHTML_XML"] =
383 new boolean_define_commented_optional('ENABLE_XHTML_XML');
385 $properties["ENABLE_SPAMASSASSIN"] =
386 new boolean_define_commented_optional('ENABLE_SPAMASSASSIN');
388 $properties["ENABLE_SPAMBLOCKLIST"] =
389 new boolean_define_optional('ENABLE_SPAMBLOCKLIST');
391 $properties["NUM_SPAM_LINKS"] =
392 new numeric_define_optional('NUM_SPAM_LINKS');
394 $properties["GOOGLE_LINKS_NOFOLLOW"] =
395 new boolean_define_commented_optional('GOOGLE_LINKS_NOFOLLOW');
397 $properties["ENABLE_LIVESEARCH"] =
398 new boolean_define_commented_optional('ENABLE_LIVESEARCH');
400 $properties["ENABLE_ACDROPDOWN"] =
401 new boolean_define_commented_optional('ENABLE_ACDROPDOWN');
403 $properties["ENABLE_DISCUSSION_LINK"] =
404 new boolean_define_commented_optional('ENABLE_DISCUSSION_LINK');
406 $properties["ENABLE_CAPTCHA"] =
407 new boolean_define_commented_optional('ENABLE_CAPTCHA');
409 $properties["USE_CAPTCHA_RANDOM_WORD"] =
410 new boolean_define_commented_optional('USE_CAPTCHA_RANDOM_WORD');
412 $properties["USE_SAFE_DBSESSION"] =
413 new boolean_define_commented_optional('USE_SAFE_DBSESSION');
415 $properties["BLOG_DEFAULT_EMPTY_PREFIX"] =
416 new boolean_define_commented_optional('BLOG_DEFAULT_EMPTY_PREFIX');
419 $properties["Part One"] =
420 new part('_part1', $SEPARATOR."\n", "
421 Part One: Authentication and security settings. See Part Three for more.");
423 $properties["Wiki Name"] =
424 new _define_optional('WIKI_NAME', WIKI_NAME);
426 $properties["Admin Username"] =
427 new _define_notempty('ADMIN_USER', ADMIN_USER, "
428 You must set this! Username and password of the administrator.",
429 "onchange=\"validate_ereg('Sorry, ADMIN_USER cannot be empty.', '^.+$', 'ADMIN_USER', this);\"");
431 $properties["Admin Password"] =
432 new _define_password('ADMIN_PASSWD', ADMIN_PASSWD, "
434 For heaven's sake pick a good password.
436 If your version of PHP supports encrypted passwords, your password will be
437 automatically encrypted within the generated config file.
438 Use the \"Create Random Password\" button to create a good (random) password.
440 ADMIN_PASSWD is ignored on HttpAuth",
441 "onchange=\"validate_ereg('Sorry, ADMIN_PASSWD must be at least 4 chars long.', '^....+$', 'ADMIN_PASSWD', this);\"");
443 $properties["Encrypted Passwords"] =
446 array('true' => "true. use crypt for all passwords",
447 'false' => "false. use plaintest passwords (not recommended)"));
449 $properties["Reverse DNS"] =
450 new boolean_define_optional
451 ('ENABLE_REVERSE_DNS',
452 array('true' => "true. perform additional reverse dns lookups",
453 'false' => "false. just record the address as given by the httpd server"));
455 $properties["ZIP Dump Authentication"] =
456 new boolean_define_optional('ZIPDUMP_AUTH',
457 array('false' => "false. Everyone may download zip dumps",
458 'true' => "true. Only admin may download zip dumps"));
460 $properties["Enable RawHtml Plugin"] =
461 new boolean_define_commented_optional('ENABLE_RAW_HTML');
463 $properties["Allow RawHtml Plugin only on locked pages"] =
464 new boolean_define_commented_optional('ENABLE_RAW_HTML_LOCKEDONLY');
466 $properties["Allow RawHtml Plugin if safe HTML code"] =
467 new boolean_define_commented_optional('ENABLE_RAW_HTML_SAFE','', "
468 If this is set, all unsafe html code is stripped automatically (experimental!)
469 See <a href=\"http://chxo.com/scripts/safe_html-test.php\" target=\"_new\">chxo.com/scripts/safe_html-test.php</a>
472 $properties["Maximum Upload Size"] =
473 new numeric_define_optional('MAX_UPLOAD_SIZE', MAX_UPLOAD_SIZE);
475 $properties["Minor Edit Timeout"] =
476 new numeric_define_optional('MINOR_EDIT_TIMEOUT', MINOR_EDIT_TIMEOUT);
478 $properties["Disabled Actions"] =
479 new array_define('DISABLED_ACTIONS', DISABLED_ACTIONS /*array()*/);
481 $properties["Moderate all Pagechanges"] =
482 new boolean_define_commented_optional('ENABLE_MODERATEDPAGE_ALL');
484 $properties["Access Log File"] =
485 new _define_commented_optional('ACCESS_LOG', ACCESS_LOG);
487 $properties["Access Log SQL"] =
488 new _define_selection(
490 array('0' => 'disabled',
492 '2' => 'read + write'));
494 $properties["Compress Output"] =
495 new boolean_define_commented_optional
497 array('' => 'undefined - GZIP compress when appropriate.',
498 'false' => 'Never compress output.',
499 'true' => 'Always try to compress output.'));
501 $properties["HTTP Cache Control"] =
502 new _define_selection_optional
504 array('LOOSE' => 'LOOSE',
505 'STRICT' => 'STRICT',
506 'NO_CACHE' => 'NO_CACHE',
507 'ALLOW_STALE' => 'ALLOW_STALE'),
511 This controls how PhpWiki sets the HTTP cache control
512 headers (Expires: and Cache-Control:)
518 <dd>This is roughly the old (pre 1.3.4) behaviour. PhpWiki will
519 instruct proxies and browsers never to cache PhpWiki output.</dd>
522 <dd>Cached pages will be invalidated whenever the database global
523 timestamp changes. This should behave just like NONE (modulo
524 bugs in PhpWiki and your proxies and browsers), except that
525 things will be slightly more efficient.</dd>
528 <dd>Cached pages will be invalidated whenever they are edited,
529 or, if the pages include plugins, when the plugin output could
530 concievably have changed.
532 <p>Behavior should be much like STRICT, except that sometimes
533 wikilinks will show up as undefined (with the question mark)
534 when in fact they refer to (recently) created pages.
535 (Hitting your browsers reload or perhaps shift-reload button
536 should fix the problem.)</p></dd>
539 <dd>Proxies and browsers will be allowed to used stale pages.
540 (The timeout for stale pages is controlled by CACHE_CONTROL_MAX_AGE.)
542 <p>This setting will result in quirky behavior. When you edit a
543 page your changes may not show up until you shift-reload the
546 <p>This setting is generally not advisable, however it may be useful
547 in certain cases (e.g. if your wiki gets lots of page views,
548 and few edits by knowledgable people who won't freak over the quirks.)</p>
551 The default is currently LOOSE.");
553 $properties["HTTP Cache Control Max Age"] =
554 new numeric_define_optional('CACHE_CONTROL_MAX_AGE', CACHE_CONTROL_MAX_AGE);
556 $properties["Markup Caching"] =
557 new boolean_define_commented_optional
558 ('WIKIDB_NOCACHE_MARKUP',
559 array('false' => 'Enable markup cache',
560 'true' => 'Disable markup cache'));
562 $properties["COOKIE_EXPIRATION_DAYS"] =
563 new numeric_define_optional('COOKIE_EXPIRATION_DAYS', COOKIE_EXPIRATION_DAYS);
565 $properties["COOKIE_DOMAIN"] =
566 new _define_commented_optional('COOKIE_DOMAIN', COOKIE_DOMAIN);
568 $properties["Path for PHP Session Support"] =
569 new _define_optional('SESSION_SAVE_PATH', defined('SESSION_SAVE_PATH') ? SESSION_SAVE_PATH : ini_get('session.save_path'));
571 $properties["Force PHP Database Sessions"] =
572 new boolean_define_commented_optional
574 array('false' => 'Disable database sessions, use files',
575 'true' => 'Enable database sessions'));
577 ///////// database selection
579 $properties["Part Two"] =
580 new part('_part2', $SEPARATOR."\n", "
583 Database Configuration
586 $properties["Database Type"] =
587 new _define_selection("DATABASE_TYPE",
588 array('dba' => "dba",
590 'ADODB' => "SQL ADODB",
591 'PDO' => "PDO (php5 only)",
592 'file' => "flatfile",
593 'cvs' => "CVS File handler")/*, "
594 Select the database backend type:
595 Choose dba (default) to use one of the standard UNIX dba libraries. This is the fastest.
596 Choose ADODB or SQL to use an SQL database with ADODB or PEAR.
597 Choose PDO on php5 to use an SQL database. (experimental, no paging yet)
598 flatfile is simple and slow.
599 CVS is highly experimental and slow.
600 Recommended is dba or SQL: PEAR or ADODB."*/);
602 $properties["SQL DSN Setup"] =
603 new unchangeable_variable('_sqldsnstuff', "", "
604 For SQL based backends, specify the database as a DSN
605 The most general form of a DSN looks like:
607 phptype(dbsyntax)://username:password@protocol+hostspec/database?option=value
609 For a MySQL database, the following should work:
611 mysql://user:password@host/databasename
613 To connect over a unix socket, use something like
615 mysql://user:password@unix(/path/to/socket)/databasename
618 DATABASE_DSN = mysql://guest@:/var/lib/mysql/mysql.sock/phpwiki
619 DATABASE_DSN = mysql://guest@localhost/phpwiki
620 DATABASE_DSN = pgsql://localhost/user_phpwiki
623 // Choose ADODB or SQL to use an SQL database with ADODB or PEAR.
624 // Choose dba to use one of the standard UNIX dbm libraries.
626 $properties["SQL Type"] =
627 new _variable_selection('_dsn_sqltype',
628 array('mysql' => "MySQL",
629 'pgsql' => "PostgreSQL",
630 'mssql' => "Microsoft SQL Server",
631 'oci8' => "Oracle 8",
632 'mysqli' => "mysqli (only ADODB)",
633 'mysqlt' => "mysqlt (only ADODB)",
634 'ODBC' => "ODBC (only ADODB or PDO)",
635 'firebird' => "Firebird (only PDO)",
636 'oracle' => "Oracle (only PDO)",
638 SQL DB types. The DSN hosttype.");
640 $properties["SQL User"] =
641 new _variable('_dsn_sqluser', "wikiuser", "
644 $properties["SQL Password"] =
645 new _variable('_dsn_sqlpass', "", "
648 $properties["SQL Database Host"] =
649 new _variable('_dsn_sqlhostorsock', "localhost", "
650 SQL Database Hostname:
652 To connect over a local named socket, use something like
654 unix(/var/lib/mysql/mysql.sock)
657 mysql on Windows via named pipes might need 127.0.0.1");
659 $properties["SQL Database Name"] =
660 new _variable('_dsn_sqldbname', "phpwiki", "
661 SQL Database Name:");
663 $dsn_sqltype = $properties["SQL Type"]->value();
664 $dsn_sqluser = $properties["SQL User"]->value();
665 $dsn_sqlpass = $properties["SQL Password"]->value();
666 $dsn_sqlhostorsock = $properties["SQL Database Host"]->value();
667 $dsn_sqldbname = $properties["SQL Database Name"]->value();
668 $dsn_sqlstring = $dsn_sqltype."://{$dsn_sqluser}:{$dsn_sqlpass}@{$dsn_sqlhostorsock}/{$dsn_sqldbname}";
670 $properties["SQL dsn"] =
671 new unchangeable_define("DATABASE_DSN",
673 Calculated from the settings above:");
675 $properties["Filename / Table name Prefix"] =
676 new _define_commented('DATABASE_PREFIX', DATABASE_PREFIX, "
677 Used by all DB types:
679 Prefix for filenames or table names, e.g. \"phpwiki_\"
681 Currently <b>you MUST EDIT THE SQL file too!</b> (in the schemas/
682 directory because we aren't doing on the fly sql generation
683 during the installation.
685 Note: This prefix is NOT prepended to the default DBAUTH_
686 tables user, pref and member!
689 $properties["DATABASE_PERSISTENT"] =
690 new boolean_define_commented_optional
691 ('DATABASE_PERSISTENT',
692 array('false' => "Disabled",
693 'true' => "Enabled"));
695 $properties["DB Session table"] =
696 new _define_optional("DATABASE_SESSION_TABLE", DATABASE_SESSION_TABLE, "
697 Tablename to store session information. Only supported by SQL backends.
699 A word of warning - any prefix defined above will be prepended to whatever is given here.
703 $temp = !empty($_ENV['TEMP']) ? $_ENV['TEMP'] : "/tmp";
704 $properties["dba directory"] =
705 new _define("DATABASE_DIRECTORY", $temp);
707 // TODO: list the available methods
708 $properties["dba handler"] =
709 new _define_selection('DATABASE_DBA_HANDLER',
710 array('gdbm' => "gdbm - GNU database manager (not recommended anymore)",
711 'dbm' => "DBM - Redhat default. On sf.net there's dbm and not gdbm anymore",
712 'db2' => "DB2 - BerkeleyDB (Sleepycat) DB2",
713 'db3' => "DB3 - BerkeleyDB (Sleepycat) DB3. Default on Windows but not on every Linux",
714 'db4' => "DB4 - BerkeleyDB (Sleepycat) DB4."), "
715 Use 'gdbm', 'dbm', 'db2', 'db3' or 'db4' depending on your DBA handler methods supported: <br > "
716 . (function_exists("dba_handlers") ? join(", ",dba_handlers()) : "")
717 . "\n\nBetter not use other hacks such as inifile, flatfile or cdb");
719 $properties["dba timeout"] =
720 new numeric_define("DATABASE_TIMEOUT", DATABASE_TIMEOUT, "
721 Recommended values are 10-20 seconds. The more load the server has, the higher the timeout.");
723 $properties["DATABASE_OPTIMISE_FREQUENCY"] =
724 new numeric_define_optional('DATABASE_OPTIMISE_FREQUENCY', DATABASE_OPTIMISE_FREQUENCY);
726 $properties["DBADMIN_USER"] =
727 new _define_optional('DBADMIN_USER', DBADMIN_USER);
729 $properties["DBADMIN_PASSWD"] =
730 new _define_password_optional('DBADMIN_PASSWD', DBADMIN_PASSWD);
732 $properties["USECACHE"] =
733 new boolean_define_commented_optional('USECACHE');
737 $properties["Page Revisions"] =
738 new unchangeable_variable('_parttworevisions', "", "
740 Section 2a: Archive Cleanup
741 The next section controls how many old revisions of each page are kept in the database.
743 There are two basic classes of revisions: major and minor. Which
744 class a revision belongs in is determined by whether the author
745 checked the \"this is a minor revision\" checkbox when they saved the
748 There is, additionally, a third class of revisions: author
749 revisions. The most recent non-mergable revision from each distinct
750 author is and author revision.
752 The expiry parameters for each of those three classes of revisions
753 can be adjusted seperately. For each class there are five
754 parameters (usually, only two or three of the five are actually
755 set) which control how long those revisions are kept in the
758 <dt>max_keep:</dt> <dd>If set, this specifies an absolute maximum for the
759 number of archived revisions of that class. This is
760 meant to be used as a safety cap when a non-zero
761 min_age is specified. It should be set relatively high,
762 and it's purpose is to prevent malicious or accidental
763 database overflow due to someone causing an
764 unreasonable number of edits in a short period of time.</dd>
766 <dt>min_age:</dt> <dd>Revisions younger than this (based upon the supplanted
767 date) will be kept unless max_keep is exceeded. The age
768 should be specified in days. It should be a
769 non-negative, real number,</dd>
771 <dt>min_keep:</dt> <dd>At least this many revisions will be kept.</dd>
773 <dt>keep:</dt> <dd>No more than this many revisions will be kept.</dd>
775 <dt>max_age:</dt> <dd>No revision older than this age will be kept.</dd>
777 Supplanted date: Revisions are timestamped at the instant that they
778 cease being the current revision. Revision age is computed using
779 this timestamp, not the edit time of the page.
781 Merging: When a minor revision is deleted, if the preceding
782 revision is by the same author, the minor revision is merged with
783 the preceding revision before it is deleted. Essentially: this
784 replaces the content (and supplanted timestamp) of the previous
785 revision with the content after the merged minor edit, the rest of
786 the page metadata for the preceding version (summary, mtime, ...)
790 // For now the expiration parameters are statically inserted as
791 // an unchangeable property. You'll have to edit the resulting
792 // config file if you really want to change these from the default.
794 $properties["Major Edits: keep minimum days"] =
795 new numeric_define('MAJOR_MIN_KEEP', MAJOR_MIN_KEEP, "
796 Default: Keep for unlimited time.
797 Set to 0 to enable archive cleanup");
798 $properties["Minor Edits: keep minumum days"] =
799 new numeric_define('MINOR_MIN_KEEP', MINOR_MIN_KEEP, "
800 Default: Keep for unlimited time.
801 Set to 0 to enable archive cleanup");
803 $properties["Major Edits: how many"] =
804 new numeric_define('MAJOR_KEEP', MAJOR_KEEP, "
805 Keep up to 8 major edits");
806 $properties["Major Edits: how many days"] =
807 new numeric_define('MAJOR_MAX_AGE', MAJOR_MAX_AGE, "
808 keep them no longer than a month");
810 $properties["Minor Edits: how many"] =
811 new numeric_define("MINOR_KEEP", MINOR_KEEP, "
812 Keep up to 4 minor edits");
813 $properties["Minor Edits: how many days"] =
814 new numeric_define("MINOR_MAX_AGE", "7", "
815 keep them no longer than a week");
817 $properties["per Author: how many"] =
818 new numeric_define("AUTHOR_KEEP", "8", "
819 Keep the latest contributions of the last 8 authors,");
820 $properties["per Author: how many days"] =
821 new numeric_define("AUTHOR_MAX_AGE", "365", "
823 $properties["per Author: keep minumum days"] =
824 new numeric_define("AUTHOR_MIN_AGE", "7", "
825 Additionally, (in the case of a particularly active page) try to
826 keep the latest contributions of all authors in the last week (even if there are more than eight of them,)");
827 $properties["per Author: max revisions"] =
828 new numeric_define("AUTHOR_MAX_KEEP", "20", "
829 but in no case keep more than twenty unique author revisions.");
831 /////////////////////////////////////////////////////////////////////
833 $properties["Part Three"] =
834 new part('_part3', $SEPARATOR."\n", "
836 Part Three: (optional)
837 Basic User Authentication Setup
840 $properties["Publicly viewable"] =
841 new boolean_define_optional('ALLOW_ANON_USER',
842 array('true' => "true. Permit anonymous view. (Default)",
843 'false' => "false. Force login even on view (strictly private)"), "
844 If ALLOW_ANON_USER is false, you have to login before viewing any page or doing any other action on a page.");
846 $properties["Allow anonymous edit"] =
847 new boolean_define_optional('ALLOW_ANON_EDIT',
848 array('true' => "true. Permit anonymous users to edit. (Default)",
849 'false' => "false. Force login on edit (moderately locked)"), "
850 If ALLOW_ANON_EDIT is false, you have to login before editing or changing any page. See below.");
852 $properties["Allow Bogo Login"] =
853 new boolean_define_optional('ALLOW_BOGO_LOGIN',
854 array('true' => "true. Users may Sign In with any WikiWord, without password. (Default)",
855 'false' => "false. Require stricter authentication."), "
856 If ALLOW_BOGO_LOGIN is false, you may not login with any wikiword username and empty password.
857 If true, users are allowed to create themselves with any WikiWord username. See below.");
859 $properties["Allow User Passwords"] =
860 new boolean_define_optional('ALLOW_USER_PASSWORDS',
861 array('true' => "True user authentication with password checking. (Default)",
862 'false' => "false. Ignore authentication settings below."), "
863 If ALLOW_USER_PASSWORDS is true, the authentication settings below define where and how to
864 check against given username/passwords. For completely security disable BOGO_LOGIN and ANON_EDIT above.");
866 $properties["User Authentication Methods"] =
867 new array_define('USER_AUTH_ORDER', array("PersonalPage", "Db"), "
868 Many different methods can be used to check user's passwords.
869 Try any of these in the given order:
872 <dd>WikiWord username, with no *actual* password checking,
873 although the user will still have to enter one.</dd>
874 <dt>PersonalPage</dt>
875 <dd>Store passwords in the users homepage metadata (simple)</dd>
877 <dd>Use DBAUTH_AUTH_* (see below) with PearDB or ADODB only.</dd>
879 <dd>Authenticate against LDAP_AUTH_HOST with LDAP_BASE_DN.</dd>
881 <dd>Authenticate against IMAP_AUTH_HOST (email account)</dd>
883 <dd>Authenticate against POP3_AUTH_HOST (email account)</dd>
885 <dd>Get username and level from a PHP session variable. (e.g. for gforge)</dd>
887 <dd>Store username:crypted-passwords in .htaccess like files.
888 Use Apache's htpasswd to manage this file.</dd>
890 <dd>Use the protection by the webserver (.htaccess/.htpasswd) (experimental)
891 Enforcing HTTP Auth not yet. Note that the ADMIN_USER should exist also.
892 Using HttpAuth disables all other methods and no userauth sessions are used.</dd>
895 Several of these methods can be used together, in the manner specified by
896 USER_AUTH_POLICY, below. To specify multiple authentication methods,
897 separate the name of each one with colons.
899 USER_AUTH_ORDER = 'PersonalPage : Db'
900 USER_AUTH_ORDER = 'BogoLogin : PersonalPage'
903 $properties["PASSWORD_LENGTH_MINIMUM"] =
904 new numeric_define('PASSWORD_LENGTH_MINIMUM', PASSWORD_LENGTH_MINIMUM);
906 $properties["USER_AUTH_POLICY"] =
907 new _define_selection('USER_AUTH_POLICY',
908 array('first-only' => "first-only - use only the first method in USER_AUTH_ORDER",
909 'old' => "old - ignore USER_AUTH_ORDER (legacy)",
910 'strict' => "strict - check all methods for userid + password (recommended)",
911 'stacked' => "stacked - check all methods for userid, and if found for password"), "
912 The following policies are available for user authentication:
915 <dd>use only the first method in USER_AUTH_ORDER</dd>
917 <dd>ignore USER_AUTH_ORDER and try to use all available
918 methods as in the previous PhpWiki releases (slow)</dd>
920 <dd>check if the user exists for all methods:
921 on the first existing user, try the password.
922 dont try the other methods on failure then</dd>
924 <dd>check the given user - password combination for all
925 methods and return true on the first success.</dd></dl>");
927 $properties["ENABLE_USER_NEW"] =
928 new boolean_define_commented_optional('ENABLE_USER_NEW');
930 $properties["ENABLE_PAGEPERM"] =
931 new boolean_define_commented_optional('ENABLE_PAGEPERM');
935 $properties["Part Three A"] =
936 new part('_part3a', $SEPARATOR."\n", "
938 Part Three A: (optional)
941 $properties["Group membership"] =
942 new _define_selection("GROUP_METHOD",
943 array('WIKIPAGE' => "WIKIPAGE - List at \"CategoryGroup\". (Slowest, but easiest to maintain)",
944 '"NONE"' => "NONE - Disable group membership (Fastest)",
945 'DB' => "DB - SQL Database, Optionally external. See USERS/GROUPS queries",
946 'FILE' => "Flatfile. See AUTH_GROUP_FILE below.",
947 'LDAP' => "LDAP - See \"LDAP authentication options\" above. (Experimental)"), "
948 Group membership. PhpWiki supports defining permissions for a group as
949 well as for individual users. This defines how group membership information
950 is obtained. Supported values are:
953 <dd>Disable group membership (Fastest). Note the required quoting.</dd>
955 <dd>Define groups as list at \"CategoryGroup\". (Slowest, but easiest to maintain)</dd>
957 <dd>Stored in an SQL database. Optionally external. See USERS/GROUPS queries</dd>
959 <dd>Flatfile. See AUTH_GROUP_FILE below.</dd>
961 <dd>LDAP groups. See \"LDAP authentication options\" above and
962 lib/WikiGroup.php. (experimental)</dd></dl>");
964 $properties["CATEGORY_GROUP_PAGE"] =
965 new _define_optional('CATEGORY_GROUP_PAGE', _("CategoryGroup"), "
966 If GROUP_METHOD = WIKIPAGE:
968 Page where all groups are listed.");
970 $properties["AUTH_GROUP_FILE"] =
971 new _define_optional('AUTH_GROUP_FILE', _("/etc/groups"), "
972 For GROUP_METHOD = FILE, the file given below is referenced to obtain
973 group membership information. It should be in the same format as the
974 standard unix /etc/groups(5) file.");
976 $properties["Part Three B"] =
977 new part('_part3b', $SEPARATOR."\n", "
979 Part Three B: (optional)
980 External database authentication and authorization.
982 If USER_AUTH_ORDER includes Db, or GROUP_METHOD = DB, the options listed
983 below define the SQL queries used to obtain the information out of the
984 database, and (optionally) store the information back to the DB.");
986 $properties["DBAUTH_AUTH_DSN"] =
987 new _define_optional('DBAUTH_AUTH_DSN', $dsn_sqlstring, "
988 A database DSN to connect to. Defaults to the DSN specified for the Wiki as a whole.");
990 $properties["User Exists Query"] =
991 new _define('DBAUTH_AUTH_USER_EXISTS', "SELECT userid FROM user WHERE userid='\$userid'", "
992 USER/PASSWORD queries:
994 For USER_AUTH_POLICY=strict and the Db method is required");
996 $properties["Check Query"] =
997 new _define_optional('DBAUTH_AUTH_CHECK', "SELECT IF(passwd='\$password',1,0) AS ok FROM user WHERE userid='\$userid'", "
999 Check to see if the supplied username/password pair is OK
1001 Plaintext passwords: (DBAUTH_AUTH_CRYPT_METHOD = plain)<br>
1002 ; DBAUTH_AUTH_CHECK = \"SELECT IF(passwd='\$password',1,0) AS ok FROM user WHERE userid='\$userid'\"
1004 database-hashed passwords (more secure):<br>
1005 ; DBAUTH_AUTH_CHECK = \"SELECT IF(passwd=PASSWORD('\$password'),1,0) AS ok FROM user WHERE userid='\$userid'\"");
1007 $properties["Crypt Method"] =
1008 new _define_selection_optional
1009 ('DBAUTH_AUTH_CRYPT_METHOD',
1010 array('plain' => 'plain',
1011 'crypt' => 'crypt'), "
1012 If you want to use Unix crypt()ed passwords, you can use DBAUTH_AUTH_CHECK
1013 to get the password out of the database with a simple SELECT query, and
1014 specify DBAUTH_AUTH_USER_EXISTS and DBAUTH_AUTH_CRYPT_METHOD:
1016 ; DBAUTH_AUTH_CHECK = \"SELECT passwd FROM user where userid='\$userid'\" <br>
1017 ; DBAUTH_AUTH_CRYPT_METHOD = crypt");
1019 $properties["Update the user's authentication credential"] =
1020 new _define('DBAUTH_AUTH_UPDATE', "UPDATE user SET passwd='\$password' WHERE userid='\$userid'", "
1021 If this is not defined but DBAUTH_AUTH_CHECK is, then the user will be unable to update their
1024 Plaintext passwords:<br>
1025 DBAUTH_AUTH_UPDATE = \"UPDATE user SET passwd='\$password' WHERE userid='\$userid'\"<br>
1026 Database-hashed passwords:<br>
1027 DBAUTH_AUTH_UPDATE = \"UPDATE user SET passwd=PASSWORD('\$password') WHERE userid='\$userid'\"");
1029 $properties["Allow the user to create their own account"] =
1030 new _define_optional('DBAUTH_AUTH_CREATE', "INSERT INTO user SET passwd=PASSWORD('\$password'),userid='\$userid'", "
1031 If this is empty, Db users cannot subscribe by their own.");
1033 $properties["USER/PREFERENCE queries"] =
1034 new _define_optional('DBAUTH_PREF_SELECT', "SELECT prefs FROM user WHERE userid='\$userid'", "
1035 If you choose to store your preferences in an external database, enable
1036 the following queries. Note that if you choose to store user preferences
1037 in the 'user' table, only registered users get their prefs from the database,
1038 self-created users do not. Better to use the special 'pref' table.
1040 The prefs field stores the serialized form of the user's preferences array,
1041 to ease the complication of storage.
1043 DBAUTH_PREF_SELECT = \"SELECT prefs FROM user WHERE userid='\$userid'\"
1044 DBAUTH_PREF_SELECT = \"SELECT prefs FROM pref WHERE userid='\$userid'\"
1047 $properties["Update the user's preferences"] =
1048 new _define_optional('DBAUTH_PREF_UPDATE', "UPDATE user SET prefs='\$pref_blob' WHERE userid='\$userid'", "
1049 Note that REPLACE works only with mysql and destroy all other columns!
1051 Mysql: DBAUTH_PREF_UPDATE = \"REPLACE INTO pref SET prefs='\$pref_blob',userid='\$userid'\"");
1053 $properties["Create new user's preferences"] =
1054 new _define_optional('DBAUTH_PREF_INSERT', "INSERT INTO pref (userid,prefs) VALUES ('\$userid','\$pref_blob')", "
1055 Define this if new user can be create by themselves.
1058 $properties["USERS/GROUPS queries"] =
1059 new _define_optional('DBAUTH_IS_MEMBER', "SELECT user FROM user WHERE user='\$userid' AND group='\$groupname'", "
1060 You can define 1:n or n:m user<=>group relations, as you wish.
1062 Sample configurations:
1064 only one group per user (1:n):<br>
1065 DBAUTH_IS_MEMBER = \"SELECT user FROM user WHERE user='\$userid' AND group='\$groupname'\"<br>
1066 DBAUTH_GROUP_MEMBERS = \"SELECT user FROM user WHERE group='\$groupname'\"<br>
1067 DBAUTH_USER_GROUPS = \"SELECT group FROM user WHERE user='\$userid'\"<br>
1068 multiple groups per user (n:m):<br>
1069 DBAUTH_IS_MEMBER = \"SELECT userid FROM member WHERE userid='\$userid' AND groupname='\$groupname'\"<br>
1070 DBAUTH_GROUP_MEMBERS = \"SELECT DISTINCT userid FROM member WHERE groupname='\$groupname'\"<br>
1071 DBAUTH_USER_GROUPS = \"SELECT groupname FROM member WHERE userid='\$userid'\"<br>");
1072 $properties["DBAUTH_GROUP_MEMBERS"] =
1073 new _define_optional('DBAUTH_GROUP_MEMBERS', "SELECT user FROM user WHERE group='\$groupname'", "");
1074 $properties["DBAUTH_USER_GROUPS"] =
1075 new _define_optional('DBAUTH_USER_GROUPS', "SELECT group FROM user WHERE user='\$userid'", "");
1077 if (function_exists('ldap_connect')) {
1079 $properties["LDAP AUTH Host"] =
1080 new _define_optional('LDAP_AUTH_HOST', "ldap://localhost:389", "
1081 If USER_AUTH_ORDER contains Ldap:
1083 The LDAP server to connect to. Can either be a hostname, or a complete
1084 URL to the server (useful if you want to use ldaps or specify a different
1087 $properties["LDAP BASE DN"] =
1088 new _define_optional('LDAP_BASE_DN', "ou=mycompany.com,o=My Company", "
1089 The organizational or domain BASE DN: e.g. \"dc=mydomain,dc=com\".
1091 Note: ou=Users and ou=Groups are used for GroupLdap Membership
1092 Better use LDAP_OU_USERS and LDAP_OU_GROUP with GROUP_METHOD=LDAP.");
1094 $properties["LDAP SET OPTION"] =
1095 new _define_optional('LDAP_SET_OPTION', "LDAP_OPT_PROTOCOL_VERSION=3:LDAP_OPT_REFERRALS=0", "
1096 Some LDAP servers need some more options, such as the Windows Active
1097 Directory Server. Specify the options (as allowed by the PHP LDAP module)
1098 and their values as NAME=value pairs separated by colons.");
1100 $properties["LDAP AUTH USER"] =
1101 new _define_optional('LDAP_AUTH_USER', "CN=ldapuser,ou=Users,o=Development,dc=mycompany.com", "
1102 DN to initially bind to the LDAP server as. This is needed if the server doesn't
1103 allow anonymous queries. (Windows Active Directory Server)");
1105 $properties["LDAP AUTH PASSWORD"] =
1106 new _define_optional('LDAP_AUTH_PASSWORD', "secret", "
1107 Password to use to initially bind to the LDAP server, as the DN
1108 specified in the LDAP_AUTH_USER option (above).");
1110 $properties["LDAP SEARCH FIELD"] =
1111 new _define_optional('LDAP_SEARCH_FIELD', "uid", "
1112 If you want to match usernames against an attribute other than uid,
1113 specify it here. Default: uid
1115 e.g.: LDAP_SEARCH_FIELD = sAMAccountName");
1117 $properties["LDAP OU USERS"] =
1118 new _define_optional('LDAP_OU_USERS', "ou=Users", "
1119 If you have an organizational unit for all users, define it here.
1120 This narrows the search, and is needed for LDAP group membership (if GROUP_METHOD=LDAP)
1121 Default: ou=Users");
1123 $properties["LDAP OU GROUP"] =
1124 new _define_optional('LDAP_OU_GROUP', "ou=Groups", "
1125 If you have an organizational unit for all groups, define it here.
1126 This narrows the search, and is needed for LDAP group membership (if GROUP_METHOD=LDAP)
1127 The entries in this ou must have a gidNumber and cn attribute.
1128 Default: ou=Groups");
1130 } else { // function_exists('ldap_connect')
1132 $properties["LDAP Authentication"] =
1133 new unchangeable_variable('LDAP Authentication', "
1134 ; If USER_AUTH_ORDER contains Ldap:
1136 ; The LDAP server to connect to. Can either be a hostname, or a complete
1137 ; URL to the server (useful if you want to use ldaps or specify a different
1139 ;LDAP_AUTH_HOST = \"ldap://localhost:389\"
1141 ; The organizational or domain BASE DN: e.g. \"dc=mydomain,dc=com\".
1143 ; Note: ou=Users and ou=Groups are used for GroupLdap Membership
1144 ; Better use LDAP_OU_USERS and LDAP_OU_GROUP with GROUP_METHOD=LDAP.
1145 ;LDAP_BASE_DN = \"ou=Users,o=Development,dc=mycompany.com\"
1147 ; Some LDAP servers need some more options, such as the Windows Active
1148 ; Directory Server. Specify the options (as allowed by the PHP LDAP module)
1149 ; and their values as NAME=value pairs separated by colons.
1150 ; LDAP_SET_OPTION = \"LDAP_OPT_PROTOCOL_VERSION=3:LDAP_OPT_REFERRALS=0\"
1152 ; DN to initially bind to the LDAP server as. This is needed if the server doesn't
1153 ; allow anonymous queries. (Windows Active Directory Server)
1154 ; LDAP_AUTH_USER = \"CN=ldapuser,ou=Users,o=Development,dc=mycompany.com\"
1156 ; Password to use to initially bind to the LDAP server, as the DN
1157 ; specified in the LDAP_AUTH_USER option (above).
1158 ; LDAP_AUTH_PASSWORD = secret
1160 ; If you want to match usernames against an attribute other than uid,
1161 ; specify it here. Default: uid
1162 ; LDAP_SEARCH_FIELD = sAMAccountName
1164 ; If you have an organizational unit for all users, define it here.
1165 ; This narrows the search, and is needed for LDAP group membership (if GROUP_METHOD=LDAP)
1167 ; LDAP_OU_USERS = ou=Users
1169 ; If you have an organizational unit for all groups, define it here.
1170 ; This narrows the search, and is needed for LDAP group membership (if GROUP_METHOD=LDAP)
1171 ; The entries in this ou must have a gidNumber and cn attribute.
1172 ; Default: ou=Groups
1173 ; LDAP_OU_GROUP = ou=Groups", "
1174 ; Ignored. No LDAP support in this php. configure --with-ldap");
1177 if (function_exists('imap_open')) {
1179 $properties["IMAP Auth Host"] =
1180 new _define_optional('IMAP_AUTH_HOST', 'localhost:143/imap/notls', "
1181 If USER_AUTH_ORDER contains IMAP:
1183 The IMAP server to check usernames from. Defaults to localhost.
1185 Some IMAP_AUTH_HOST samples:
1186 localhost, localhost:143/imap/notls,
1187 localhost:993/imap/ssl/novalidate-cert (SuSE refuses non-SSL conections)");
1189 } else { // function_exists('imap_open')
1191 $properties["IMAP Authentication"] =
1192 new unchangeable_variable('IMAP_AUTH_HOST',"
1193 ; If USER_AUTH_ORDER contains IMAP:
1194 ; The IMAP server to check usernames from. Defaults to localhost.
1196 ; Some IMAP_AUTH_HOST samples:
1197 ; localhost, localhost:143/imap/notls,
1198 ; localhost:993/imap/ssl/novalidate-cert (SuSE refuses non-SSL conections)
1199 ;IMAP_AUTH_HOST = localhost:143/imap/notls", "
1200 Ignored. No IMAP support in this php. configure --with-imap");
1204 $properties["POP3 Authentication"] =
1205 new _define_optional('POP3_AUTH_HOST', 'localhost:110', "
1206 If USER_AUTH_ORDER contains POP3:
1208 The POP3 mail server to check usernames and passwords against.");
1209 $properties["File Authentication"] =
1210 new _define_optional('AUTH_USER_FILE', '/etc/shadow', "
1211 If USER_AUTH_ORDER contains File:
1213 File to read for authentication information.
1214 Popular choices are /etc/shadow and /etc/httpd/.htpasswd");
1216 $properties["File Storable?"] =
1217 new boolean_define_commented_optional('AUTH_USER_FILE_STORABLE');
1219 $properties["Session Auth USER"] =
1220 new _define_optional('AUTH_SESS_USER', 'userid', "
1221 If USER_AUTH_ORDER contains Session:
1223 Name of the session variable which holds the already authenticated username.
1224 Sample: 'userid', 'user[username]', 'user->username'");
1226 $properties["Session Auth LEVEL"] =
1227 new numeric_define('AUTH_SESS_LEVEL', '2', "
1228 Which level will the user be? 1 = Bogo or 2 = Pass");
1230 /////////////////////////////////////////////////////////////////////
1232 $properties["Part Four"] =
1233 new part('_part4', $SEPARATOR."\n", "
1236 Page appearance and layout");
1238 $properties["Theme"] =
1239 new _define_selection_optional('THEME',
1240 array('default' => "default",
1241 'MacOSX' => "MacOSX",
1242 'smaller' => 'smaller',
1243 'Wordpress'=> 'Wordpress',
1244 'Portland' => "Portland",
1245 'Sidebar' => "Sidebar",
1247 'wikilens' => 'wikilens (Ratings)',
1248 'shamino_com' => 'shamino_com',
1249 'SpaceWiki' => "SpaceWiki",
1250 'Hawaiian' => "Hawaiian",
1251 'MonoBook' => 'MonoBook [experimental]',
1252 'blog' => 'blog [experimental]',
1256 Most of the page appearance is controlled by files in the theme
1259 There are a number of pre-defined themes shipped with PhpWiki.
1260 Or you may create your own, e.g. by copying and then modifying one of
1265 THEME = MonoBook (WikiPedia)
1271 THEME = wikilens (with Ratings)
1279 THEME = blog (Kubrick) [experimental. Several links missing]
1282 $properties["Character Set"] =
1283 new _define_optional('CHARSET', 'iso-8859-1');
1285 $properties["Ignore Charset Not Supported Warning"] =
1286 new _define_optional('IGNORE_CHARSET_NOT_SUPPORTED_WARNING');
1288 $properties["Language"] =
1289 new _define_selection_optional('DEFAULT_LANGUAGE',
1290 array('en' => "English",
1291 '' => "<empty> (user-specific)",
1294 'nl' => "Nederlands",
1299 'zh' => "Chinese"), "
1300 Select your language/locale - default language is \"en\" for English.
1301 Other languages available:<pre>
1302 English \"en\" (English - HomePage)
1303 German \"de\" (Deutsch - StartSeite)
1304 French \"fr\" (Fran~is - Accueil)
1305 Dutch \"nl\" (Nederlands - ThuisPagina)
1306 Spanish \"es\" (Espa~l - P~inaPrincipal)
1307 Swedish \"sv\" (Svenska - Framsida)
1308 Italian \"it\" (Italiano - PaginaPrincipale)
1309 Japanese \"ja\" (Japanese - ~~~~~~)
1310 Chinese \"zh\" (Chinese)
1312 If you set DEFAULT_LANGUAGE to the empty string, your systems default language
1313 (as determined by the applicable environment variables) will be
1316 $properties["Wiki Page Source"] =
1317 new _define_optional('WIKI_PGSRC', 'pgsrc', "
1318 WIKI_PGSRC -- specifies the source for the initial page contents of
1319 the Wiki. The setting of WIKI_PGSRC only has effect when the wiki is
1320 accessed for the first time (or after clearing the database.)
1321 WIKI_PGSRC can either name a directory or a zip file. In either case
1322 WIKI_PGSRC is scanned for files -- one file per page.
1324 // Default (old) behavior:
1325 define('WIKI_PGSRC', 'pgsrc');
1327 define('WIKI_PGSRC', 'wiki.zip');
1328 define('WIKI_PGSRC',
1329 '../Logs/Hamwiki/hamwiki-20010830.zip');
1332 $properties["Default Wiki Page Source"] =
1333 new _define('DEFAULT_WIKI_PGSRC', 'pgsrc', "
1334 DEFAULT_WIKI_PGSRC is only used when the language is *not* the
1335 default (English) and when reading from a directory: in that case
1336 some English pages are inserted into the wiki as well.
1337 DEFAULT_WIKI_PGSRC defines where the English pages reside.
1340 $properties["Generic Pages"] =
1341 new array_variable('DEFAULT_WIKI_PAGES', array('ReleaseNotes', 'SteveWainstead', 'TestPage'), "
1342 These are ':'-seperated pages which will get loaded untranslated from DEFAULT_WIKI_PGSRC.
1347 $properties["Part Five"] =
1348 new part('_part5', $SEPARATOR."\n", "
1353 $properties["Allowed Protocols"] =
1354 new list_define('ALLOWED_PROTOCOLS', 'http|https|mailto|ftp|news|nntp|ssh|gopher', "
1355 Allowed protocols for links - be careful not to allow \"javascript:\"
1356 URL of these types will be automatically linked.
1357 within a named link [name|uri] one more protocol is defined: phpwiki");
1359 $properties["Inline Images"] =
1360 new list_define('INLINE_IMAGES', 'png|jpg|gif');
1362 $properties["WikiName Regexp"] =
1363 new _define('WIKI_NAME_REGEXP', "(?<![[:alnum:]])(?:[[:upper:]][[:lower:]]+){2,}(?![[:alnum:]])", "
1364 Perl regexp for WikiNames (\"bumpy words\")
1365 (?<!..) & (?!...) used instead of '\b' because \b matches '_' as well");
1367 $properties["Subpage Separator"] =
1368 new _define_optional('SUBPAGE_SEPARATOR', '"/"', "
1369 One character which seperates pages from subpages. Defaults to '/', but '.' or ':' were also used.",
1370 "onchange=\"validate_ereg('Sorry, \'%s\' must be a single character. Currently only :, / or .', '^[/:.]$', 'SUBPAGE_SEPARATOR', this);\""
1373 $properties["InterWiki Map File"] =
1374 new _define('INTERWIKI_MAP_FILE', 'lib/interwiki.map', "
1375 InterWiki linking -- wiki-style links to other wikis on the web
1377 The map will be taken from a page name InterWikiMap.
1378 If that page is not found (or is not locked), or map
1379 data can not be found in it, then the file specified
1380 by INTERWIKI_MAP_FILE (if any) will be used.");
1382 $properties["WARN_NONPUBLIC_INTERWIKIMAP"] =
1383 new boolean_define('WARN_NONPUBLIC_INTERWIKIMAP');
1385 $properties["Keyword Link Regexp"] =
1386 new _define_optional('KEYWORDS', '\"Category* OR Topic*\"', "
1387 Search term used for automatic page classification by keyword extraction.
1389 Any links on a page to pages whose names match this search
1390 will be used keywords in the keywords html meta tag. This is an aid to
1391 classification by search engines. The value of the match is
1392 used as the keyword.
1394 The default behavior is to match Category* or Topic* links.");
1396 $properties["Author and Copyright Site Navigation Links"] =
1397 new _define_commented_optional('COPYRIGHTPAGE_TITLE', "GNU General Public License", "
1399 These will be inserted as <link rel> tags in the html header of
1400 every page, for search engines and for browsers like Mozilla which
1401 take advantage of link rel site navigation.
1403 If you have your own copyright and contact information pages change
1404 these as appropriate.");
1406 $properties["COPYRIGHTPAGE URL"] =
1407 new _define_commented_optional('COPYRIGHTPAGE_URL', "http://www.gnu.org/copyleft/gpl.html#SEC1", "
1409 Other useful alternatives to consider:
1411 COPYRIGHTPAGE_TITLE = \"GNU Free Documentation License\"
1412 COPYRIGHTPAGE_URL = \"http://www.gnu.org/copyleft/fdl.html\"
1413 COPYRIGHTPAGE_TITLE = \"Creative Commons License 2.0\"
1414 COPYRIGHTPAGE_URL = \"http://creativecommons.org/licenses/by/2.0/\"</pre>
1415 See http://creativecommons.org/learn/licenses/ for variations");
1417 $properties["AUTHORPAGE_TITLE"] =
1418 new _define_commented_optional('AUTHORPAGE_TITLE', "The PhpWiki Programming Team", "
1419 Default Author Names");
1420 $properties["AUTHORPAGE_URL"] =
1421 new _define_commented_optional('AUTHORPAGE_URL', "http://phpwiki.org/ThePhpWikiProgrammingTeam", "
1422 Default Author URL");
1424 $properties["TOC_FULL_SYNTAX"] =
1425 new boolean_define_optional('TOC_FULL_SYNTAX');
1427 $properties["ENABLE_MARKUP_COLOR"] =
1428 new boolean_define_optional('ENABLE_MARKUP_COLOR');
1430 $properties["ENABLE_MARKUP_TEMPLATE"] =
1431 new boolean_define_optional('ENABLE_MARKUP_TEMPLATE');
1433 $properties["DISABLE_MARKUP_WIKIWORD"] =
1434 new boolean_define_optional('DISABLE_MARKUP_WIKIWORD');
1436 $properties["ENABLE_MARKUP_DIVSPAN" ] =
1437 new boolean_define_optional('ENABLE_MARKUP_DIVSPAN');
1441 $properties["Part Six"] =
1442 new part('_part6', $SEPARATOR."\n", "
1444 Part Six (optional):
1445 URL options -- you can probably skip this section.
1447 For a pretty wiki (no index.php in the url) set a seperate DATA_PATH.");
1449 $properties["Server Name"] =
1450 new _define_commented_optional('SERVER_NAME', $_SERVER['SERVER_NAME'], "
1451 Canonical name of the server on which this PhpWiki resides.");
1453 $properties["Server Port"] =
1454 new numeric_define_commented('SERVER_PORT', $_SERVER['SERVER_PORT'], "
1455 Canonical httpd port of the server on which this PhpWiki resides.",
1456 "onchange=\"validate_ereg('Sorry, \'%s\' is no valid port number.', '^[0-9]+$', 'SERVER_PORT', this);\"");
1458 $properties["Server Protocol"] =
1459 new _define_selection_optional_commented('SERVER_PROTOCOL',
1460 array('http' => 'http',
1461 'https' => 'https'));
1463 $properties["Script Name"] =
1464 new _define_commented_optional('SCRIPT_NAME', $scriptname);
1466 $properties["Data Path"] =
1467 new _define_commented_optional('DATA_PATH', dirname($scriptname));
1469 $properties["PhpWiki Install Directory"] =
1470 new _define_commented_optional('PHPWIKI_DIR', dirname(__FILE__));
1472 $properties["Use PATH_INFO"] =
1473 new _define_selection_optional_commented('USE_PATH_INFO',
1474 array('' => 'automatic',
1475 'true' => 'use PATH_INFO',
1476 'false' => 'do not use PATH_INFO'), "
1477 PhpWiki will try to use short urls to pages, eg
1478 http://www.example.com/index.php/HomePage
1479 If you want to use urls like
1480 http://www.example.com/index.php?pagename=HomePage
1481 then define 'USE_PATH_INFO' as false by uncommenting the line below.
1482 NB: If you are using Apache >= 2.0.30, then you may need to to use
1483 the directive \"AcceptPathInfo On\" in your Apache configuration file
1484 (or in an appropriate <.htaccess> file) for the short urls to work:
1485 See http://httpd.apache.org/docs-2.0/mod/core.html#acceptpathinfo
1487 See also http://phpwiki.sourceforge.net/phpwiki/PrettyWiki for more ideas
1488 on prettifying your urls.
1490 Default: PhpWiki will try to divine whether use of PATH_INFO
1491 is supported in by your webserver/PHP configuration, and will
1492 use PATH_INFO if it thinks that is possible.");
1494 $properties["Virtual Path"] =
1495 new _define_commented_optional('VIRTUAL_PATH', '/SomeWiki', "
1496 VIRTUAL_PATH is the canonical URL path under which your your wiki
1497 appears. Normally this is the same as dirname(SCRIPT_NAME), however
1498 using e.g. seperate starter scripts, apaches mod_actions (or mod_rewrite),
1499 you can make it something different.
1501 If you do this, you should set VIRTUAL_PATH here or in the starter scripts.
1503 E.g. your phpwiki might be installed at at /scripts/phpwiki/index.php,
1504 but you've made it accessible through eg. /wiki/HomePage.
1506 One way to do this is to create a directory named 'wiki' in your
1507 server root. The directory contains only one file: an .htaccess
1508 file which reads something like:
1510 Action x-phpwiki-page /scripts/phpwiki/index.php
1511 SetHandler x-phpwiki-page
1512 DirectoryIndex /scripts/phpwiki/index.php
1514 In that case you should set VIRTUAL_PATH to '/wiki'.
1516 (VIRTUAL_PATH is only used if USE_PATH_INFO is true.)
1519 $temp = !empty($_ENV['TEMP']) ? $_ENV['TEMP'] : "/tmp";
1520 $properties["TEMP_DIR"] =
1521 new _define_optional('TEMP_DIR', $temp);
1525 $properties["Part Seven"] =
1526 new part('_part7', $SEPARATOR."\n", "
1530 Miscellaneous settings
1533 $properties["Strict Mailable Pagedumps"] =
1534 new boolean_define_optional('STRICT_MAILABLE_PAGEDUMPS',
1535 array('false' => "binary",
1536 'true' => "quoted-printable"));
1538 $properties["Default local Dump Directory"] =
1539 new _define_optional('DEFAULT_DUMP_DIR');
1541 $properties["Default local HTML Dump Directory"] =
1542 new _define_optional('HTML_DUMP_DIR');
1544 $properties["HTML Dump Filename Suffix"] =
1545 new _define_optional('HTML_DUMP_SUFFIX');
1547 $properties["Pagename of Recent Changes"] =
1548 new _define_optional('RECENT_CHANGES',
1551 $properties["Disable HTTP Redirects"] =
1552 new boolean_define_commented_optional('DISABLE_HTTP_REDIRECT');
1554 $properties["Disable GETIMAGESIZE"] =
1555 new boolean_define_commented_optional('DISABLE_GETIMAGESIZE');
1557 $properties["EDITING_POLICY"] =
1558 new _define_optional('EDITING_POLICY');
1560 $properties["TOOLBAR_PAGELINK_PULLDOWN"] =
1561 new _define_commented_optional('TOOLBAR_PAGELINK_PULLDOWN');
1562 $properties["TOOLBAR_TEMPLATE_PULLDOWN"] =
1563 new _define_commented_optional('TOOLBAR_TEMPLATE_PULLDOWN');
1564 $properties["FULLTEXTSEARCH_STOPLIST"] =
1565 new _define_commented_optional('FULLTEXTSEARCH_STOPLIST');
1567 $properties["Part Seven A"] =
1568 new part('_part7a', $SEPARATOR."\n", "
1572 Optional Plugin Settings and external executables
1575 $properties["FORTUNE_DIR"] =
1576 new _define_commented_optional('FORTUNE_DIR', "/usr/share/fortune");
1577 $properties["USE_EXTERNAL_HTML2PDF"] =
1578 new _define_commented_optional('USE_EXTERNAL_HTML2PDF', "htmldoc --quiet --format pdf14 --no-toc --no-title %s");
1579 $properties["BABYCART_PATH"] =
1580 new _define_commented_optional('BABYCART_PATH', "/usr/local/bin/babycart");
1581 $properties["GOOGLE_LICENSE_KEY"] =
1582 new _define_commented_optional('GOOGLE_LICENSE_KEY');
1583 $properties["RATEIT_IMGPREFIX"] =
1584 new _define_commented_optional('RATEIT_IMGPREFIX'); //BStar
1585 $properties["GRAPHVIZ_EXE"] =
1586 new _define_commented_optional('GRAPHVIZ_EXE'); // /usr/local/bin/dot
1587 $properties["VISUALWIKIFONT"] =
1588 new _define_commented_optional('VISUALWIKIFONT'); // Arial
1589 $properties["VISUALWIKI_ALLOWOPTIONS"] =
1590 new boolean_define_commented_optional('VISUALWIKI_ALLOWOPTIONS'); // false
1591 $properties["PLOTICUS_EXE"] =
1592 new _define_commented_optional('PLOTICUS_EXE'); // /usr/local/bin/pl
1593 $properties["PLOTICUS_PREFABS"] =
1594 new _define_commented_optional('PLOTICUS_PREFABS'); // /usr/share/ploticus
1595 $properties["MY_JABBER_ID"] =
1596 new _define_commented_optional('MY_JABBER_ID'); //
1597 $properties["PHPWEATHER_BASE_DIR"] =
1598 new _define_commented_optional('PHPWEATHER_BASE_DIR'); //
1599 $properties["HIGHLIGHT_EXE"] =
1600 new _define_commented_optional('HIGHLIGHT_EXE'); // /usr/local/bin/highlight
1601 $properties["HIGHLIGHT_DATA_DIR"] =
1602 new _define_commented_optional('HIGHLIGHT_DATA_DIR'); // /usr/share/highlight
1605 $properties["Part Eight"] =
1606 new part('_part8', $SEPARATOR."\n", "
1610 Cached Plugin Settings. (pear Cache)
1613 $properties["pear Cache USECACHE"] =
1614 new boolean_define_optional('PLUGIN_CACHED_USECACHE',
1615 array('true' => 'Enabled',
1616 'false' => 'Disabled'), "
1617 Enable or disable pear caching of plugins.");
1618 $properties["pear Cache Database Container"] =
1619 new _define_selection_optional('PLUGIN_CACHED_DATABASE',
1620 array('file' => 'file'), "
1621 Curently only file is supported.
1622 db, trifile and imgfile might be supported, but you must hack that by yourself.");
1624 $properties["pear Cache cache directory"] =
1625 new _define_commented_optional('PLUGIN_CACHED_CACHE_DIR', "/tmp/cache", "
1626 Should be writable to the webserver.");
1627 $properties["pear Cache Filename Prefix"] =
1628 new _define_optional('PLUGIN_CACHED_FILENAME_PREFIX', "phpwiki", "");
1629 $properties["pear Cache HIGHWATER"] =
1630 new numeric_define_optional('PLUGIN_CACHED_HIGHWATER', "4194304", "
1631 Garbage collection parameter.");
1632 $properties["pear Cache LOWWATER"] =
1633 new numeric_define_optional('PLUGIN_CACHED_LOWWATER', "3145728", "
1634 Garbage collection parameter.");
1635 $properties["pear Cache MAXLIFETIME"] =
1636 new numeric_define_optional('PLUGIN_CACHED_MAXLIFETIME', "2592000", "
1637 Garbage collection parameter.");
1638 $properties["pear Cache MAXARGLEN"] =
1639 new numeric_define_optional('PLUGIN_CACHED_MAXARGLEN', "1000", "
1640 max. generated url length.");
1641 $properties["pear Cache FORCE_SYNCMAP"] =
1642 new boolean_define_optional('PLUGIN_CACHED_FORCE_SYNCMAP',
1643 array('true' => 'Enabled',
1644 'false' => 'Disabled'), "");
1645 $properties["pear Cache IMGTYPES"] =
1646 new list_define('PLUGIN_CACHED_IMGTYPES', "png|gif|gd|gd2|jpeg|wbmp|xbm|xpm", "
1647 Handle those image types via GD handles. Check your GD supported image types.");
1649 $end = "\n".$SEPARATOR."\n";
1652 text_from_dist("_MAGIC_CLOSE_FILE");
1654 // end of configuration options
1655 ///////////////////////////////
1656 // begin class definitions
1659 * A basic config-dist.ini configuration line in the form of a variable.
1660 * (not needed anymore, we have only defines)
1662 * Produces a string in the form "$name = value;"
1664 * $WikiNameRegexp = "value";
1668 var $config_item_name;
1674 function _variable($config_item_name, $default_value, $description = '', $jscheck = '') {
1675 $this->config_item_name = $config_item_name;
1677 $description = text_from_dist($config_item_name);
1678 $this->description = $description;
1679 if (defined($config_item_name)
1680 and !preg_match("/(selection|boolean)/", get_class($this))
1681 and !preg_match("/^(SCRIPT_NAME|VIRTUAL_PATH|TEMP_DIR)$/", $config_item_name))
1682 $this->default_value = constant($config_item_name); // ignore given default value
1683 elseif ($config_item_name == $default_value)
1684 $this->default_value = '';
1686 $this->default_value = $default_value;
1687 $this->jscheck = $jscheck;
1688 if (preg_match("/variable/i", get_class($this)))
1689 $this->prefix = "\$";
1690 elseif (preg_match("/ini_set/i", get_class($this)))
1691 $this->prefix = "ini_get: ";
1697 global $HTTP_POST_VARS;
1698 if (isset($HTTP_POST_VARS[$this->config_item_name]))
1699 return $HTTP_POST_VARS[$this->config_item_name];
1701 return $this->default_value;
1704 function _config_format($value) {
1706 $v = $this->get_config_item_name();
1707 // handle arrays: a|b --> a['b']
1708 if (strpos($v, '|')) {
1709 list($a, $b) = explode('|', $v);
1710 $v = sprintf("%s['%s']", $a, $b);
1712 if (preg_match("/[\"']/", $value))
1713 $value = '"' . $value . '"';
1714 return sprintf("%s = \"%s\"", $v, $value);
1717 function get_config_item_name() {
1718 return $this->config_item_name;
1721 function get_config_item_id() {
1722 return str_replace('|', '-', $this->config_item_name);
1725 function get_config_item_header() {
1726 if (strchr($this->config_item_name,'|')) {
1727 list($var,$param) = explode('|',$this->config_item_name);
1728 return "<b>" . $this->prefix . $var . "['" . $param . "']</b><br />";
1730 elseif ($this->config_item_name[0] != '_')
1731 return "<b>" . $this->prefix . $this->config_item_name . "</b><br />";
1736 function _get_description() {
1737 return $this->description;
1740 function _get_config_line($posted_value) {
1741 return "\n" . $this->_config_format($posted_value);
1744 function get_config($posted_value) {
1745 $d = stripHtml($this->_get_description());
1746 $d = str_replace("\n", "\n; ", $d) . $this->_get_config_line($posted_value) ."\n";
1750 function get_instructions($title) {
1752 $i = "<h3>" . $title . "</h3>\n " . nl2p($this->_get_description()) . "\n";
1753 return "<tr>\n<td width=\"$tdwidth\" class=\"instructions\">\n" . $i . "</td>\n";
1756 function get_html() {
1757 $size = strlen($this->default_value) > 45 ? 90 : 50;
1758 return $this->get_config_item_header() .
1759 "<input type=\"text\" size=\"$50\" name=\"" . $this->get_config_item_name() . "\" value=\"" . htmlspecialchars($this->default_value) . "\" " .
1760 $this->jscheck . " />" . "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: green\">Input accepted.</p>";
1764 class unchangeable_variable
1766 function _config_format($value) {
1769 // function get_html() { return false; }
1770 function get_html() {
1771 return $this->get_config_item_header() .
1772 "<em>Not editable.</em>" .
1773 "<pre>" . $this->default_value."</pre>";
1775 function _get_config_line($posted_value) {
1776 if ($this->description)
1778 return "${n}".$this->default_value;
1780 function get_instructions($title) {
1782 $i = "<h3>" . $title . "</h3>\n " . nl2p($this->_get_description()) . "\n";
1783 // $i .= "<em>Not editable.</em><br />\n<pre>" . $this->default_value."</pre>";
1784 return '<tr><td width="100%" class="unchangeable-variable-top" colspan="2">'."\n".$i."</td></tr>\n"
1785 . '<tr style="border-top: none;"><td class="unchangeable-variable-left" width="'.$tdwidth.'"> </td>';
1789 class unchangeable_define
1790 extends unchangeable_variable {
1791 function _get_config_line($posted_value) {
1792 if ($this->description)
1795 $posted_value = $this->default_value;
1796 return "${n}".$this->_config_format($posted_value);
1798 function _config_format($value) {
1799 return sprintf("%s = \"%s\"", $this->get_config_item_name(), $value);
1802 class unchangeable_ini_set
1803 extends unchangeable_variable {
1804 function _config_format($value) {
1809 class _variable_selection
1812 global $HTTP_POST_VARS;
1813 if (!empty($HTTP_POST_VARS[$this->config_item_name]))
1814 return $HTTP_POST_VARS[$this->config_item_name];
1816 list($option, $label) = each($this->default_value);
1820 function get_html() {
1821 $output = $this->get_config_item_header();
1822 $output .= '<select name="' . $this->get_config_item_name() . "\">\n";
1823 /* The first option is the default */
1824 $values = $this->default_value;
1825 if (defined($this->get_config_item_name()))
1826 $this->default_value = constant($this->get_config_item_name());
1828 $this->default_value = null;
1829 while(list($option, $label) = each($values)) {
1830 if (!is_null($this->default_value) and $this->default_value === $option)
1831 $output .= " <option value=\"$option\" selected=\"selected\">$label</option>\n";
1833 $output .= " <option value=\"$option\">$label</option>\n";
1835 $output .= "</select>\n";
1843 function _config_format($value) {
1844 return sprintf("%s = \"%s\"", $this->get_config_item_name(), $value);
1846 function _get_config_line($posted_value) {
1847 if ($this->description)
1849 if ($posted_value == '')
1850 return "${n};" . $this->_config_format("");
1852 return "${n}" . $this->_config_format($posted_value);
1854 function get_html() {
1855 $size = strlen($this->default_value) > 45 ? 90 : 50;
1856 return $this->get_config_item_header()
1857 . "<input type=\"text\" size=\"$size\" name=\"" . htmlentities($this->get_config_item_name())
1858 . "\" value=\"" . htmlentities($this->default_value) . "\" {$this->jscheck} />"
1859 . "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: green\">Input accepted.</p>";
1863 class _define_commented
1865 function _get_config_line($posted_value) {
1866 if ($this->description)
1868 if ($posted_value == $this->default_value)
1869 return "${n};" . $this->_config_format($posted_value);
1870 elseif ($posted_value == '')
1871 return "${n};" . $this->_config_format("");
1873 return "${n}" . $this->_config_format($posted_value);
1878 * We don't use _optional anymore, because INI-style config's don't need that.
1879 * IniConfig.php does the optional logic now.
1880 * But we use _optional for config-default.ini options
1882 class _define_commented_optional
1883 extends _define_commented { }
1885 class _define_optional
1888 class _define_notempty
1890 function get_html() {
1891 $s = $this->get_config_item_header()
1892 . "<input type=\"text\" size=\"50\" name=\"" . $this->get_config_item_name()
1893 . "\" value=\"" . $this->default_value . "\" {$this->jscheck} />";
1894 if (empty($this->default_value))
1895 return $s . "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: red\">Cannot be empty.</p>";
1897 return $s . "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: green\">Input accepted.</p>";
1901 class _variable_commented
1903 function _get_config_line($posted_value) {
1904 if ($this->description)
1906 if ($posted_value == $this->default_value)
1907 return "${n};" . $this->_config_format($posted_value);
1908 elseif ($posted_value == '')
1909 return "${n};" . $this->_config_format("");
1911 return "${n}" . $this->_config_format($posted_value);
1915 class numeric_define
1918 function numeric_define($config_item_name, $default_value, $description = '', $jscheck = '') {
1919 $this->_define($config_item_name, $default_value, $description, $jscheck);
1921 $this->jscheck = "onchange=\"validate_ereg('Sorry, \'%s\' is not an integer.', '^[-+]?[0-9]+$', '" . $this->get_config_item_name() . "', this);\"";
1923 function _config_format($value) {
1924 //return sprintf("define('%s', %s);", $this->get_config_item_name(), $value);
1925 return sprintf("%s = %s", $this->get_config_item_name(), $value);
1927 function _get_config_line($posted_value) {
1928 if ($this->description)
1930 if ($posted_value == '')
1931 return "${n};" . $this->_config_format('0');
1933 return "${n}" . $this->_config_format($posted_value);
1937 class numeric_define_optional
1938 extends numeric_define {}
1940 class numeric_define_commented
1941 extends numeric_define {
1942 function _get_config_line($posted_value) {
1943 if ($this->description)
1945 if ($posted_value == $this->default_value)
1946 return "${n};" . $this->_config_format($posted_value);
1947 elseif ($posted_value == '')
1948 return "${n};" . $this->_config_format('0');
1950 return "${n}" . $this->_config_format($posted_value);
1954 class _define_selection
1955 extends _variable_selection {
1956 function _config_format($value) {
1957 return sprintf("%s = %s", $this->get_config_item_name(), $value);
1959 function _get_config_line($posted_value) {
1960 return _define::_get_config_line($posted_value);
1962 function get_html() {
1963 return _variable_selection::get_html();
1967 class _define_selection_optional
1968 extends _define_selection { }
1970 class _variable_selection_optional
1971 extends _variable_selection { }
1973 class _define_selection_optional_commented
1974 extends _define_selection_optional {
1975 function _get_config_line($posted_value) {
1976 if ($this->description)
1978 if ($posted_value == $this->default_value)
1979 return "${n};" . $this->_config_format($posted_value);
1980 elseif ($posted_value == '')
1981 return "${n};" . $this->_config_format("");
1983 return "${n}" . $this->_config_format($posted_value);
1987 class _define_password
1990 function _define_password($config_item_name, $default_value, $description = '', $jscheck = '') {
1991 if ($config_item_name == $default_value) $default_value = '';
1992 $this->_define($config_item_name, $default_value, $description, $jscheck);
1994 $this->jscheck = "onchange=\"validate_ereg('Sorry, \'%s\' cannot be empty.', '^.+$', '"
1995 . $this->get_config_item_name() . "', this);\"";
1997 function _get_config_line($posted_value) {
1998 if ($this->description)
2000 if ($posted_value == '') {
2001 $p = "${n};" . $this->_config_format("");
2002 $p .= "\n; If you used the passencrypt.php utility to encode the password";
2003 $p .= "\n; then uncomment this line:";
2004 $p .= "\n;ENCRYPTED_PASSWD = true";
2007 if (function_exists('crypt')) {
2008 $salt_length = max(CRYPT_SALT_LENGTH,
2012 16 * CRYPT_BLOWFISH);
2013 // generate an encrypted password
2014 $crypt_pass = crypt($posted_value, rand_ascii($salt_length));
2015 $p = "${n}" . $this->_config_format($crypt_pass);
2016 return $p . "\nENCRYPTED_PASSWD = true";
2018 $p = "${n}" . $this->_config_format($posted_value);
2019 $p .= "\n; Encrypted passwords cannot be used:";
2020 $p .= "\n; 'function crypt()' not available in this version of php";
2021 $p .= "\nENCRYPTED_PASSWD = false";
2026 function get_html() {
2027 return _variable_password::get_html();
2031 class _define_password_optional
2032 extends _define_password {
2034 function _define_password_optional($config_item_name, $default_value, $description = '', $jscheck = '') {
2035 if ($config_item_name == $default_value) $default_value = '';
2036 if (!$jscheck) $this->jscheck = " ";
2037 $this->_define($config_item_name, $default_value, $description, $jscheck);
2040 function _get_config_line($posted_value) {
2041 if ($this->description)
2043 if ($posted_value == '') {
2044 return "${n};" . $this->_config_format("");
2046 return "${n}" . $this->_config_format($posted_value);
2049 function get_html() {
2050 $s = $this->get_config_item_header();
2051 // dont re-encrypt already encrypted passwords
2052 $value = $this->value();
2053 $encrypted = !empty($GLOBALS['properties']["Encrypted Passwords"]) and
2054 $GLOBALS['properties']["Encrypted Passwords"]->value();
2057 $s .= "<input type=\"". ($encrypted ? "text" : "password") . "\" name=\"" . $this->get_config_item_name()
2058 . "\" value=\"" . $value . "\" {$this->jscheck} />";
2063 class _define_password_commented_optional
2064 extends _define_password_optional { }
2066 class _variable_password
2068 function _variable_password($config_item_name, $default_value, $description = '', $jscheck = '') {
2069 if ($config_item_name == $default_value) $default_value = '';
2070 $this->_define($config_item_name, $default_value, $description, $jscheck);
2072 $this->jscheck = "onchange=\"validate_ereg('Sorry, \'%s\' cannot be empty.', '^.+$', '" . $this->get_config_item_name() . "', this);\"";
2074 function get_html() {
2075 global $HTTP_POST_VARS, $HTTP_GET_VARS;
2076 $s = $this->get_config_item_header();
2077 if (isset($HTTP_POST_VARS['create']) or isset($HTTP_GET_VARS['create'])) {
2078 $new_password = random_good_password();
2079 $this->default_value = $new_password;
2080 $s .= "Created password: <strong>$new_password</strong><br /> <br />";
2082 // dont re-encrypt already encrypted passwords
2083 $value = $this->value();
2084 $encrypted = !empty($GLOBALS['properties']["Encrypted Passwords"]) and
2085 $GLOBALS['properties']["Encrypted Passwords"]->value();
2088 $s .= "<input type=\"". ($encrypted ? "text" : "password") . "\" name=\"" . $this->get_config_item_name()
2089 . "\" value=\"" . $value . "\" {$this->jscheck} />"
2090 . " <input type=\"submit\" name=\"create\" value=\"Create Random Password\" />";
2092 $s .= "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: red\">Cannot be empty.</p>";
2093 elseif (strlen($this->default_value) < 4)
2094 $s .= "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: red\">Must be longer than 4 chars.</p>";
2096 $s .= "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: green\">Input accepted.</p>";
2103 function _get_config_line($posted_value) {
2104 // split the phrase by any number of commas or space characters,
2105 // which include " ", \r, \t, \n and \f
2106 $list_values = preg_split("/[\s,]+/", $posted_value, -1, PREG_SPLIT_NO_EMPTY);
2107 $list_values = join("|", $list_values);
2108 return _variable::_get_config_line($list_values);
2110 function get_html() {
2111 $list_values = explode("|", $this->default_value);
2112 $rows = max(3, count($list_values) +1);
2113 $list_values = join("\n", $list_values);
2114 $ta = $this->get_config_item_header();
2115 $ta .= "<textarea cols=\"18\" rows=\"". $rows ."\" name=\"".$this->get_config_item_name()."\" {$this->jscheck}>";
2116 $ta .= $list_values . "</textarea>";
2117 $ta .= "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: green\">Input accepted.</p>";
2124 function _get_config_line($posted_value) {
2125 $list_values = preg_split("/[\s,]+/", $posted_value, -1, PREG_SPLIT_NO_EMPTY);
2126 $list_values = join("|", $list_values);
2127 return _variable::_get_config_line($list_values);
2129 function get_html() {
2130 $list_values = explode("|", $this->default_value);
2131 $rows = max(3, count($list_values) +1);
2132 $list_values = join("\n", $list_values);
2133 $ta = $this->get_config_item_header();
2134 $ta .= "<textarea cols=\"18\" rows=\"". $rows ."\" name=\"".$this->get_config_item_name()."\" {$this->jscheck}>";
2135 $ta .= $list_values . "</textarea>";
2136 $ta .= "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: green\">Input accepted.</p>";
2141 class array_variable
2143 function _config_format($value) {
2144 return sprintf("%s = \"%s\"", $this->get_config_item_name(),
2145 is_array($value) ? join(':', $value) : $value);
2147 function _get_config_line($posted_value) {
2148 // split the phrase by any number of commas or space characters,
2149 // which include " ", \r, \t, \n and \f
2150 $list_values = preg_split("/[\s,]+/", $posted_value, -1, PREG_SPLIT_NO_EMPTY);
2151 if (!empty($list_values)) {
2152 $list_values = "'".join("', '", $list_values)."'";
2153 return "\n" . $this->_config_format($list_values);
2155 return "\n;" . $this->_config_format('');
2157 function get_html() {
2158 $list_values = join("\n", $this->default_value);
2159 $rows = max(3, count($this->default_value) +1);
2160 $ta = $this->get_config_item_header();
2161 $ta .= "<textarea cols=\"18\" rows=\"". $rows ."\" name=\"".$this->get_config_item_name()."\" {$this->jscheck}>";
2162 $ta .= $list_values . "</textarea>";
2163 $ta .= "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: green\">Input accepted.</p>";
2170 function _config_format($value) {
2171 return sprintf("%s = \"%s\"", $this->get_config_item_name(),
2172 is_array($value) ? join(' : ', $value) : $value);
2174 function _get_config_line($posted_value) {
2175 // split the phrase by any number of commas or space characters,
2176 // which include " ", \r, \t, \n and \f
2177 $list_values = preg_split("/[\s,:]+/", $posted_value, -1, PREG_SPLIT_NO_EMPTY);
2178 if (!empty($list_values)) {
2179 $list_values = join(" : ", $list_values);
2180 return "\n" . $this->_config_format($list_values);
2182 return "\n;" . $this->_config_format('');
2184 function get_html () {
2185 if (!$this->default_value)
2186 $this->default_value = array();
2187 elseif (is_string($this->default_value))
2188 $this->default_value = preg_split("/[\s,:]+/", $this->default_value, -1, PREG_SPLIT_NO_EMPTY);
2189 $list_values = join(" : \n", $this->default_value);
2190 $rows = max(3, count($this->default_value) + 1);
2191 $ta = $this->get_config_item_header();
2192 $ta .= "<textarea cols=\"18\" rows=\"". $rows ."\" name=\"".$this->get_config_item_name()."\" {$this->jscheck}>";
2193 $ta .= $list_values . "</textarea>";
2194 $ta .= "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: green\">Input accepted.</p>";
2203 global $HTTP_POST_VARS;
2204 if ($v = $HTTP_POST_VARS[$this->config_item_name])
2207 return ini_get($this->get_config_item_name);
2210 function _config_format($value) {
2211 return sprintf("ini_set('%s', '%s');", $this->get_config_item_name(), $value);
2213 function _get_config_line($posted_value) {
2214 if ($posted_value && ! $posted_value == $this->default_value)
2215 return "\n" . $this->_config_format($posted_value);
2217 return "\n;" . $this->_config_format($this->default_value);
2222 class boolean_define
2225 // adds ->values property, instead of ->default_value
2226 function boolean_define($config_item_name, $values = false, $description = '', $jscheck = '') {
2227 $this->config_item_name = $config_item_name;
2229 $description = text_from_dist($config_item_name);
2230 $this->description = $description;
2231 // TESTME: get boolean default value from config-default.ini
2232 if (defined($config_item_name))
2233 $this->default_value = constant($config_item_name); // ignore given default value
2234 elseif (is_array($values))
2235 list($this->default_value,$dummy) = $values[0];
2237 $values = array('false' => "Disabled",
2238 'true' => "Enabled");
2239 $this->values = $values;
2240 $this->jscheck = $jscheck;
2243 function _get_config_line($posted_value) {
2244 if ($this->description)
2246 return "${n}" . $this->_config_format($posted_value);
2248 function _config_format($value) {
2249 if (strtolower(trim($value)) == 'false')
2251 return sprintf("%s = %s", $this->get_config_item_name(),
2252 (bool)$value ? 'true' : 'false');
2254 //TODO: radiobuttons, no list
2255 function get_html() {
2256 $output = $this->get_config_item_header();
2257 $name = $this->get_config_item_name();
2258 $output .= '<select name="' . $name . "\" {$this->jscheck}>\n";
2259 $values = $this->values;
2260 $default_value = $this->default_value ? 'true' : 'false';
2261 /* There can usually only be two options, there can be
2262 * three options in the case of a boolean_define_commented_optional */
2263 while (list($option, $label) = each($values)) {
2264 if (!is_null($this->default_value) and $option === $default_value)
2265 $output .= " <option value=\"$option\" selected=\"selected\">$label</option>\n";
2267 $output .= " <option value=\"$option\">$label</option>\n";
2269 $output .= "</select>\n";
2274 class boolean_define_optional
2275 extends boolean_define {}
2277 class boolean_define_commented
2278 extends boolean_define {
2279 function _get_config_line($posted_value) {
2280 if ($this->description)
2282 list($default_value, $label) = each($this->default_value);
2283 if ($posted_value == $default_value)
2284 return "${n};" . $this->_config_format($posted_value);
2285 elseif ($posted_value == '')
2286 return "${n};" . $this->_config_format('false');
2288 return "${n}" . $this->_config_format($posted_value);
2292 class boolean_define_commented_optional
2293 extends boolean_define_commented {}
2297 function value () { return; }
2298 function get_config($posted_value) {
2299 $d = stripHtml($this->_get_description());
2301 return "\n".$SEPARATOR . str_replace("\n", "\n; ", $d) ."\n".$this->default_value;
2303 function get_instructions($title) {
2304 $id = preg_replace("/\W/","",$this->config_item_name);
2305 $group_name = preg_replace("/\W/","",$title);
2306 $i = "<tr class=\"header\" id=\"$id\">\n<td class=\"part\" width=\"100%\" colspan=\"2\" bgcolor=\"#eeeeee\">\n";
2307 $i .= "<h2>" . $title . "</h2>\n " . nl2p($this->_get_description()) ."\n";
2308 $i .= "<p><a href=\"javascript:toggle_group('$id')\" id=\"{$id}_text\">Hide options.</a></p>";
2309 return $i ."</td>\n";
2311 function get_html() {
2316 // html utility functions
2317 function nl2p($text) {
2318 preg_match_all("@\s*(<pre>.*?</pre>|<dl>.*?</dl>|.*?(?=\n\n|<pre>|<dl>|$))@s",
2319 $text, $m, PREG_PATTERN_ORDER);
2322 foreach ($m[1] as $par) {
2323 if (!($par = trim($par)))
2325 if (!preg_match('/^<(pre|dl)>/', $par))
2326 $par = "<p>$par</p>";
2332 function text_from_dist($var) {
2333 static $distfile = 0;
2337 $sep = (substr(PHP_OS,0,3) == 'WIN' ? '\\' : '/');
2338 $distfile = dirname(__FILE__) . $sep . "config" . $sep . "config-dist.ini";
2339 $f = fopen($distfile, "r");
2341 if ($var == '_MAGIC_CLOSE_FILE') {
2345 // if all vars would be in natural order as in the config-dist this would not be needed.
2350 if (preg_match("/^; \w/", $s)) {
2351 $par .= (substr($s,2) . " ");
2352 } elseif (preg_match("/^;\s*$/", $s)) {
2355 if (preg_match("/^;?".preg_quote($var)."\s*=/", $s))
2357 if (preg_match("/^\s*$/", $s)) // new paragraph
2363 function stripHtml($text) {
2364 $d = str_replace("<pre>", "", $text);
2365 $d = str_replace("</pre>", "", $d);
2366 $d = str_replace("<dl>", "", $d);
2367 $d = str_replace("</dl>", "", $d);
2368 $d = str_replace("<dt>", "", $d);
2369 $d = str_replace("</dt>", "", $d);
2370 $d = str_replace("<dd>", "", $d);
2371 $d = str_replace("</dd>", "", $d);
2372 $d = str_replace("<p>", "", $d);
2373 $d = str_replace("</p>", "", $d);
2374 //restore html entities into characters
2375 // http://www.php.net/manual/en/function.htmlentities.php
2376 $trans = get_html_translation_table (HTML_ENTITIES);
2377 $trans = array_flip ($trans);
2378 $d = strtr($d, $trans);
2382 include_once(dirname(__FILE__)."/lib/stdlib.php");
2385 // Function to create better user passwords (much larger keyspace),
2386 // suitable for user passwords.
2387 // Sequence of random ASCII numbers, letters and some special chars.
2388 // Note: There exist other algorithms for easy-to-remember passwords.
2389 function random_good_password ($minlength = 5, $maxlength = 8) {
2391 // assume ASCII ordering (not valid on EBCDIC systems!)
2392 $valid_chars = "!#%&+-.0123456789=@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz";
2393 $start = ord($valid_chars);
2394 $end = ord(substr($valid_chars,-1));
2396 if (function_exists('mt_rand')) // mersenne twister
2397 $length = mt_rand($minlength, $maxlength);
2398 else // the usually bad glibc rand()
2399 $length = rand($minlength, $maxlength);
2400 while ($length > 0) {
2401 if (function_exists('mt_rand'))
2402 $newchar = mt_rand($start, $end);
2404 $newchar = rand($start, $end);
2405 if (! strrpos($valid_chars,$newchar) ) continue; // skip holes
2406 $newpass .= sprintf("%c", $newchar);
2413 function printArray($a) {
2414 echo "<hr />\n<pre>\n";
2416 echo "\n</pre>\n<hr />\n";
2419 // end of class definitions
2420 /////////////////////////////
2421 // begin auto generation code
2423 if (!function_exists('is_a')) {
2424 function is_a($object, $class) {
2425 $class = strtolower($class);
2426 return (get_class($object) == $class) or is_subclass_of($object, $class);
2431 if (!empty($HTTP_POST_VARS['action'])
2432 and $HTTP_POST_VARS['action'] == 'make_config'
2433 and !empty($HTTP_POST_VARS['ADMIN_USER'])
2434 and !empty($HTTP_POST_VARS['ADMIN_PASSWD'])
2438 $timestamp = date ('dS of F, Y H:i:s');
2441 ; This is a local configuration file for PhpWiki.
2442 ; It was automatically generated by the configurator script
2443 ; on the $timestamp.
2448 $posted = $GLOBALS['HTTP_POST_VARS'];
2449 /*if (defined('DEBUG'))
2450 printArray($GLOBALS['HTTP_POST_VARS']);*/
2452 foreach ($properties as $option_name => $a) {
2453 $posted_value = stripslashes($posted[$a->config_item_name]);
2454 $config .= $properties[$option_name]->get_config($posted_value);
2459 if (is_writable($fs_config_file)) {
2460 // We first check if the config-file exists.
2461 if (file_exists($fs_config_file)) {
2462 // We make a backup copy of the file
2463 $new_filename = preg_replace('/\.ini$/', '-' . time() . '.ini', $fs_config_file);
2464 if (@copy($fs_config_file, $new_filename)) {
2465 $fp = @fopen($fs_config_file, 'w');
2468 $fp = @fopen($fs_config_file, 'w');
2476 fputs($fp, $config);
2478 echo "<p>The configuration was written to <code><b>$config_file</b></code>.</p>\n";
2479 if ($new_filename) {
2480 echo "<p>A backup was made to <code><b>$new_filename</b></code>.</p>\n";
2482 ; //echo "<p><strong>You must rename or copy this</strong> <code><b>$config_file</b></code> <strong>file to</strong> <code><b>config/config.ini</b></code>.</p>\n";
2485 echo "<p>The configuration file could <b>not</b> be written.<br />\n",
2486 " You should copy the above configuration to a file, ",
2487 "and manually save it as <code><b>config/config.ini</b></code>.</p>\n";
2490 echo "<hr />\n<p>Here's the configuration file based on your answers:</p>\n";
2491 echo "<form method=\"get\" action=\"", $configurator, "\">\n";
2492 echo "<textarea id='config-output' readonly='readonly' style='width:100%;' rows='30' cols='100'>\n";
2493 echo htmlentities($config);
2494 echo "</textarea></form>\n";
2497 echo "<p>To make any corrections, <a href=\"configurator.php\">edit the settings again</a>.</p>\n";
2499 } else { // first time or create password
2500 $posted = $GLOBALS['HTTP_POST_VARS'];
2501 // No action has been specified - we make a form.
2503 if (!empty($GLOBALS['HTTP_GET_VARS']['start_debug']))
2504 $configurator .= ("?start_debug=" . $GLOBALS['HTTP_GET_VARS']['start_debug']);
2506 <form action="',$configurator,'" method="post">
2507 <input type="hidden" name="action" value="make_config" />
2508 <table cellpadding="4" cellspacing="0">
2511 while (list($property, $obj) = each($properties)) {
2512 echo $obj->get_instructions($property);
2513 if ($h = $obj->get_html()) {
2514 if (defined('DEBUG') and DEBUG) $h = get_class($obj) . "<br />\n" . $h;
2515 echo "<td>".$h."</td>\n";
2522 <p><input type="submit" id="submit" value="Save ',$config_file,'" /> <input type="reset" value="Clear" /></p>