1 <?php // $Id: configurator.php,v 1.38 2005-09-15 05:56:12 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 mixin class for commented
42 * o fix SQL quotes, AUTH_ORDER quotes and file forward slashes
43 * o posted values validation, extend js validation for sane DB values
44 * o read config-dist.ini into sections, comments, and optional/required settings
46 * A file config/config.ini will be automatically generated, if writable.
48 * NOTE: If you have a starterscript outside PHPWIKI_DIR but no
49 * config/config.ini yet (very unlikely!), you must define DATA_PATH in the
50 * starterscript, otherwise the webpath to configurator is unknown, and
51 * subsequent requests will fail. (POST to save the INI)
54 global $HTTP_SERVER_VARS, $HTTP_POST_VARS, $tdwidth;
55 if (empty($_GET)) $_GET =& $GLOBALS['HTTP_GET_VARS'];
56 if (empty($_ENV)) $_ENV =& $GLOBALS['HTTP_ENV_VARS'];
58 if (empty($configurator))
59 $configurator = "configurator.php";
60 if (!strstr($HTTP_SERVER_VARS["SCRIPT_NAME"], $configurator) and defined('DATA_PATH'))
61 $configurator = DATA_PATH . "/" . $configurator;
62 $scriptname = str_replace('configurator.php', 'index.php', $HTTP_SERVER_VARS["SCRIPT_NAME"]);
65 $config_file = (substr(PHP_OS,0,3) == 'WIN') ? 'config\\config.ini' : 'config/config.ini';
66 $fs_config_file = dirname(__FILE__) . (substr(PHP_OS,0,3) == 'WIN' ? '\\' : '/') . $config_file;
67 if (isset($HTTP_POST_VARS['create'])) header('Location: '.$configurator.'?show=_part1&create=1#create');
69 // helpers from lib/WikiUser/HttpAuth.php
70 if (!function_exists('_http_user')) {
71 function _http_user() {
73 $_SERVER = $GLOBALS['HTTP_SERVER_VARS'];
74 if (!empty($_SERVER['PHP_AUTH_USER']))
75 return array($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']);
76 if (!empty($_SERVER['REMOTE_USER']))
77 return array($_SERVER['REMOTE_USER'], $_SERVER['PHP_AUTH_PW']);
78 if (!empty($GLOBALS['HTTP_ENV_VARS']['REMOTE_USER']))
79 return array($GLOBALS['HTTP_ENV_VARS']['REMOTE_USER'],
80 $GLOBALS['HTTP_ENV_VARS']['PHP_AUTH_PW']);
81 if (!empty($GLOBALS['REMOTE_USER']))
82 return array($GLOBALS['REMOTE_USER'], $GLOBALS['PHP_AUTH_PW']);
85 if (!empty($_SERVER['HTTP_AUTHORIZATION'])) {
86 list($userid, $passwd) = explode(':', base64_decode(substr($_SERVER['HTTP_AUTHORIZATION'], 6)));
87 return array($userid, $passwd);
91 function _http_logout() {
93 $_SERVER =& $GLOBALS['HTTP_SERVER_VARS'];
94 // maybe we should random the realm to really force a logout. but the next login will fail.
95 // better_srand(); $realm = microtime().rand();
96 header('WWW-Authenticate: Basic realm="'.WIKI_NAME.'"');
97 if (strstr(php_sapi_name(), 'apache'))
98 header('HTTP/1.0 401 Unauthorized');
100 header("Status: 401 Access Denied"); //IIS and CGI need that
101 unset($GLOBALS['REMOTE_USER']);
102 unset($_SERVER['PHP_AUTH_USER']);
103 unset($_SERVER['PHP_AUTH_PW']);
105 trigger_error("Permission denied. Require ADMIN_USER.", E_USER_ERROR);
110 // If config.ini exists, we require ADMIN_USER access by faking HttpAuth.
111 // So nobody can see or reset the password(s).
112 if (file_exists($fs_config_file)) {
113 // Require admin user
114 if (!defined('ADMIN_USER') or !defined('ADMIN_PASSWD')) {
115 if (!function_exists("IniConfig")) {
116 include_once("lib/prepend.php");
117 include_once("lib/IniConfig.php");
119 IniConfig($fs_config_file);
121 if (!defined('ADMIN_USER') or ADMIN_USER == '') {
122 trigger_error("Configuration problem:\nADMIN_USER not defined in \"$fs_config_file\".\n"
123 . "Cannot continue: You have to fix that manually.", E_USER_ERROR);
127 list($admin_user, $admin_pw) = _http_user();
128 //$required_user = ADMIN_USER;
129 if (empty($admin_user) or $admin_user != ADMIN_USER)
134 if (ENCRYPTED_PASSWD and function_exists('crypt')) {
135 if (crypt($admin_pw, ADMIN_PASSWD) != ADMIN_PASSWD)
137 } elseif ($admin_pw != ADMIN_PASSWD) {
141 if (!function_exists("IniConfig")) {
142 include_once("lib/prepend.php");
143 include_once("lib/IniConfig.php");
145 $def_file = (substr(PHP_OS,0,3) == 'WIN') ? 'config\\config-default.ini' : 'config/config-default.ini';
146 $fs_def_file = dirname(__FILE__) . (substr(PHP_OS,0,3) == 'WIN' ? '\\' : '/') . $def_file;
147 IniConfig($fs_def_file);
150 echo "<","?xml version=\"1.0\" encoding=\"'iso-8859-1'\"?",">\n";
152 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
153 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
154 <html xmlns="http://www.w3.org/1999/xhtml">
156 <!-- $Id: configurator.php,v 1.38 2005-09-15 05:56:12 rurban Exp $ -->
157 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
158 <title>Configuration tool for PhpWiki <?php echo $config_file ?></title>
159 <style type="text/css" media="screen">
161 /* TABLE { border: thin solid black } */
162 body { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 80%; }
163 pre { font-size: 120%; }
164 td { border: thin solid black }
166 div.hint { border: thin solid red, background-color: #eeeeee; }
167 tr.hidden { border: none; display: none; }
168 td.part { background-color: #eeeeee; color: inherit; }
169 td.instructions { background-color: #ffffee; width: <?php echo $tdwidth ?>px; color: inherit; }
170 td.unchangeable-variable-top { border-bottom: none; background-color: #ffffee; color:inherit; }
171 td.unchangeable-variable-left { border-top: none; background-color: #ffffee; color:inherit; }
174 <script language="JavaScript" type="text/javascript">
176 function update(accepted, error, value, output) {
177 var msg = document.getElementById(output);
179 /* MSIE 5.0 fails here */
180 if (msg && msg.innerHTML) { msg.innerHTML = "<font color=\"green\">Input accepted.</font>"; }
182 while ((index = error.indexOf("%s")) > -1) {
183 error = error.substring(0, index) + value + error.substring(index+2);
185 if (msg) { msg.innerHTML = "<font color=\"red\">" + error + "</font>"; }
187 if (submit = document.getElementById('submit')) submit.disabled = accepted ? false : true;
190 function validate(error, value, output, field) {
191 update(field.value == value, error, field.value, output);
194 function validate_ereg(error, ereg, output, field) {
195 regex = new RegExp(ereg);
196 update(regex.test(field.value), error, field.value, output);
199 function validate_range(error, low, high, empty_ok, output, field) {
200 update((empty_ok == 1 && field.value == "") ||
201 (field.value >= low && field.value <= high),
202 error, field.value, output);
205 function toggle_group(id) {
206 var text = document.getElementById(id + "_text");
208 if (text.innerHTML == "Hide options.") {
210 text.innerHTML = "Show options.";
212 text.innerHTML = "Hide options.";
215 var rows = document.getElementsByTagName('tr');
217 for (i = 0; i < rows.length; i++) {
219 if (tr.className == 'header' && tr.id == id) {
224 for (; i < rows.length; i++) {
226 if (tr.className == 'header')
228 tr.className = do_hide ? 'hidden': 'nonhidden';
233 // Hide all groups. We do this via JavaScript to avoid
234 // hiding the groups if JavaScript is not supported...
235 var rows = document.getElementsByTagName('tr');
236 var show = '<?php echo $_GET["show"] ?>';
237 for (var i = 0; i < rows.length; i++) {
239 if (tr.className == 'header')
240 if (!show || tr.id != show)
244 // Select text in textarea upon focus
245 var area = document.getElementById('config-output');
247 listener = { handleEvent: function (e) { area.select(); } };
248 area.addEventListener('focus', listener, false);
255 <body onload="do_init();">
257 <h1>Configuration for PhpWiki <?php echo $config_file ?></h1>
260 Using this configurator.php is experimental!<br>
261 On any configuration problems, please edit the resulting config.ini manually.
265 //define('DEBUG', 1);
267 * The Configurator is a php script to aid in the configuration of PhpWiki.
268 * Parts of this file were based on PHPWeather's configurator.php file.
269 * http://sourceforge.net/projects/phpweather/
271 * TO CHANGE THE CONFIGURATION OF YOUR PHPWIKI, DO *NOT* MODIFY THIS FILE!
272 * more instructions go here
276 * * eval config.ini to get the actual settings.
279 //////////////////////////////
280 // begin configuration options
283 * Notes for the description parameter of $property:
285 * - Descriptive text will be changed into comments (preceeded by ; )
286 * for the final output to config.ini.
288 * - Only a limited set of html is allowed: pre, dl dt dd; it will be
289 * stripped from the final output.
291 * - Line breaks and spacing will be preserved for the final output.
293 * - Double line breaks are automatically converted to paragraphs
294 * for the html version of the descriptive text.
296 * - Double-quotes and dollar signs in the descriptive text must be
297 * escaped: \" and \$. Instead of escaping double-quotes you can use
298 * single (') quotes for the enclosing quotes.
300 * - Special characters like < and > must use html entities,
301 * they will be converted back to characters for the final output.
304 $SEPARATOR = ";=========================================================================";
307 ; This is the main configuration file for PhpWiki in INI-style format.
308 ; Note that certain characters are used as comment char and therefore
309 ; these entries must be in double-quotes. Such as \":\", \";\", \",\" and \"|\"
310 ; Take special care for DBAUTH_ sql statements. (Part 3a)
312 ; This file is divided into several parts: Each one has different configuration
313 ; settings you can change; in all cases the default should work on your system,
314 ; however, we recommend you tailor things to your particular setting.
315 ; Here undefined definitions get defined by config-default.ini settings.
318 $properties["Part Zero"] =
319 new part('_part0', $SEPARATOR."\n", "
320 Part Zero: (optional)
321 Latest Development and Tricky Options");
323 if (defined('INCLUDE_PATH'))
324 $include_path = INCLUDE_PATH;
326 if (substr(PHP_OS,0,3) == 'WIN') {
327 $include_path = dirname(__FILE__) . ';' . ini_get('include_path');
328 if (strchr(ini_get('include_path'),'/'))
329 $include_path = strtr($include_path,'\\','/');
331 $include_path = dirname(__FILE__) . ':' . ini_get('include_path');
335 $properties["PHP include_path"] =
336 new _define('INCLUDE_PATH', $include_path);
338 // TODO: convert this a checkbox row as in tests/unit/test.pgp
339 $properties["DEBUG"] =
340 new numeric_define_optional('DEBUG', DEBUG);
342 // TODO: bring the default to the front
343 $properties["ENABLE_USER_NEW"] =
344 new boolean_define_commented_optional
346 array('true' => "Enabled",
347 'false' => "Disabled."));
349 $properties["ENABLE_PAGEPERM"] =
350 new boolean_define_commented_optional
352 array('true' => "Enabled",
353 'false' => "Disabled."));
355 $properties["ENABLE_EDIT_TOOLBAR"] =
356 new boolean_define_commented_optional
357 ('ENABLE_EDIT_TOOLBAR',
358 array('true' => "Enabled",
359 'false' => "Disabled."));
361 $properties["JS_SEARCHREPLACE"] =
362 new boolean_define_commented_optional
364 array('true' => "Enabled",
365 'false' => "Disabled"));
367 $properties["ENABLE_DOUBLECLICKEDIT"] =
368 new boolean_define_commented_optional
369 ('ENABLE_DOUBLECLICKEDIT',
370 array('true' => "Enabled",
371 'false' => "Disabled"));
373 $properties["ENABLE_XHTML_XML"] =
374 new boolean_define_commented_optional
376 array('false' => "Disabled",
377 'true' => "Enabled"));
379 $properties["USECACHE"] =
380 new boolean_define_commented_optional
382 array('true' => "Enabled",
383 'false' => "Disabled"));
385 $properties["ENABLE_SPAMASSASSIN"] =
386 new boolean_define_commented_optional
387 ('ENABLE_SPAMASSASSIN',
388 array('true' => "Enabled",
389 'false' => "Disabled"));
391 $properties["GOOGLE_LINKS_NOFOLLOW"] =
392 new boolean_define_commented_optional
393 ('GOOGLE_LINKS_NOFOLLOW',
394 array('true' => "Enabled",
395 'false' => "Disabled"));
397 $properties["ENABLE_LIVESEARCH"] =
398 new boolean_define_commented_optional
399 ('ENABLE_LIVESEARCH',
400 array('true' => "Enabled",
401 'false' => "Disabled"));
403 $properties["ENABLE_ACDROPDOWN"] =
404 new boolean_define_commented_optional
405 ('ENABLE_ACDROPDOWN',
406 array('true' => "Enabled",
407 'false' => "Disabled"));
409 $properties["ENABLE_DISCUSSION_LINK"] =
410 new boolean_define_commented_optional
411 ('ENABLE_DISCUSSION_LINK',
412 array('true' => "Enabled",
413 'false' => "Disabled"));
415 $properties["ENABLE_CAPTCHA"] =
416 new boolean_define_commented_optional
418 array('true' => "Enabled",
419 'false' => "Disabled"));
421 $properties["USE_SAFE_DBSESSION"] =
422 new boolean_define_commented_optional
423 ('USE_SAFE_DBSESSION',
424 array('false' => "Disabled",
425 'true' => "Enabled"));
427 $properties["Part One"] =
428 new part('_part1', $SEPARATOR."\n", "
429 Part One: Authentication and security settings. See Part Three for more.");
431 $properties["Wiki Name"] =
432 new _define_optional('WIKI_NAME', WIKI_NAME);
434 $properties["Admin Username"] =
435 new _define_notempty('ADMIN_USER', ADMIN_USER, "
436 You must set this! Username and password of the administrator.",
437 "onchange=\"validate_ereg('Sorry, ADMIN_USER cannot be empty.', '^.+$', 'ADMIN_USER', this);\"");
439 $properties["Admin Password"] =
440 new _define_password('ADMIN_PASSWD', ADMIN_PASSWD, "
442 For heaven's sake pick a good password.
444 If your version of PHP supports encrypted passwords, your password will be
445 automatically encrypted within the generated config file.
446 Use the \"Create Random Password\" button to create a good (random) password.
448 ADMIN_PASSWD is ignored on HttpAuth",
449 "onchange=\"validate_ereg('Sorry, ADMIN_PASSWD must be at least 4 chars long.', '^....+$', 'ADMIN_PASSWD', this);\"");
451 $properties["Encrypted Passwords"] =
454 array('true' => "true. use crypt for all passwords",
455 'false' => "false. use plaintest passwords (not recommended)"));
457 $properties["Reverse DNS"] =
458 new boolean_define_optional
459 ('ENABLE_REVERSE_DNS',
460 array('true' => "true. perform additional reverse dns lookups",
461 'false' => "false. just record the address as given by the httpd server"));
463 $properties["ZIPdump Authentication"] =
464 new boolean_define_optional('ZIPDUMP_AUTH',
465 array('false' => "false. Everyone may download zip dumps",
466 'true' => "true. Only admin may download zip dumps"));
468 $properties["Enable RawHtml Plugin"] =
469 new boolean_define_commented_optional
471 array('true' => "Enabled",
472 'false' => "Disabled"));
474 $properties["Allow RawHtml Plugin only on locked pages"] =
475 new boolean_define_commented_optional
476 ('ENABLE_RAW_HTML_LOCKEDONLY',
477 array('true' => "Enabled",
478 'false' => "Disabled"));
480 $properties["Allow RawHtml Plugin if safe HTML code"] =
481 new boolean_define_commented_optional
482 ('ENABLE_RAW_HTML_SAFE',
483 array('true' => "Enabled",
484 'false' => "Disabled"), "
485 If this is set, all unsafe html code is stripped automatically (experimental!)
486 See <a href=\"http://chxo.com/scripts/safe_html-test.php\" target=\"_new\">chxo.com/scripts/safe_html-test.php</a>
489 $properties["Maximum Upload Size"] =
490 new numeric_define_optional('MAX_UPLOAD_SIZE', MAX_UPLOAD_SIZE /*"16 * 1024 * 1024"*/, "
491 The maximum file upload size.");
493 $properties["Minor Edit Timeout"] =
494 new numeric_define_optional('MINOR_EDIT_TIMEOUT', MINOR_EDIT_TIMEOUT /*"7 * 24 * 3600"*/, "
495 If the last edit is older than MINOR_EDIT_TIMEOUT seconds, the
496 default state for the \"minor edit\" checkbox on the edit page form
499 $properties["Disabled Actions"] =
500 new array_define('DISABLED_ACTIONS', DISABLED_ACTIONS /*array()*/, "
501 Actions listed in this array will not be allowed. Actions are:
502 browse, create, diff, dumphtml, dumpserial, edit, loadfile, lock, remove,
503 unlock, upload, viewsource, zip, ziphtml");
505 $properties["Access Log File"] =
506 new _define_commented_optional('ACCESS_LOG', ACCESS_LOG /*"/var/logs/wiki_access.log"*/, "
507 PhpWiki can generate an access_log (in \"NCSA combined log\" format)
508 for you. If you want one, define this to the name of the log file,
509 such as /tmp/wiki_access_log. Preferred is to use SQL access logging as below.
511 Default: empty - no access log file will be generated.");
513 $properties["Access Log SQL"] =
514 new _define_selection(
516 array('0' => 'disable',
518 '2' => 'read + write'), "
519 PhpWiki can read and/or write apache-style mod_log_sql accesslog tables for faster
520 abuse detection and referer lists.
521 See http://www.outoforder.cc/projects/apache/mod_log_sql/docs-2.0/#id2756178
523 If defined (e.g. 1) only read-access is done via SQL.
524 If flag 2 is set, phpwiki also writes. (Default on SQL or ADODB)
525 This must use DATABASE_TYPE = SQL or ADODB.
528 $properties["Compress Output"] =
529 new boolean_define_commented_optional
531 array('' => 'GZIP compress when PhpWiki thinks appropriate.',
532 'false' => 'Never compress output.',
533 'true' => 'Always try to compress output.'),
535 By default PhpWiki will try to have PHP compress it's output
536 before sending it to the browser (if you have a recent enough
537 version of PHP and the action and the browser supports it.)
539 Define COMPRESS_OUTPUT to false to prevent output compression at all.
541 Define COMPRESS_OUTPUT to true to force output compression,
542 even if we think your version of PHP does this in a buggy
545 Leave it undefined to leave the choice up to PhpWiki.");
547 $properties["HTTP Cache Control"] =
548 new _define_selection_optional
550 array('LOOSE' => 'LOOSE',
551 'STRICT' => 'STRICT',
552 'NO_CACHE' => 'NO_CACHE',
553 'ALLOW_STALE' => 'ALLOW_STALE'),
557 This controls how PhpWiki sets the HTTP cache control
558 headers (Expires: and Cache-Control:)
564 <dd>This is roughly the old (pre 1.3.4) behaviour. PhpWiki will
565 instruct proxies and browsers never to cache PhpWiki output.</dd>
568 <dd>Cached pages will be invalidated whenever the database global
569 timestamp changes. This should behave just like NONE (modulo
570 bugs in PhpWiki and your proxies and browsers), except that
571 things will be slightly more efficient.</dd>
574 <dd>Cached pages will be invalidated whenever they are edited,
575 or, if the pages include plugins, when the plugin output could
576 concievably have changed.
578 <p>Behavior should be much like STRICT, except that sometimes
579 wikilinks will show up as undefined (with the question mark)
580 when in fact they refer to (recently) created pages.
581 (Hitting your browsers reload or perhaps shift-reload button
582 should fix the problem.)</p></dd>
585 <dd>Proxies and browsers will be allowed to used stale pages.
586 (The timeout for stale pages is controlled by CACHE_CONTROL_MAX_AGE.)
588 <p>This setting will result in quirky behavior. When you edit a
589 page your changes may not show up until you shift-reload the
592 <p>This setting is generally not advisable, however it may be useful
593 in certain cases (e.g. if your wiki gets lots of page views,
594 and few edits by knowledgable people who won't freak over the quirks.)</p>
597 The default is currently LOOSE.");
599 // FIXME: should be numeric_define_optional
600 $properties["HTTP Cache Control Max Age"] =
601 new numeric_define_optional('CACHE_CONTROL_MAX_AGE', CACHE_CONTROL_MAX_AGE,
603 Maximum page staleness, in seconds.");
605 $properties["Markup Caching"] =
606 new boolean_define_commented_optional
607 ('WIKIDB_NOCACHE_MARKUP',
608 array('false' => 'Enable markup cache',
609 'true' => 'Disable markup cache'),
613 PhpWiki normally caches a preparsed version (i.e. mostly
614 converted to HTML) of the most recent version of each page.
615 (Parsing the wiki-markup takes a fair amount of CPU.)
617 Define WIKIDB_NOCACHE_MARKUP to true to disable the
618 caching of marked-up page content.
620 Note that you can also disable markup caching on a per-page
621 temporary basis by addinging a query arg of '?nocache=1'
622 to the URL to the page. (Use '?nocache=purge' to completely
623 discard the cached version of the page.)
625 You can also purge the cached markup globally by using the
626 \"Purge Markup Cache\" button on the PhpWikiAdministration page.");
628 $properties["Path for PHP Session Support"] =
629 new _define_optional('SESSION_SAVE_PATH', defined('SESSION_SAVE_PATH') ? SESSION_SAVE_PATH : ini_get('session.save_path'), "
630 The login code now uses PHP session support. Usually, the default
631 configuration of PHP is to store the session state information in
632 /tmp. That probably will work fine, but fails e.g. on clustered
633 servers where each server has their own distinct /tmp (this is the
634 case on SourceForge's project web server.) You can specify an
635 alternate directory in which to store state information like so
636 (whatever user your httpd runs as must have read/write permission
639 On USE_DB_SESSION = true you can ignore this.
642 ///////// database selection
644 $properties["Part Two"] =
645 new part('_part2', $SEPARATOR."\n", "
648 Database Configuration
651 $properties["Database Type"] =
652 new _define_selection("DATABASE_TYPE",
653 array('dba' => "dba",
655 'ADODB' => "SQL ADODB",
656 'PDO' => "PDO (php5 only)",
657 'file' => "flatfile",
658 'cvs' => "CVS File handler"), "
659 Select the database backend type:
660 Choose dba (default) to use one of the standard UNIX dba libraries. This is the fastest.
661 Choose ADODB or SQL to use an SQL database with ADODB or PEAR.
662 Choose PDO on php5 to use an SQL database.
663 flatfile is simple and slow.
664 CVS is highly experimental and slow.
665 Recommended is dba or SQL: PEAR or ADODB.");
667 $properties["SQL DSN Setup"] =
668 new unchangeable_variable('_sqldsnstuff', "", "
669 For SQL based backends, specify the database as a DSN
670 The most general form of a DSN looks like:
672 phptype(dbsyntax)://username:password@protocol+hostspec/database?option=value
674 For a MySQL database, the following should work:
676 mysql://user:password@host/databasename
678 To connect over a unix socket, use something like
680 mysql://user:password@unix(/path/to/socket)/databasename
683 DATABASE_DSN = mysql://guest@:/var/lib/mysql/mysql.sock/phpwiki
684 DATABASE_DSN = mysql://guest@localhost/phpwiki
685 DATABASE_DSN = pgsql://localhost/user_phpwiki
688 // Choose ADODB or SQL to use an SQL database with ADODB or PEAR.
689 // Choose dba to use one of the standard UNIX dbm libraries.
691 $properties["SQL Type"] =
692 new _variable_selection('_dsn_sqltype',
693 array('mysql' => "MySQL",
694 'pgsql' => "PostgreSQL",
695 'mssql' => "Microsoft SQL Server",
696 'oci8' => "Oracle 8",
697 'mysqli' => "mysqli (only ADODB)",
698 'mysqlt' => "mysqlt (only ADODB)",
699 'ODBC' => "ODBC (only ADODB or PDO)",
700 'firebird' => "Firebird (only PDO)",
701 'oracle' => "Oracle (only PDO)",
703 SQL DB types. The DSN hosttype.");
705 $properties["SQL User"] =
706 new _variable('_dsn_sqluser', "wikiuser", "
709 $properties["SQL Password"] =
710 new _variable('_dsn_sqlpass', "", "
713 $properties["SQL Database Host"] =
714 new _variable('_dsn_sqlhostorsock', "localhost", "
715 SQL Database Hostname:
717 To connect over a local named socket, use something like
719 unix(/var/lib/mysql/mysql.sock)
722 mysql on Windows via named pipes might need 127.0.0.1");
724 $properties["SQL Database Name"] =
725 new _variable('_dsn_sqldbname', "phpwiki", "
726 SQL Database Name:");
728 $dsn_sqltype = $properties["SQL Type"]->value();
729 $dsn_sqluser = $properties["SQL User"]->value();
730 $dsn_sqlpass = $properties["SQL Password"]->value();
731 $dsn_sqlhostorsock = $properties["SQL Database Host"]->value();
732 $dsn_sqldbname = $properties["SQL Database Name"]->value();
733 $dsn_sqlstring = $dsn_sqltype."://{$dsn_sqluser}:{$dsn_sqlpass}@{$dsn_sqlhostorsock}/{$dsn_sqldbname}";
735 $properties["SQL dsn"] =
736 new unchangeable_define("DATABASE_DSN",
737 "DATABASE_DSN = \"$dsn_sqlstring\"", "
738 Calculated from the settings above:");
740 $properties["Filename / Table name Prefix"] =
741 new _define_commented("DATABASE_PREFIX", DATABASE_PREFIX, "
742 Used by all DB types:
744 Prefix for filenames or table names, e.g. \"phpwiki_\"
746 Currently <b>you MUST EDIT THE SQL file too!</b> (in the schemas/
747 directory because we aren't doing on the fly sql generation
748 during the installation.");
750 $properties["DB Session table"] =
751 new _define_optional("DATABASE_SESSION_TABLE", DATABASE_SESSION_TABLE, "
752 Tablename to store session information. Only supported by SQL backends.
754 A word of warning - any prefix defined above will be prepended to whatever is given here.
758 $temp = !empty($_ENV['TEMP']) ? $_ENV['TEMP'] : "/tmp";
759 $properties["dba directory"] =
760 new _define("DATABASE_DIRECTORY", $temp, "
763 // TODO: list the available methods
764 $properties["dba handler"] =
765 new _define_selection('DATABASE_DBA_HANDLER',
766 array('gdbm' => "Gdbm - GNU database manager (recommended)",
767 'dbm' => "DBM - Redhat default. On sf.net there's dbm and gdbm",
768 'db2' => "DB2 - Sleepycat Software's DB2",
769 'db3' => "DB3 - Sleepycat Software's DB3. Default on Windows but not on every Linux",
770 'db4' => "DB4 - Sleepycat Software's DB4."), "
771 Use 'gdbm', 'dbm', 'db2', 'db3' or 'db4' depending on your DBA handler methods supported: <br > "
772 . (function_exists("dba_handlers") ? join(", ",dba_handlers()) : ""));
774 $properties["dba timeout"] =
775 new numeric_define("DATABASE_TIMEOUT", DATABASE_TIMEOUT, "
776 Recommended values are 10-20 seconds. The more load the server has, the higher the timeout.");
778 $properties["DATABASE_PERSISTENT"] =
779 new boolean_define_commented_optional
780 ('DATABASE_PERSISTENT',
781 array('false' => "Disabled",
782 'true' => "Enabled"), "
783 Use persistent database connections for SQL databases, if the database backend supports it.
784 Not recommended for heavily loaded servers.
789 $properties["Page Revisions"] =
790 new unchangeable_variable('_parttworevisions', "", "
792 Section 2a: Archive Cleanup
793 The next section controls how many old revisions of each page are kept in the database.
795 There are two basic classes of revisions: major and minor. Which
796 class a revision belongs in is determined by whether the author
797 checked the \"this is a minor revision\" checkbox when they saved the
800 There is, additionally, a third class of revisions: author
801 revisions. The most recent non-mergable revision from each distinct
802 author is and author revision.
804 The expiry parameters for each of those three classes of revisions
805 can be adjusted seperately. For each class there are five
806 parameters (usually, only two or three of the five are actually
807 set) which control how long those revisions are kept in the
810 <dt>max_keep:</dt> <dd>If set, this specifies an absolute maximum for the
811 number of archived revisions of that class. This is
812 meant to be used as a safety cap when a non-zero
813 min_age is specified. It should be set relatively high,
814 and it's purpose is to prevent malicious or accidental
815 database overflow due to someone causing an
816 unreasonable number of edits in a short period of time.</dd>
818 <dt>min_age:</dt> <dd>Revisions younger than this (based upon the supplanted
819 date) will be kept unless max_keep is exceeded. The age
820 should be specified in days. It should be a
821 non-negative, real number,</dd>
823 <dt>min_keep:</dt> <dd>At least this many revisions will be kept.</dd>
825 <dt>keep:</dt> <dd>No more than this many revisions will be kept.</dd>
827 <dt>max_age:</dt> <dd>No revision older than this age will be kept.</dd>
829 Supplanted date: Revisions are timestamped at the instant that they
830 cease being the current revision. Revision age is computed using
831 this timestamp, not the edit time of the page.
833 Merging: When a minor revision is deleted, if the preceding
834 revision is by the same author, the minor revision is merged with
835 the preceding revision before it is deleted. Essentially: this
836 replaces the content (and supplanted timestamp) of the previous
837 revision with the content after the merged minor edit, the rest of
838 the page metadata for the preceding version (summary, mtime, ...)
842 // For now the expiration parameters are statically inserted as
843 // an unchangeable property. You'll have to edit the resulting
844 // config file if you really want to change these from the default.
846 $properties["Major Edits: keep minumum days"] =
847 new numeric_define("MAJOR_MIN_KEEP", MAJOR_MIN_KEEP, "
848 Default: Keep at least for unlimited time.
849 Set to 0 to enable archive cleanup");
850 $properties["Minor Edits: keep minumum days"] =
851 new numeric_define("MINOR_MIN_KEEP", MINOR_MIN_KEEP, "
852 Default: Keep at least for unlimited time.
853 Set to 0 to enable archive cleanup");
855 $properties["Major Edits: how many"] =
856 new numeric_define("MAJOR_KEEP", MAJOR_KEEP, "
857 Keep up to 8 major edits");
858 $properties["Major Edits: how many days"] =
859 new numeric_define("MAJOR_MAX_AGE", MAJOR_MAX_AGE, "
860 keep them no longer than a month");
862 $properties["Minor Edits: how many"] =
863 new numeric_define("MINOR_KEEP", MINOR_KEEP, "
864 Keep up to 4 minor edits");
865 $properties["Minor Edits: how many days"] =
866 new numeric_define("MINOR_MAX_AGE", "7", "
867 keep them no longer than a week");
869 $properties["per Author: how many"] =
870 new numeric_define("AUTHOR_KEEP", "8", "
871 Keep the latest contributions of the last 8 authors,");
872 $properties["per Author: how many days"] =
873 new numeric_define("AUTHOR_MAX_AGE", "365", "
875 $properties["per Author: keep minumum days"] =
876 new numeric_define("AUTHOR_MIN_AGE", "7", "
877 Additionally, (in the case of a particularly active page) try to
878 keep the latest contributions of all authors in the last week (even if there are more than eight of them,)");
879 $properties["per Author: max revisions"] =
880 new numeric_define("AUTHOR_MAX_KEEP", "20", "
881 but in no case keep more than twenty unique author revisions.");
883 /////////////////////////////////////////////////////////////////////
885 $properties["Part Three"] =
886 new part('_part3', $SEPARATOR."\n", "
888 Part Three: (optional)
889 Basic User Authentication Setup
892 $properties["Publicly viewable"] =
893 new boolean_define_optional('ALLOW_ANON_USER',
894 array('true' => "true. Permit anonymous view. (Default)",
895 'false' => "false. Force login even on view (strictly private)"), "
896 If ALLOW_ANON_USER is false, you have to login before viewing any page or doing any other action on a page.");
898 $properties["Allow anonymous edit"] =
899 new boolean_define_optional('ALLOW_ANON_EDIT',
900 array('true' => "true. Permit anonymous users to edit. (Default)",
901 'false' => "false. Force login on edit (moderately locked)"), "
902 If ALLOW_ANON_EDIT is false, you have to login before editing or changing any page. See below.");
904 $properties["Allow Bogo Login"] =
905 new boolean_define_optional('ALLOW_BOGO_LOGIN',
906 array('true' => "true. Users may Sign In with any WikiWord, without password. (Default)",
907 'false' => "false. Require stricter authentication."), "
908 If ALLOW_BOGO_LOGIN is false, you may not login with any wikiword username and empty password.
909 If true, users are allowed to create themselves with any WikiWord username. See below.");
911 $properties["Allow User Passwords"] =
912 new boolean_define_optional('ALLOW_USER_PASSWORDS',
913 array('true' => "True user authentication with password checking. (Default)",
914 'false' => "false. Ignore authentication settings below."), "
915 If ALLOW_USER_PASSWORDS is true, the authentication settings below define where and how to
916 check against given username/passwords. For completely security disable BOGO_LOGIN and ANON_EDIT above.");
918 $properties["Allow User Passwords"] =
919 new array_define('USER_AUTH_ORDER', array("PersonalPage", "Db"), "
920 Many different methods can be used to check user's passwords.
921 Try any of these in the given order:
924 <dd>WikiWord username, with no *actual* password checking,
925 although the user will still have to enter one.</dd>
926 <dt>PersonalPage</dt>
927 <dd>Store passwords in the users homepage metadata (simple)</dd>
929 <dd>Use DBAUTH_AUTH_* (see below) with PearDB or ADODB only.</dd>
931 <dd>Authenticate against LDAP_AUTH_HOST with LDAP_BASE_DN.</dd>
933 <dd>Authenticate against IMAP_AUTH_HOST (email account)</dd>
935 <dd>Authenticate against POP3_AUTH_HOST (email account)</dd>
937 <dd>Get username and level from a PHP session variable. (e.g. for gforge)</dd>
939 <dd>Store username:crypted-passwords in .htaccess like files.
940 Use Apache's htpasswd to manage this file.</dd>
942 <dd>Use the protection by the webserver (.htaccess/.htpasswd) (experimental)
943 Enforcing HTTP Auth not yet. Note that the ADMIN_USER should exist also.
944 Using HttpAuth disables all other methods and no userauth sessions are used.</dd>
947 Several of these methods can be used together, in the manner specified by
948 USER_AUTH_POLICY, below. To specify multiple authentication methods,
949 separate the name of each one with colons.
951 USER_AUTH_ORDER = 'PersonalPage : Db'
952 USER_AUTH_ORDER = 'BogoLogin : PersonalPage'
955 $properties["PASSWORD_LENGTH_MINIMUM"] =
956 new numeric_define("PASSWORD_LENGTH_MINIMUM", "6", "
957 For 'security' purposes, you can specify that a password be at least a
958 certain number of characters long. This applies even to the BogoLogin method.
959 Default: 0 (to allow immediate passwordless BogoLogin)");
961 $properties["USER_AUTH_POLICY"] =
962 new _define_selection('USER_AUTH_POLICY',
963 array('first-only' => "first-only - use only the first method in USER_AUTH_ORDER",
964 'old' => "old - ignore USER_AUTH_ORDER (legacy)",
965 'strict' => "strict - check all methods for userid + password (recommended)",
966 'stacked' => "stacked - check all methods for userid, and if found for password"), "
967 The following policies are available for user authentication:
970 <dd>use only the first method in USER_AUTH_ORDER</dd>
972 <dd>ignore USER_AUTH_ORDER and try to use all available
973 methods as in the previous PhpWiki releases (slow)</dd>
975 <dd>check if the user exists for all methods:
976 on the first existing user, try the password.
977 dont try the other methods on failure then</dd>
979 <dd>check the given user - password combination for all
980 methods and return true on the first success.</dd></dl>");
984 $properties["Part Three A"] =
985 new part('_part3a', $SEPARATOR."\n", "
987 Part Three A: (optional)
990 $properties["Group membership"] =
991 new _define_selection("GROUP_METHOD",
992 array('WIKIPAGE' => "WIKIPAGE - List at \"CategoryGroup\". (Slowest, but easiest to maintain)",
993 '"NONE"' => "NONE - Disable group membership (Fastest)",
994 'DB' => "DB - SQL Database, Optionally external. See USERS/GROUPS queries",
995 'FILE' => "Flatfile. See AUTH_GROUP_FILE below.",
996 'LDAP' => "LDAP - See \"LDAP authentication options\" above. (Experimental)"), "
997 Group membership. PhpWiki supports defining permissions for a group as
998 well as for individual users. This defines how group membership information
999 is obtained. Supported values are:
1002 <dd>Disable group membership (Fastest). Note the required quoting.</dd>
1004 <dd>Define groups as list at \"CategoryGroup\". (Slowest, but easiest to maintain)</dd>
1006 <dd>Stored in an SQL database. Optionally external. See USERS/GROUPS queries</dd>
1008 <dd>Flatfile. See AUTH_GROUP_FILE below.</dd>
1010 <dd>LDAP groups. See \"LDAP authentication options\" above and
1011 lib/WikiGroup.php. (experimental)</dd></dl>");
1013 $properties["CATEGORY_GROUP_PAGE"] =
1014 new _define_optional('CATEGORY_GROUP_PAGE', _("CategoryGroup"), "
1015 If GROUP_METHOD = WIKIPAGE:
1017 Page where all groups are listed.");
1019 $properties["AUTH_GROUP_FILE"] =
1020 new _define_optional('AUTH_GROUP_FILE', _("/etc/groups"), "
1021 For GROUP_METHOD = FILE, the file given below is referenced to obtain
1022 group membership information. It should be in the same format as the
1023 standard unix /etc/groups(5) file.");
1025 $properties["Part Three B"] =
1026 new part('_part3b', $SEPARATOR."\n", "
1028 Part Three B: (optional)
1029 External database authentication and authorization.
1031 If USER_AUTH_ORDER includes Db, or GROUP_METHOD = DB, the options listed
1032 below define the SQL queries used to obtain the information out of the
1033 database, and (optionally) store the information back to the DB.");
1035 $properties["DBAUTH_AUTH_DSN"] =
1036 new _define_optional('DBAUTH_AUTH_DSN', $dsn_sqlstring, "
1037 A database DSN to connect to. Defaults to the DSN specified for the Wiki as a whole.");
1039 $properties["User Exists Query"] =
1040 new _define('DBAUTH_AUTH_USER_EXISTS', "SELECT userid FROM user WHERE userid='\$userid'", "
1041 USER/PASSWORD queries:
1043 For USER_AUTH_POLICY=strict and the Db method is required");
1045 $properties["Check Query"] =
1046 new _define_optional('DBAUTH_AUTH_CHECK', "SELECT IF(passwd='\$password',1,0) AS ok FROM user WHERE userid='\$userid'", "
1048 Check to see if the supplied username/password pair is OK
1050 Plaintext passwords: (DBAUTH_AUTH_CRYPT_METHOD = plain)<br>
1051 ; DBAUTH_AUTH_CHECK = \"SELECT IF(passwd='\$password',1,0) AS ok FROM user WHERE userid='\$userid'\"
1053 database-hashed passwords (more secure):<br>
1054 ; DBAUTH_AUTH_CHECK = \"SELECT IF(passwd=PASSWORD('\$password'),1,0) AS ok FROM user WHERE userid='\$userid'\"");
1056 $properties["Crypt Method"] =
1057 new _define_selection_optional
1058 ('DBAUTH_AUTH_CRYPT_METHOD',
1059 array('plain' => 'plain',
1060 'crypt' => 'crypt'), "
1061 If you want to use Unix crypt()ed passwords, you can use DBAUTH_AUTH_CHECK
1062 to get the password out of the database with a simple SELECT query, and
1063 specify DBAUTH_AUTH_USER_EXISTS and DBAUTH_AUTH_CRYPT_METHOD:
1065 ; DBAUTH_AUTH_CHECK = \"SELECT passwd FROM user where userid='\$userid'\" <br>
1066 ; DBAUTH_AUTH_CRYPT_METHOD = crypt");
1068 $properties["Update the user's authentication credential"] =
1069 new _define('DBAUTH_AUTH_UPDATE', "UPDATE user SET passwd='\$password' WHERE userid='\$userid'", "
1070 If this is not defined but DBAUTH_AUTH_CHECK is, then the user will be unable to update their
1073 Plaintext passwords:<br>
1074 DBAUTH_AUTH_UPDATE = \"UPDATE user SET passwd='\$password' WHERE userid='\$userid'\"<br>
1075 Database-hashed passwords:<br>
1076 DBAUTH_AUTH_UPDATE = \"UPDATE user SET passwd=PASSWORD('\$password') WHERE userid='\$userid'\"");
1078 $properties["Allow the user to create their own account"] =
1079 new _define_optional('DBAUTH_AUTH_CREATE', "INSERT INTO user SET passwd=PASSWORD('\$password'),userid='\$userid'", "
1080 If this is empty, Db users cannot subscribe by their own.");
1082 $properties["USER/PREFERENCE queries"] =
1083 new _define_optional('DBAUTH_PREF_SELECT', "SELECT prefs FROM user WHERE userid='\$userid'", "
1084 If you choose to store your preferences in an external database, enable
1085 the following queries. Note that if you choose to store user preferences
1086 in the 'user' table, only registered users get their prefs from the database,
1087 self-created users do not. Better to use the special 'pref' table.
1089 The prefs field stores the serialized form of the user's preferences array,
1090 to ease the complication of storage.
1092 DBAUTH_PREF_SELECT = \"SELECT prefs FROM user WHERE userid='\$userid'\"
1093 DBAUTH_PREF_SELECT = \"SELECT prefs FROM pref WHERE userid='\$userid'\"
1096 $properties["Update the user's preferences"] =
1097 new _define_optional('DBAUTH_PREF_UPDATE', "UPDATE user SET prefs='\$pref_blob' WHERE userid='\$userid'", "
1098 Note that REPLACE works only with mysql and destroy all other columns!
1100 Mysql: DBAUTH_PREF_UPDATE = \"REPLACE INTO pref SET prefs='\$pref_blob',userid='\$userid'\"");
1102 $properties["USERS/GROUPS queries"] =
1103 new _define_optional('DBAUTH_IS_MEMBER', "SELECT user FROM user WHERE user='\$userid' AND group='\$groupname'", "
1104 You can define 1:n or n:m user<=>group relations, as you wish.
1106 Sample configurations:
1108 only one group per user (1:n):<br>
1109 DBAUTH_IS_MEMBER = \"SELECT user FROM user WHERE user='\$userid' AND group='\$groupname'\"<br>
1110 DBAUTH_GROUP_MEMBERS = \"SELECT user FROM user WHERE group='\$groupname'\"<br>
1111 DBAUTH_USER_GROUPS = \"SELECT group FROM user WHERE user='\$userid'\"<br>
1112 multiple groups per user (n:m):<br>
1113 DBAUTH_IS_MEMBER = \"SELECT userid FROM member WHERE userid='\$userid' AND groupname='\$groupname'\"<br>
1114 DBAUTH_GROUP_MEMBERS = \"SELECT DISTINCT userid FROM member WHERE groupname='\$groupname'\"<br>
1115 DBAUTH_USER_GROUPS = \"SELECT groupname FROM member WHERE userid='\$userid'\"<br>");
1116 $properties["DBAUTH_GROUP_MEMBERS"] =
1117 new _define_optional('DBAUTH_GROUP_MEMBERS', "SELECT user FROM user WHERE group='\$groupname'", "");
1118 $properties["DBAUTH_USER_GROUPS"] =
1119 new _define_optional('DBAUTH_USER_GROUPS', "SELECT group FROM user WHERE user='\$userid'", "");
1121 if (function_exists('ldap_connect')) {
1123 $properties["LDAP AUTH Host"] =
1124 new _define_optional('LDAP_AUTH_HOST', "ldap://localhost:389", "
1125 If USER_AUTH_ORDER contains Ldap:
1127 The LDAP server to connect to. Can either be a hostname, or a complete
1128 URL to the server (useful if you want to use ldaps or specify a different
1131 $properties["LDAP BASE DN"] =
1132 new _define_optional('LDAP_BASE_DN', "ou=mycompany.com,o=My Company", "
1133 The organizational or domain BASE DN: e.g. \"dc=mydomain,dc=com\".
1135 Note: ou=Users and ou=Groups are used for GroupLdap Membership
1136 Better use LDAP_OU_USERS and LDAP_OU_GROUP with GROUP_METHOD=LDAP.");
1138 $properties["LDAP SET OPTION"] =
1139 new _define_optional('LDAP_SET_OPTION', "LDAP_OPT_PROTOCOL_VERSION=3:LDAP_OPT_REFERRALS=0", "
1140 Some LDAP servers need some more options, such as the Windows Active
1141 Directory Server. Specify the options (as allowed by the PHP LDAP module)
1142 and their values as NAME=value pairs separated by colons.");
1144 $properties["LDAP AUTH USER"] =
1145 new _define_optional('LDAP_AUTH_USER', "CN=ldapuser,ou=Users,o=Development,dc=mycompany.com", "
1146 DN to initially bind to the LDAP server as. This is needed if the server doesn't
1147 allow anonymous queries. (Windows Active Directory Server)");
1149 $properties["LDAP AUTH PASSWORD"] =
1150 new _define_optional('LDAP_AUTH_PASSWORD', "secret", "
1151 Password to use to initially bind to the LDAP server, as the DN
1152 specified in the LDAP_AUTH_USER option (above).");
1154 $properties["LDAP SEARCH FIELD"] =
1155 new _define_optional('LDAP_SEARCH_FIELD', "uid", "
1156 If you want to match usernames against an attribute other than uid,
1157 specify it here. Default: uid
1159 e.g.: LDAP_SEARCH_FIELD = sAMAccountName");
1161 $properties["LDAP OU USERS"] =
1162 new _define_optional('LDAP_OU_USERS', "ou=Users", "
1163 If you have an organizational unit for all users, define it here.
1164 This narrows the search, and is needed for LDAP group membership (if GROUP_METHOD=LDAP)
1165 Default: ou=Users");
1167 $properties["LDAP OU GROUP"] =
1168 new _define_optional('LDAP_OU_GROUP', "ou=Groups", "
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");
1174 } else { // function_exists('ldap_connect')
1176 $properties["LDAP Authentication"] =
1177 new unchangeable_define('LDAP Authentication', "
1178 ; If USER_AUTH_ORDER contains Ldap:
1180 ; The LDAP server to connect to. Can either be a hostname, or a complete
1181 ; URL to the server (useful if you want to use ldaps or specify a different
1183 ;LDAP_AUTH_HOST = \"ldap://localhost:389\"
1185 ; The organizational or domain BASE DN: e.g. \"dc=mydomain,dc=com\".
1187 ; Note: ou=Users and ou=Groups are used for GroupLdap Membership
1188 ; Better use LDAP_OU_USERS and LDAP_OU_GROUP with GROUP_METHOD=LDAP.
1189 ;LDAP_BASE_DN = \"ou=Users,o=Development,dc=mycompany.com\"
1191 ; Some LDAP servers need some more options, such as the Windows Active
1192 ; Directory Server. Specify the options (as allowed by the PHP LDAP module)
1193 ; and their values as NAME=value pairs separated by colons.
1194 ; LDAP_SET_OPTION = \"LDAP_OPT_PROTOCOL_VERSION=3:LDAP_OPT_REFERRALS=0\"
1196 ; DN to initially bind to the LDAP server as. This is needed if the server doesn't
1197 ; allow anonymous queries. (Windows Active Directory Server)
1198 ; LDAP_AUTH_USER = \"CN=ldapuser,ou=Users,o=Development,dc=mycompany.com\"
1200 ; Password to use to initially bind to the LDAP server, as the DN
1201 ; specified in the LDAP_AUTH_USER option (above).
1202 ; LDAP_AUTH_PASSWORD = secret
1204 ; If you want to match usernames against an attribute other than uid,
1205 ; specify it here. Default: uid
1206 ; LDAP_SEARCH_FIELD = sAMAccountName
1208 ; If you have an organizational unit for all users, define it here.
1209 ; This narrows the search, and is needed for LDAP group membership (if GROUP_METHOD=LDAP)
1211 ; LDAP_OU_USERS = ou=Users
1213 ; If you have an organizational unit for all groups, define it here.
1214 ; This narrows the search, and is needed for LDAP group membership (if GROUP_METHOD=LDAP)
1215 ; The entries in this ou must have a gidNumber and cn attribute.
1216 ; Default: ou=Groups
1217 ; LDAP_OU_GROUP = ou=Groups", "
1218 ; Ignored. No LDAP support in this php. configure --with-ldap");
1221 if (function_exists('imap_open')) {
1223 $properties["IMAP Auth Host"] =
1224 new _define_optional('IMAP_AUTH_HOST', 'localhost:143/imap/notls', "
1225 If USER_AUTH_ORDER contains IMAP:
1227 The IMAP server to check usernames from. Defaults to localhost.
1229 Some IMAP_AUTH_HOST samples:
1230 localhost, localhost:143/imap/notls,
1231 localhost:993/imap/ssl/novalidate-cert (SuSE refuses non-SSL conections)");
1233 } else { // function_exists('imap_open')
1235 $properties["IMAP Authentication"] =
1236 new unchangeable_define('IMAP_AUTH_HOST',"
1237 ; If USER_AUTH_ORDER contains IMAP:
1238 ; The IMAP server to check usernames from. Defaults to localhost.
1240 ; Some IMAP_AUTH_HOST samples:
1241 ; localhost, localhost:143/imap/notls,
1242 ; localhost:993/imap/ssl/novalidate-cert (SuSE refuses non-SSL conections)
1243 ;IMAP_AUTH_HOST = localhost:143/imap/notls", "
1244 Ignored. No IMAP support in this php. configure --with-imap");
1248 $properties["POP3 Authentication"] =
1249 new _define_optional('POP3_AUTH_HOST', 'localhost:110', "
1250 If USER_AUTH_ORDER contains POP3:
1252 The POP3 mail server to check usernames and passwords against.");
1253 $properties["File Authentication"] =
1254 new _define_optional('AUTH_USER_FILE', '/etc/shadow', "
1255 If USER_AUTH_ORDER contains File:
1257 File to read for authentication information.
1258 Popular choices are /etc/shadow and /etc/httpd/.htpasswd");
1260 $properties["File Storable?"] =
1261 new boolean_define_commented_optional
1262 ('AUTH_USER_FILE_STORABLE',
1263 array('false' => "Disabled",
1264 'true' => "Enabled"), "
1265 Defines whether the user is able to change their own password via PhpWiki.
1266 Note that this means that the webserver user must be able to write to the
1267 file specified in AUTH_USER_FILE.");
1269 $properties["Session Auth USER"] =
1270 new _define_optional('AUTH_SESS_USER', 'userid', "
1271 If USER_AUTH_ORDER contains Session:
1273 Name of the session variable which holds the already authenticated username.
1274 Sample: 'userid', 'user[username]', 'user->username'");
1276 $properties["Session Auth LEVEL"] =
1277 new numeric_define('AUTH_SESS_LEVEL', '2', "
1278 Which level will the user be? 1 = Bogo or 2 = Pass");
1280 /////////////////////////////////////////////////////////////////////
1282 $properties["Part Four"] =
1283 new part('_part4', $SEPARATOR."\n", "
1286 Page appearance and layout");
1288 $properties["Theme"] =
1289 new _define_selection_optional('THEME',
1290 array('default' => "default",
1291 'MacOSX' => "MacOSX",
1292 'smaller' => 'smaller',
1293 'Wordpress'=> 'Wordpress',
1294 'Portland' => "Portland",
1295 'Sidebar' => "Sidebar",
1297 'wikilens' => 'wikilens (Ratings)',
1298 'shamino_com' => 'shamino_com',
1299 'SpaceWiki' => "SpaceWiki",
1300 'Hawaiian' => "Hawaiian",
1301 'MonoBook' => 'MonoBook [experimental]',
1302 'blog' => 'blog [experimental]',
1306 Most of the page appearance is controlled by files in the theme
1309 There are a number of pre-defined themes shipped with PhpWiki.
1310 Or you may create your own (e.g. by copying and then modifying one of
1320 THEME = wikilens (Ratings)
1328 THEME = MonoBook (WikiPedia) [experimental. MSIE problems]
1329 THEME = blog (Kubrick) [experimental. Several links missing]
1332 $properties["Character Set"] =
1333 new _define_optional('CHARSET', 'iso-8859-1', "
1334 Select a valid charset name to be inserted into the xml/html pages,
1335 and to reference links to the stylesheets (css). For more info see:
1336 http://www.iana.org/assignments/character-sets. Note that PhpWiki
1337 has been extensively tested only with the latin1 (iso-8859-1)
1340 If you change the default from iso-8859-1 PhpWiki may not work
1341 properly and it will require code modifications. However, character
1342 sets similar to iso-8859-1 may work with little or no modification
1343 depending on your setup. The database must also support the same
1344 charset, and of course the same is true for the web browser. (Some
1345 work is in progress hopefully to allow more flexibility in this
1346 area in the future).");
1348 $properties["Language"] =
1349 new _define_selection_optional('DEFAULT_LANGUAGE',
1350 array('en' => "English",
1351 '' => "<empty> (user-specific)",
1354 'nl' => "Nederlands",
1359 'zh' => "Chinese"), "
1360 Select your language/locale - default language is \"en\" for English.
1361 Other languages available:<pre>
1362 English \"en\" (English - HomePage)
1363 German \"de\" (Deutsch - StartSeite)
1364 French \"fr\" (Fran~is - Accueil)
1365 Dutch \"nl\" (Nederlands - ThuisPagina)
1366 Spanish \"es\" (Espa~l - P~inaPrincipal)
1367 Swedish \"sv\" (Svenska - Framsida)
1368 Italian \"it\" (Italiano - PaginaPrincipale)
1369 Japanese \"ja\" (Japanese - ~~~~~~)
1370 Chinese \"zh\" (Chinese)
1372 If you set DEFAULT_LANGUAGE to the empty string, your systems default language
1373 (as determined by the applicable environment variables) will be
1376 $properties["Wiki Page Source"] =
1377 new _define_optional('WIKI_PGSRC', 'pgsrc', "
1378 WIKI_PGSRC -- specifies the source for the initial page contents of
1379 the Wiki. The setting of WIKI_PGSRC only has effect when the wiki is
1380 accessed for the first time (or after clearing the database.)
1381 WIKI_PGSRC can either name a directory or a zip file. In either case
1382 WIKI_PGSRC is scanned for files -- one file per page.
1384 // Default (old) behavior:
1385 define('WIKI_PGSRC', 'pgsrc');
1387 define('WIKI_PGSRC', 'wiki.zip');
1388 define('WIKI_PGSRC',
1389 '../Logs/Hamwiki/hamwiki-20010830.zip');
1393 $properties["Default Wiki Page Source"] =
1394 new _define('DEFAULT_WIKI_PGSRC', 'pgsrc', "
1395 DEFAULT_WIKI_PGSRC is only used when the language is *not* the
1396 default (English) and when reading from a directory: in that case
1397 some English pages are inserted into the wiki as well.
1398 DEFAULT_WIKI_PGSRC defines where the English pages reside.
1400 FIXME: is this really needed?
1403 $properties["Generic Pages"] =
1404 new array_variable('GenericPages', array('ReleaseNotes', 'SteveWainstead', 'TestPage'), "
1405 These are the pages which will get loaded from DEFAULT_WIKI_PGSRC.
1407 FIXME: is this really needed? Cannot we just copy these pages into
1408 the localized pgsrc?
1414 $properties["Part Five"] =
1415 new part('_part5', $SEPARATOR."\n", "
1420 $properties["Allowed Protocols"] =
1421 new list_define('ALLOWED_PROTOCOLS', 'http|https|mailto|ftp|news|nntp|ssh|gopher', "
1422 Allowed protocols for links - be careful not to allow \"javascript:\"
1423 URL of these types will be automatically linked.
1424 within a named link [name|uri] one more protocol is defined: phpwiki");
1426 $properties["Inline Images"] =
1427 new list_define('INLINE_IMAGES', 'png|jpg|gif', "
1428 URLs ending with the following extension should be inlined as images.
1429 Scripts shoud not be allowed!");
1431 $properties["WikiName Regexp"] =
1432 new _define('WIKI_NAME_REGEXP', "(?<![[:alnum:]])(?:[[:upper:]][[:lower:]]+){2,}(?![[:alnum:]])", "
1433 Perl regexp for WikiNames (\"bumpy words\")
1434 (?<!..) & (?!...) used instead of '\b' because \b matches '_' as well");
1436 $properties["Subpage Separator"] =
1437 new _define_optional('SUBPAGE_SEPARATOR', '"/"', "
1438 One character which seperates pages from subpages. Defaults to '/', but '.' or ':' were also used.",
1439 "onchange=\"validate_ereg('Sorry, \'%s\' must be a single character. Currently only :, / or .', '^[/:.]$', 'SUBPAGE_SEPARATOR', this);\""
1442 $properties["InterWiki Map File"] =
1443 new _define('INTERWIKI_MAP_FILE', 'lib/interwiki.map', "
1444 InterWiki linking -- wiki-style links to other wikis on the web
1446 The map will be taken from a page name InterWikiMap.
1447 If that page is not found (or is not locked), or map
1448 data can not be found in it, then the file specified
1449 by INTERWIKI_MAP_FILE (if any) will be used.");
1451 $properties["WARN_NONPUBLIC_INTERWIKIMAP"] =
1452 new boolean_define('WARN_NONPUBLIC_INTERWIKIMAP',
1453 array('true' => "true",
1454 'false' => "false"), "
1455 Display a warning if the internal lib/interwiki.map is used, and
1456 not the public InterWikiMap page. This map is not readable from outside.");
1459 $properties["Keyword Link Regexp"] =
1460 new _define_optional('KEYWORDS', '\"Category* OR Topic*\"', "
1461 Search term used for automatic page classification by keyword extraction.
1463 Any links on a page to pages whose names match this search
1464 will be used keywords in the keywords html meta tag. This is an aid to
1465 classification by search engines. The value of the match is
1466 used as the keyword.
1468 The default behavior is to match Category* or Topic* links.");
1470 $properties["Author and Copyright Site Navigation Links"] =
1471 new _define_commented_optional('COPYRIGHTPAGE_TITLE', "GNU General Public License", "
1473 These will be inserted as <link rel> tags in the html header of
1474 every page, for search engines and for browsers like Mozilla which
1475 take advantage of link rel site navigation.
1477 If you have your own copyright and contact information pages change
1478 these as appropriate.");
1480 $properties["COPYRIGHTPAGE URL"] =
1481 new _define_commented_optional('COPYRIGHTPAGE_URL', "http://www.gnu.org/copyleft/gpl.html#SEC1", "
1483 Other useful alternatives to consider:
1485 COPYRIGHTPAGE_TITLE = \"GNU Free Documentation License\"
1486 COPYRIGHTPAGE_URL = \"http://www.gnu.org/copyleft/fdl.html\"
1487 COPYRIGHTPAGE_TITLE = \"Creative Commons License 2.0\"
1488 COPYRIGHTPAGE_URL = \"http://creativecommons.org/licenses/by/2.0/\"</pre>
1489 See http://creativecommons.org/learn/licenses/ for variations");
1491 $properties["AUTHORPAGE_TITLE"] =
1492 new _define_commented_optional('AUTHORPAGE_TITLE', "The PhpWiki Programming Team", "
1493 Default Author Names");
1494 $properties["AUTHORPAGE_URL"] =
1495 new _define_commented_optional('AUTHORPAGE_URL', "http://phpwiki.org/ThePhpWikiProgrammingTeam", "
1496 Default Author URL");
1498 $properties["TOC_FULL_SYNTAX"] =
1499 new boolean_define_optional
1501 array('true' => "Enabled",
1502 'false' => "Disabled"), "
1503 Allow full markup in headers to be parsed by the CreateToc plugin.
1505 If false you may not use WikiWords or [] links or any other markup in
1506 headers in pages with the CreateToc plugin. But if false the parsing is
1507 faster and more stable.");
1509 $properties["ENABLE_MARKUP_COLOR"] =
1510 new boolean_define_optional
1511 ('ENABLE_MARKUP_COLOR',
1512 array('true' => "Enabled",
1513 'false' => "Disabled"), "
1514 If disabled the %color=... %% syntax will be disabled. Since 1.3.11
1517 $properties["ENABLE_MARKUP_TEMPLATE"] =
1518 new boolean_define_optional
1519 ('ENABLE_MARKUP_TEMPLATE',
1520 array('true' => "Enabled",
1521 'false' => "Disabled"), "
1522 Enable mediawiki-style {{TemplatePage|vars=value|...}} syntax. Since 1.3.11
1523 Default: undefined. Enabled automatically on the MonoBook theme if undefined.");
1527 $properties["Part Six"] =
1528 new part('_part6', $SEPARATOR."\n", "
1530 Part Six (optional):
1531 URL options -- you can probably skip this section.
1533 For a pretty wiki (no index.php in the url) set a seperate DATA_PATH.");
1535 global $HTTP_SERVER_VARS;
1536 $properties["Server Name"] =
1537 new _define_commented_optional('SERVER_NAME', $HTTP_SERVER_VARS['SERVER_NAME'], "
1538 Canonical name of the server on which this PhpWiki resides.");
1540 $properties["Server Port"] =
1541 new numeric_define_commented('SERVER_PORT', $HTTP_SERVER_VARS['SERVER_PORT'], "
1542 Canonical httpd port of the server on which this PhpWiki resides.",
1543 "onchange=\"validate_ereg('Sorry, \'%s\' is no valid port number.', '^[0-9]+$', 'SERVER_PORT', this);\"");
1545 $properties["Script Name"] =
1546 new _define_commented_optional('SCRIPT_NAME', $scriptname, "
1547 Relative URL (from the server root) of the PhpWiki script.");
1549 $properties["Data Path"] =
1550 new _define_commented_optional('DATA_PATH', dirname($scriptname), "
1551 URL of the PhpWiki install directory. (You only need to set this
1552 if you've moved index.php out of the install directory.) This can
1553 be either a relative URL (from the directory where the top-level
1554 PhpWiki script is) or an absolute one.");
1557 $properties["PhpWiki Install Directory"] =
1558 new _define_commented_optional('PHPWIKI_DIR', dirname(__FILE__), "
1559 Path to the PhpWiki install directory. This is the local
1560 filesystem counterpart to DATA_PATH. (If you have to set
1561 DATA_PATH, your probably have to set this as well.) This can be
1562 either an absolute path, or a relative path interpreted from the
1563 directory where the top-level PhpWiki script (normally index.php)
1566 $properties["Use PATH_INFO"] =
1567 new _define_selection_optional_commented('USE_PATH_INFO',
1568 array('' => 'automatic',
1569 'true' => 'use PATH_INFO',
1570 'false' => 'do not use PATH_INFO'), "
1571 PhpWiki will try to use short urls to pages, eg
1572 http://www.example.com/index.php/HomePage
1573 If you want to use urls like
1574 http://www.example.com/index.php?pagename=HomePage
1575 then define 'USE_PATH_INFO' as false by uncommenting the line below.
1576 NB: If you are using Apache >= 2.0.30, then you may need to to use
1577 the directive \"AcceptPathInfo On\" in your Apache configuration file
1578 (or in an appropriate <.htaccess> file) for the short urls to work:
1579 See http://httpd.apache.org/docs-2.0/mod/core.html#acceptpathinfo
1581 See also http://phpwiki.sourceforge.net/phpwiki/PrettyWiki for more ideas
1582 on prettifying your urls.
1584 Default: PhpWiki will try to divine whether use of PATH_INFO
1585 is supported in by your webserver/PHP configuration, and will
1586 use PATH_INFO if it thinks that is possible.");
1588 $properties["Virtual Path"] =
1589 new _define_commented_optional('VIRTUAL_PATH', '/SomeWiki', "
1590 VIRTUAL_PATH is the canonical URL path under which your your wiki
1591 appears. Normally this is the same as dirname(SCRIPT_NAME), however
1592 using e.g. seperate starter scripts, apaches mod_actions (or mod_rewrite),
1593 you can make it something different.
1595 If you do this, you should set VIRTUAL_PATH here or in the starter scripts.
1597 E.g. your phpwiki might be installed at at /scripts/phpwiki/index.php,
1598 but you've made it accessible through eg. /wiki/HomePage.
1600 One way to do this is to create a directory named 'wiki' in your
1601 server root. The directory contains only one file: an .htaccess
1602 file which reads something like:
1604 Action x-phpwiki-page /scripts/phpwiki/index.php
1605 SetHandler x-phpwiki-page
1606 DirectoryIndex /scripts/phpwiki/index.php
1608 In that case you should set VIRTUAL_PATH to '/wiki'.
1610 (VIRTUAL_PATH is only used if USE_PATH_INFO is true.)
1615 $properties["Part Seven"] =
1616 new part('_part7', $SEPARATOR."\n", "
1620 Miscellaneous settings
1623 $properties["Strict Mailable Pagedumps"] =
1624 new boolean_define_optional
1625 ('STRICT_MAILABLE_PAGEDUMPS',
1626 array('false' => "binary",
1627 'true' => "quoted-printable"),
1629 If you define this to true, (MIME-type) page-dumps (either zip dumps,
1630 or \"dumps to directory\" will be encoded using the quoted-printable
1631 encoding. If you're actually thinking of mailing the raw page dumps,
1632 then this might be useful, since (among other things,) it ensures
1633 that all lines in the message body are under 80 characters in length.
1635 Also, setting this will cause a few additional mail headers
1636 to be generated, so that the resulting dumps are valid
1637 RFC 2822 e-mail messages.
1639 Probably, you can just leave this set to false, in which case you get
1640 raw ('binary' content-encoding) page dumps.");
1642 $properties["HTML Dump Filename Suffix"] =
1643 new _define_optional('HTML_DUMP_SUFFIX', ".html", "
1644 Here you can change the filename suffix used for XHTML page dumps.
1645 If you don't want any suffix just comment this out.");
1647 $properties["Default local Dump Directory"] =
1648 new _define_optional('DEFAULT_DUMP_DIR', "/tmp/wikidump", "
1649 Specify the default directory for local backups.");
1651 $properties["Default local HTML Dump Directory"] =
1652 new _define_optional('HTML_DUMP_DIR', "/tmp/wikidumphtml", "
1653 Specify the default directory for local XHTML dumps.");
1655 $properties["Pagename of Recent Changes"] =
1656 new _define_optional('RECENT_CHANGES', 'RecentChanges', "
1657 Page name of RecentChanges page. Used for RSS Auto-discovery.");
1659 $properties["Disable HTTP Redirects"] =
1660 new boolean_define_commented_optional
1661 ('DISABLE_HTTP_REDIRECT',
1662 array('false' => 'Enable HTTP Redirects',
1663 'true' => 'Disable HTTP Redirects'),
1665 (You probably don't need to touch this.)
1667 PhpWiki uses HTTP redirects for some of it's functionality.
1668 (e.g. after saving changes, PhpWiki redirects your browser to
1669 view the page you just saved.)
1671 Some web service providers (notably free European Lycos) don't seem to
1672 allow these redirects. (On Lycos the result in an \"Internal Server Error\"
1673 report.) In that case you can set DISABLE_HTTP_REDIRECT to true.
1674 (In which case, PhpWiki will revert to sneakier tricks to try to
1675 redirect the browser...)");
1677 $properties["Disable GETIMAGESIZE"] =
1678 new boolean_define_commented_optional
1679 ('DISABLE_GETIMAGESIZE',
1680 array('false' => 'Enable',
1681 'true' => 'Disable'), "
1682 Set GETIMAGESIZE to disabled, if your php fails to calculate the size on
1683 inlined images, or you don't want to disable too small images to be inlined.
1685 Per default too small ploaded or external images are not displayed,
1686 to prevent from external 1 pixel spam.");
1688 $properties["EDITING_POLICY"] =
1689 new _define_optional('EDITING_POLICY', "EditingPolicy", "
1690 An interim page which gets displayed on every edit attempt, if it exists.");
1692 $properties["ENABLE_MODERATEDPAGE_ALL"] =
1693 new boolean_define_commented_optional
1694 ('ENABLE_MODERATEDPAGE_ALL',
1695 array('false' => 'Disable',
1696 'true' => 'Enable'), "
1699 $properties["FORTUNE_DIR"] =
1700 new _define_commented_optional('FORTUNE_DIR', "/usr/share/fortune", "
1702 $properties["DBADMIN_USER"] =
1703 new _define_commented_optional('DBADMIN_USER', "", "
1705 $properties["DBADMIN_PASSWD"] =
1706 new _define_commented_optional('DBADMIN_PASSWD', "", "
1708 $properties["USE_EXTERNAL_HTML2PDF"] =
1709 new _define_commented_optional('USE_EXTERNAL_HTML2PDF', "htmldoc --quiet --format pdf14 --no-toc --no-title %s", "
1711 $properties["BABYCART_PATH"] =
1712 new _define_commented_optional('BABYCART_PATH', "/usr/local/bin/babycart", "
1715 $properties["Part Seven A"] =
1716 new part('_part7a', $SEPARATOR."\n", "
1720 Cached Plugin Settings. (pear Cache)
1723 $properties["pear Cache USECACHE"] =
1724 new boolean_define_optional('PLUGIN_CACHED_USECACHE',
1725 array('true' => 'Enabled',
1726 'false' => 'Disabled'), "
1727 Enable or disable pear caching of plugins.");
1728 $properties["pear Cache Database Container"] =
1729 new _define_selection_optional('PLUGIN_CACHED_DATABASE',
1730 array('file' => 'file'), "
1731 Curently only file is supported.
1732 db, trifile and imgfile might be supported, but you must hack that by yourself.");
1734 $properties["pear Cache cache directory"] =
1735 new _define_commented_optional('PLUGIN_CACHED_CACHE_DIR', "/tmp/cache", "
1736 Should be writable to the webserver.");
1737 $properties["pear Cache Filename Prefix"] =
1738 new _define_optional('PLUGIN_CACHED_FILENAME_PREFIX', "phpwiki", "");
1739 $properties["pear Cache HIGHWATER"] =
1740 new numeric_define_optional('PLUGIN_CACHED_HIGHWATER', "4194304", "
1741 Garbage collection parameter.");
1742 $properties["pear Cache LOWWATER"] =
1743 new numeric_define_optional('PLUGIN_CACHED_LOWWATER', "3145728", "
1744 Garbage collection parameter.");
1745 $properties["pear Cache MAXLIFETIME"] =
1746 new numeric_define_optional('PLUGIN_CACHED_MAXLIFETIME', "2592000", "
1747 Garbage collection parameter.");
1748 $properties["pear Cache MAXARGLEN"] =
1749 new numeric_define_optional('PLUGIN_CACHED_MAXARGLEN', "1000", "
1750 max. generated url length.");
1751 $properties["pear Cache FORCE_SYNCMAP"] =
1752 new boolean_define_optional('PLUGIN_CACHED_FORCE_SYNCMAP',
1753 array('true' => 'Enabled',
1754 'false' => 'Disabled'), "");
1755 $properties["pear Cache IMGTYPES"] =
1756 new list_define('PLUGIN_CACHED_IMGTYPES', "png|gif|gd|gd2|jpeg|wbmp|xbm|xpm", "
1757 Handle those image types via GD handles. Check your GD supported image types.");
1759 $end = "\n".$SEPARATOR."\n";
1762 text_from_dist("_MAGIC_CLOSE_FILE");
1764 // end of configuration options
1765 ///////////////////////////////
1766 // begin class definitions
1769 * A basic config-dist.ini configuration line in the form of a variable.
1770 * (not needed anymore, we have only defines)
1772 * Produces a string in the form "$name = value;"
1774 * $WikiNameRegexp = "value";
1778 var $config_item_name;
1784 function _variable($config_item_name, $default_value, $description = '', $jscheck = '') {
1785 $this->config_item_name = $config_item_name;
1787 $description = text_from_dist($config_item_name);
1788 $this->description = $description;
1789 if (defined($config_item_name)
1790 and !preg_match("/(selection|boolean)/", get_class($this))
1791 and !preg_match("/(SCRIPT_NAME|VIRTUAL_PATH)/", $config_item_name))
1792 $this->default_value = constant($config_item_name); // ignore given default value
1793 elseif ($config_item_name == $default_value)
1794 $this->default_value = '';
1796 $this->default_value = $default_value;
1797 $this->jscheck = $jscheck;
1798 if (preg_match("/variable/i",get_class($this)))
1799 $this->prefix = "\$";
1800 elseif (preg_match("/ini_set/i",get_class($this)))
1801 $this->prefix = "ini_get: ";
1807 global $HTTP_POST_VARS;
1808 if (isset($HTTP_POST_VARS[$this->config_item_name]))
1809 return $HTTP_POST_VARS[$this->config_item_name];
1811 return $this->default_value;
1814 function _config_format($value) {
1816 $v = $this->get_config_item_name();
1817 // handle arrays: a|b --> a['b']
1818 if (strpos($v, '|')) {
1819 list($a, $b) = explode('|', $v);
1820 $v = sprintf("%s['%s']", $a, $b);
1822 if (preg_match("/[\"']/", $value))
1823 $value = '"' . $value . '"';
1824 return sprintf("%s = \"%s\"", $v, $value);
1827 function get_config_item_name() {
1828 return $this->config_item_name;
1831 function get_config_item_id() {
1832 return str_replace('|', '-', $this->config_item_name);
1835 function get_config_item_header() {
1836 if (strchr($this->config_item_name,'|')) {
1837 list($var,$param) = explode('|',$this->config_item_name);
1838 return "<b>" . $this->prefix . $var . "['" . $param . "']</b><br />";
1840 elseif ($this->config_item_name[0] != '_')
1841 return "<b>" . $this->prefix . $this->config_item_name . "</b><br />";
1846 function _get_description() {
1847 return $this->description;
1850 function _get_config_line($posted_value) {
1851 return "\n" . $this->_config_format($posted_value);
1854 function get_config($posted_value) {
1855 $d = stripHtml($this->_get_description());
1856 $d = str_replace("\n", "\n; ", $d) . $this->_get_config_line($posted_value) ."\n";
1860 function get_instructions($title) {
1862 $i = "<h3>" . $title . "</h3>\n " . nl2p($this->_get_description()) . "\n";
1863 return "<tr>\n<td width=\"$tdwidth\" class=\"instructions\">\n" . $i . "</td>\n";
1866 function get_html() {
1867 $size = strlen($this->default_value) > 45 ? 90 : 50;
1868 return $this->get_config_item_header() .
1869 "<input type=\"text\" size=\"$50\" name=\"" . $this->get_config_item_name() . "\" value=\"" . htmlspecialchars($this->default_value) . "\" " .
1870 $this->jscheck . " />" . "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: green\">Input accepted.</p>";
1874 class unchangeable_variable
1876 function _config_format($value) {
1879 // function get_html() { return false; }
1880 function get_html() {
1881 return $this->get_config_item_header() .
1882 "<em>Not editable.</em>" .
1883 "<pre>" . $this->default_value."</pre>";
1885 function _get_config_line($posted_value) {
1886 if ($this->description)
1888 return "${n}".$this->default_value;
1890 function get_instructions($title) {
1892 $i = "<h3>" . $title . "</h3>\n " . nl2p($this->_get_description()) . "\n";
1893 // $i .= "<em>Not editable.</em><br />\n<pre>" . $this->default_value."</pre>";
1894 return '<tr><td width="100%" class="unchangeable-variable-top" colspan="2">'."\n".$i."</td></tr>\n"
1895 . '<tr style="border-top: none;"><td class="unchangeable-variable-left" width="'.$tdwidth.'"> </td>';
1899 class unchangeable_define
1900 extends unchangeable_variable {
1901 function _config_format($value) {
1905 class unchangeable_ini_set
1906 extends unchangeable_variable {
1907 function _config_format($value) {
1912 class _variable_selection
1915 global $HTTP_POST_VARS;
1916 if (!empty($HTTP_POST_VARS[$this->config_item_name]))
1917 return $HTTP_POST_VARS[$this->config_item_name];
1919 list($option, $label) = each($this->default_value);
1923 function get_html() {
1924 $output = $this->get_config_item_header();
1925 $output .= '<select name="' . $this->get_config_item_name() . "\">\n";
1926 /* The first option is the default */
1927 $values = $this->default_value;
1928 if (defined($this->get_config_item_name()))
1929 $this->default_value = constant($this->get_config_item_name());
1931 $this->default_value = null;
1932 while(list($option, $label) = each($values)) {
1933 if (!is_null($this->default_value) and $this->default_value === $option)
1934 $output .= " <option value=\"$option\" selected=\"selected\">$label</option>\n";
1936 $output .= " <option value=\"$option\">$label</option>\n";
1938 $output .= "</select>\n";
1946 function _config_format($value) {
1947 return sprintf("%s = \"%s\"", $this->get_config_item_name(), $value);
1949 function _get_config_line($posted_value) {
1950 if ($this->description)
1952 if ($posted_value == '')
1953 return "${n};" . $this->_config_format("");
1955 return "${n}" . $this->_config_format($posted_value);
1957 function get_html() {
1958 $size = strlen($this->default_value) > 45 ? 90 : 50;
1959 return $this->get_config_item_header()
1960 . "<input type=\"text\" size=\"$size\" name=\"" . htmlentities($this->get_config_item_name())
1961 . "\" value=\"" . htmlentities($this->default_value) . "\" {$this->jscheck} />"
1962 . "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: green\">Input accepted.</p>";
1966 class _define_commented
1968 function _get_config_line($posted_value) {
1969 if ($this->description)
1971 if ($posted_value == $this->default_value)
1972 return "${n};" . $this->_config_format($posted_value);
1973 elseif ($posted_value == '')
1974 return "${n};" . $this->_config_format("");
1976 return "${n}" . $this->_config_format($posted_value);
1981 * We don't use _optional anymore, because INI-style config's don't need that.
1982 * IniConfig.php does the optional logic now.
1983 * But we use _optional for config-default.ini options
1985 class _define_commented_optional
1986 extends _define_commented { }
1988 class _define_optional
1991 class _define_notempty
1993 function get_html() {
1994 $s = $this->get_config_item_header()
1995 . "<input type=\"text\" size=\"50\" name=\"" . $this->get_config_item_name()
1996 . "\" value=\"" . $this->default_value . "\" {$this->jscheck} />";
1997 if (empty($this->default_value))
1998 return $s . "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: red\">Cannot be empty.</p>";
2000 return $s . "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: green\">Input accepted.</p>";
2004 class _variable_commented
2006 function _get_config_line($posted_value) {
2007 if ($this->description)
2009 if ($posted_value == $this->default_value)
2010 return "${n};" . $this->_config_format($posted_value);
2011 elseif ($posted_value == '')
2012 return "${n};" . $this->_config_format("");
2014 return "${n}" . $this->_config_format($posted_value);
2018 class numeric_define
2021 function numeric_define($config_item_name, $default_value, $description = '', $jscheck = '') {
2022 $this->_define($config_item_name, $default_value, $description, $jscheck);
2024 $this->jscheck = "onchange=\"validate_ereg('Sorry, \'%s\' is not an integer.', '^[-+]?[0-9]+$', '" . $this->get_config_item_name() . "', this);\"";
2026 function _config_format($value) {
2027 //return sprintf("define('%s', %s);", $this->get_config_item_name(), $value);
2028 return sprintf("%s = %s", $this->get_config_item_name(), $value);
2030 function _get_config_line($posted_value) {
2031 if ($this->description)
2033 if ($posted_value == '')
2034 return "${n};" . $this->_config_format('0');
2036 return "${n}" . $this->_config_format($posted_value);
2040 class numeric_define_optional
2041 extends numeric_define {}
2043 class numeric_define_commented
2044 extends numeric_define {
2045 function _get_config_line($posted_value) {
2046 if ($this->description)
2048 if ($posted_value == $this->default_value)
2049 return "${n};" . $this->_config_format($posted_value);
2050 elseif ($posted_value == '')
2051 return "${n};" . $this->_config_format('0');
2053 return "${n}" . $this->_config_format($posted_value);
2057 class _define_selection
2058 extends _variable_selection {
2059 function _config_format($value) {
2060 return sprintf("%s = %s", $this->get_config_item_name(), $value);
2062 function _get_config_line($posted_value) {
2063 return _define::_get_config_line($posted_value);
2065 function get_html() {
2066 return _variable_selection::get_html();
2070 class _define_selection_optional
2071 extends _define_selection { }
2073 class _variable_selection_optional
2074 extends _variable_selection { }
2076 class _define_selection_optional_commented
2077 extends _define_selection_optional {
2078 function _get_config_line($posted_value) {
2079 if ($this->description)
2081 if ($posted_value == $this->default_value)
2082 return "${n};" . $this->_config_format($posted_value);
2083 elseif ($posted_value == '')
2084 return "${n};" . $this->_config_format("");
2086 return "${n}" . $this->_config_format($posted_value);
2090 class _define_password
2093 function _define_password($config_item_name, $default_value, $description = '', $jscheck = '') {
2094 if ($config_item_name == $default_value) $default_value = '';
2095 $this->_define($config_item_name, $default_value, $description, $jscheck);
2097 $this->jscheck = "onchange=\"validate_ereg('Sorry, \'%s\' cannot be empty.', '^.+$', '"
2098 . $this->get_config_item_name() . "', this);\"";
2100 function _get_config_line($posted_value) {
2101 if ($this->description)
2103 if ($posted_value == '') {
2104 $p = "${n};" . $this->_config_format("");
2105 $p .= "\n; If you used the passencrypt.php utility to encode the password";
2106 $p .= "\n; then uncomment this line:";
2107 $p .= "\n;ENCRYPTED_PASSWD = true";
2110 if (function_exists('crypt')) {
2111 $salt_length = max(CRYPT_SALT_LENGTH,
2115 16 * CRYPT_BLOWFISH);
2116 // generate an encrypted password
2117 $crypt_pass = crypt($posted_value, rand_ascii($salt_length));
2118 $p = "${n}" . $this->_config_format($crypt_pass);
2119 return $p . "\nENCRYPTED_PASSWD = true";
2121 $p = "${n}" . $this->_config_format($posted_value);
2122 $p .= "\n; Encrypted passwords cannot be used:";
2123 $p .= "\n; 'function crypt()' not available in this version of php";
2124 $p .= "\nENCRYPTED_PASSWD = false";
2129 function get_html() {
2130 return _variable_password::get_html();
2134 class _define_password_optional
2135 extends _define_password { }
2137 class _variable_password
2139 function _variable_password($config_item_name, $default_value, $description = '', $jscheck = '') {
2140 if ($config_item_name == $default_value) $default_value = '';
2141 $this->_define($config_item_name, $default_value, $description, $jscheck);
2143 $this->jscheck = "onchange=\"validate_ereg('Sorry, \'%s\' cannot be empty.', '^.+$', '" . $this->get_config_item_name() . "', this);\"";
2145 function get_html() {
2146 global $HTTP_POST_VARS, $HTTP_GET_VARS;
2147 $s = $this->get_config_item_header();
2148 if (isset($HTTP_POST_VARS['create']) or isset($HTTP_GET_VARS['create'])) {
2149 $new_password = random_good_password();
2150 $this->default_value = $new_password;
2151 $s .= "Created password: <strong>$new_password</strong><br /> <br />";
2153 // dont re-encrypt already encrypted passwords
2154 $value = $this->value();
2155 $encrypted = !empty($GLOBALS['properties']["Encrypted Passwords"]) and
2156 $GLOBALS['properties']["Encrypted Passwords"]->value();
2159 $s .= "<input type=\"". ($encrypted ? "text" : "password") . "\" name=\"" . $this->get_config_item_name()
2160 . "\" value=\"" . $value . "\" {$this->jscheck} />"
2161 . " <input type=\"submit\" name=\"create\" value=\"Create Random Password\" />";
2163 $s .= "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: red\">Cannot be empty.</p>";
2164 elseif (strlen($this->default_value) < 4)
2165 $s .= "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: red\">Must be longer than 4 chars.</p>";
2167 $s .= "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: green\">Input accepted.</p>";
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 $list_values = join("|", $list_values);
2179 return _variable::_get_config_line($list_values);
2181 function get_html() {
2182 $list_values = explode("|", $this->default_value);
2183 $rows = max(3, count($list_values) +1);
2184 $list_values = join("\n", $list_values);
2185 $ta = $this->get_config_item_header();
2186 $ta .= "<textarea cols=\"18\" rows=\"". $rows ."\" name=\"".$this->get_config_item_name()."\" {$this->jscheck}>";
2187 $ta .= $list_values . "</textarea>";
2188 $ta .= "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: green\">Input accepted.</p>";
2195 function _get_config_line($posted_value) {
2196 $list_values = preg_split("/[\s,]+/", $posted_value, -1, PREG_SPLIT_NO_EMPTY);
2197 $list_values = join("|", $list_values);
2198 return _variable::_get_config_line($list_values);
2200 function get_html() {
2201 $list_values = explode("|", $this->default_value);
2202 $rows = max(3, count($list_values) +1);
2203 $list_values = join("\n", $list_values);
2204 $ta = $this->get_config_item_header();
2205 $ta .= "<textarea cols=\"18\" rows=\"". $rows ."\" name=\"".$this->get_config_item_name()."\" {$this->jscheck}>";
2206 $ta .= $list_values . "</textarea>";
2207 $ta .= "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: green\">Input accepted.</p>";
2212 class array_variable
2214 function _config_format($value) {
2215 return sprintf("%s = \"%s\"", $this->get_config_item_name(),
2216 is_array($value) ? join(':', $value) : $value);
2218 function _get_config_line($posted_value) {
2219 // split the phrase by any number of commas or space characters,
2220 // which include " ", \r, \t, \n and \f
2221 $list_values = preg_split("/[\s,]+/", $posted_value, -1, PREG_SPLIT_NO_EMPTY);
2222 if (!empty($list_values)) {
2223 $list_values = "'".join("', '", $list_values)."'";
2224 return "\n" . $this->_config_format($list_values);
2226 return "\n;" . $this->_config_format('');
2228 function get_html() {
2229 $list_values = join("\n", $this->default_value);
2230 $rows = max(3, count($this->default_value) +1);
2231 $ta = $this->get_config_item_header();
2232 $ta .= "<textarea cols=\"18\" rows=\"". $rows ."\" name=\"".$this->get_config_item_name()."\" {$this->jscheck}>";
2233 $ta .= $list_values . "</textarea>";
2234 $ta .= "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: green\">Input accepted.</p>";
2241 function _config_format($value) {
2242 return sprintf("%s = \"%s\"", $this->get_config_item_name(),
2243 is_array($value) ? join(' : ', $value) : $value);
2245 function _get_config_line($posted_value) {
2246 // split the phrase by any number of commas or space characters,
2247 // which include " ", \r, \t, \n and \f
2248 $list_values = preg_split("/[\s,:]+/", $posted_value, -1, PREG_SPLIT_NO_EMPTY);
2249 if (!empty($list_values)) {
2250 $list_values = "'".join("' : '", $list_values)."'";
2251 return "\n" . $this->_config_format($list_values);
2253 return "\n;" . $this->_config_format('');
2255 function get_html() {
2256 if (!$this->default_value)
2257 $this->default_value = array();
2258 elseif (is_string($this->default_value))
2259 $this->default_value = preg_split("/[\s,:]+/", $this->default_value, -1, PREG_SPLIT_NO_EMPTY);
2260 $list_values = join(" : \n", $this->default_value);
2261 $rows = max(3, count($this->default_value) + 1);
2262 $ta = $this->get_config_item_header();
2263 $ta .= "<textarea cols=\"18\" rows=\"". $rows ."\" name=\"".$this->get_config_item_name()."\" {$this->jscheck}>";
2264 $ta .= $list_values . "</textarea>";
2265 $ta .= "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: green\">Input accepted.</p>";
2274 global $HTTP_POST_VARS;
2275 if ($v = $HTTP_POST_VARS[$this->config_item_name])
2278 return ini_get($this->get_config_item_name);
2281 function _config_format($value) {
2282 return sprintf("ini_set('%s', '%s');", $this->get_config_item_name(), $value);
2284 function _get_config_line($posted_value) {
2285 if ($posted_value && ! $posted_value == $this->default_value)
2286 return "\n" . $this->_config_format($posted_value);
2288 return "\n;" . $this->_config_format($this->default_value);
2293 class boolean_define
2295 function _get_config_line($posted_value) {
2296 if ($this->description)
2298 return "${n}" . $this->_config_format($posted_value);
2300 function _config_format($value) {
2301 if (strtolower(trim($value)) == 'false')
2303 return sprintf("%s = %s", $this->get_config_item_name(),
2304 (bool)$value ? 'true' : 'false');
2306 function get_html() {
2307 $output = $this->get_config_item_header();
2308 $output .= '<select name="' . $this->get_config_item_name() . "\" {$this->jscheck}>\n";
2309 $values = $this->default_value;
2310 if (defined($this->get_config_item_name()))
2311 $this->default_value = constant($this->get_config_item_name());
2313 $this->default_value = null;
2314 list($option, $label) = each($values);
2315 $output .= " <option value=\"$option\" selected=\"selected\">$label</option>\n";
2317 /* There can usually, only be two options, there can be
2318 * three options in the case of a boolean_define_commented_optional */
2319 while (list($option, $label) = each($values)) {
2320 if (!is_null($this->default_value) and $this->default_value === $option)
2321 $output .= " <option value=\"$option\" selected=\"selected\">$label</option>\n";
2323 $output .= " <option value=\"$option\">$label</option>\n";
2325 $output .= "</select>\n";
2330 class boolean_define_optional
2331 extends boolean_define {}
2333 class boolean_define_commented
2334 extends boolean_define {
2335 function _get_config_line($posted_value) {
2336 if ($this->description)
2338 list($default_value, $label) = each($this->default_value);
2339 if ($posted_value == $default_value)
2340 return "${n};" . $this->_config_format($posted_value);
2341 elseif ($posted_value == '')
2342 return "${n};" . $this->_config_format('false');
2344 return "${n}" . $this->_config_format($posted_value);
2348 class boolean_define_commented_optional
2349 extends boolean_define_commented {}
2353 function value () { return; }
2354 function get_config($posted_value) {
2355 $d = stripHtml($this->_get_description());
2357 return "\n".$SEPARATOR . str_replace("\n", "\n; ", $d) ."\n".$this->default_value;
2359 function get_instructions($title) {
2360 $id = preg_replace("/\W/","",$this->config_item_name);
2361 $group_name = preg_replace("/\W/","",$title);
2362 $i = "<tr class=\"header\" id=\"$id\">\n<td class=\"part\" width=\"100%\" colspan=\"2\" bgcolor=\"#eeeeee\">\n";
2363 $i .= "<h2>" . $title . "</h2>\n " . nl2p($this->_get_description()) ."\n";
2364 $i .= "<p><a href=\"javascript:toggle_group('$id')\" id=\"{$id}_text\">Hide options.</a></p>";
2365 return $i ."</td>\n";
2367 function get_html() {
2372 // html utility functions
2373 function nl2p($text) {
2374 preg_match_all("@\s*(<pre>.*?</pre>|<dl>.*?</dl>|.*?(?=\n\n|<pre>|<dl>|$))@s",
2375 $text, $m, PREG_PATTERN_ORDER);
2378 foreach ($m[1] as $par) {
2379 if (!($par = trim($par)))
2381 if (!preg_match('/^<(pre|dl)>/', $par))
2382 $par = "<p>$par</p>";
2388 function text_from_dist($var) {
2389 static $distfile = 0;
2393 $sep = (substr(PHP_OS,0,3) == 'WIN' ? '\\' : '/');
2394 $distfile = dirname(__FILE__) . $sep . "config" . $sep . "config-dist.ini";
2395 $f = fopen($distfile, "r");
2397 if ($var == '_MAGIC_CLOSE_FILE') {
2401 // if all vars would be in natural order as in the config-dist this would not be needed.
2406 if (preg_match("/^; \w/", $s)) {
2407 $par .= (substr($s,2) . " ");
2408 } elseif (preg_match("/^;\s*$/", $s)) {
2411 if (preg_match("/^;?".preg_quote($var)."\s*=/", $s))
2413 if (preg_match("/^\s*$/", $s)) // new paragraph
2419 function stripHtml($text) {
2420 $d = str_replace("<pre>", "", $text);
2421 $d = str_replace("</pre>", "", $d);
2422 $d = str_replace("<dl>", "", $d);
2423 $d = str_replace("</dl>", "", $d);
2424 $d = str_replace("<dt>", "", $d);
2425 $d = str_replace("</dt>", "", $d);
2426 $d = str_replace("<dd>", "", $d);
2427 $d = str_replace("</dd>", "", $d);
2428 $d = str_replace("<p>", "", $d);
2429 $d = str_replace("</p>", "", $d);
2430 //restore html entities into characters
2431 // http://www.php.net/manual/en/function.htmlentities.php
2432 $trans = get_html_translation_table (HTML_ENTITIES);
2433 $trans = array_flip ($trans);
2434 $d = strtr($d, $trans);
2438 include_once(dirname(__FILE__)."/lib/stdlib.php");
2441 // Function to create better user passwords (much larger keyspace),
2442 // suitable for user passwords.
2443 // Sequence of random ASCII numbers, letters and some special chars.
2444 // Note: There exist other algorithms for easy-to-remember passwords.
2445 function random_good_password ($minlength = 5, $maxlength = 8) {
2447 // assume ASCII ordering (not valid on EBCDIC systems!)
2448 $valid_chars = "!#%&+-.0123456789=@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz";
2449 $start = ord($valid_chars);
2450 $end = ord(substr($valid_chars,-1));
2452 if (function_exists('mt_rand')) // mersenne twister
2453 $length = mt_rand($minlength, $maxlength);
2454 else // the usually bad glibc rand()
2455 $length = rand($minlength, $maxlength);
2456 while ($length > 0) {
2457 if (function_exists('mt_rand'))
2458 $newchar = mt_rand($start, $end);
2460 $newchar = rand($start, $end);
2461 if (! strrpos($valid_chars,$newchar) ) continue; // skip holes
2462 $newpass .= sprintf("%c", $newchar);
2469 function printArray($a) {
2470 echo "<hr />\n<pre>\n";
2472 echo "\n</pre>\n<hr />\n";
2475 // end of class definitions
2476 /////////////////////////////
2477 // begin auto generation code
2479 if (!function_exists('is_a')) {
2480 function is_a($object, $class) {
2481 $class = strtolower($class);
2482 return (get_class($object) == $class) or is_subclass_of($object, $class);
2487 if (!empty($HTTP_POST_VARS['action'])
2488 and $HTTP_POST_VARS['action'] == 'make_config'
2489 and !empty($HTTP_POST_VARS['ADMIN_USER'])
2490 and !empty($HTTP_POST_VARS['ADMIN_PASSWD'])
2494 $timestamp = date ('dS of F, Y H:i:s');
2497 ; This is a local configuration file for PhpWiki.
2498 ; It was automatically generated by the configurator script
2499 ; on the $timestamp.
2504 $posted = $GLOBALS['HTTP_POST_VARS'];
2505 /*if (defined('DEBUG'))
2506 printArray($GLOBALS['HTTP_POST_VARS']);*/
2508 foreach ($properties as $option_name => $a) {
2509 $posted_value = stripslashes($posted[$a->config_item_name]);
2510 $config .= $properties[$option_name]->get_config($posted_value);
2515 if (is_writable($fs_config_file)) {
2516 // We first check if the config-file exists.
2517 if (file_exists($fs_config_file)) {
2518 // We make a backup copy of the file
2519 $new_filename = preg_replace('/\.ini$/', '-' . time() . '.ini', $fs_config_file);
2520 if (@copy($fs_config_file, $new_filename)) {
2521 $fp = @fopen($fs_config_file, 'w');
2524 $fp = @fopen($fs_config_file, 'w');
2532 fputs($fp, $config);
2534 echo "<p>The configuration was written to <code><b>$config_file</b></code>.</p>\n";
2535 if ($new_filename) {
2536 echo "<p>A backup was made to <code><b>$new_filename</b></code>.</p>\n";
2538 ; //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";
2541 echo "<p>The configuration file could <b>not</b> be written.<br />\n",
2542 " You should copy the above configuration to a file, ",
2543 "and manually save it as <code><b>config/config.ini</b></code>.</p>\n";
2546 echo "<hr />\n<p>Here's the configuration file based on your answers:</p>\n";
2547 echo "<form method=\"get\" action=\"", $configurator, "\">\n";
2548 echo "<textarea id='config-output' readonly='readonly' style='width:100%;' rows='30' cols='100'>\n";
2549 echo htmlentities($config);
2550 echo "</textarea></form>\n";
2553 echo "<p>To make any corrections, <a href=\"configurator.php\">edit the settings again</a>.</p>\n";
2555 } else { // first time or create password
2556 $posted = $GLOBALS['HTTP_POST_VARS'];
2557 // No action has been specified - we make a form.
2560 <form action="',$configurator,'" method="post">
2561 <input type="hidden" name="action" value="make_config" />
2562 <table cellpadding="4" cellspacing="0">
2565 while (list($property, $obj) = each($properties)) {
2566 echo $obj->get_instructions($property);
2567 if ($h = $obj->get_html()) {
2568 if (defined('DEBUG') and DEBUG) $h = get_class($obj) . "<br />\n" . $h;
2569 echo "<td>".$h."</td>\n";
2576 <p><input type="submit" id="submit" value="Save ',$config_file,'" /> <input type="reset" value="Clear" /></p>