3 * Copyright 2002,2003,2005,2008-2010 $ThePhpWikiProgrammingTeam
4 * Copyright 2002 Martin Geisler <gimpster@gimpster.com>
5 * Copyright 2008-2009 Marc-Etienne Vargenau, Alcatel-Lucent
7 * This file is part of PhpWiki.
8 * Parts of this file were based on PHPWeather's configurator.php file.
9 * http://sourceforge.net/projects/phpweather/
11 * PhpWiki is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * PhpWiki is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License along
22 * with PhpWiki; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 * Starts automatically the first time by IniConfig("config/config.ini")
28 * if it doesn't exist.
31 * o Initial expand ?show=_part1 (the part id)
32 * o read config-default.ini and use this as default_values
33 * o commented / optional: non-default values should not be commented!
34 * default values if optional can be omitted.
35 * o validate input (fix javascript, add POST checks)
36 * o start this automatically the first time
39 * 1.3.11 TODO: (or 1.3.12?)
40 * o parse_ini_file("config-dist.ini") for the commented vars
41 * o check automatically for commented and optional vars
42 * o fix _optional, to ignore existing config.ini and only use config-default.ini values
43 * o mixin class for commented
44 * o fix SQL quotes, AUTH_ORDER quotes and file forward slashes
45 * o posted values validation, extend js validation for sane DB values
46 * o read config-dist.ini into sections, comments, and optional/required settings
48 * A file config/config.ini will be automatically generated, if writable.
50 * NOTE: If you have a starterscript outside PHPWIKI_DIR but no
51 * config/config.ini yet (very unlikely!), you must define DATA_PATH in the
52 * starterscript, otherwise the webpath to configurator is unknown, and
53 * subsequent requests will fail. (POST to save the INI)
56 global $HTTP_POST_VARS, $tdwidth;
57 if (empty($_SERVER)) $_SERVER =& $GLOBALS['HTTP_SERVER_VARS'];
58 if (empty($_GET)) $_GET =& $GLOBALS['HTTP_GET_VARS'];
59 if (empty($_ENV)) $_ENV =& $GLOBALS['HTTP_ENV_VARS'];
60 if (empty($_POST)) $_POST =& $GLOBALS['HTTP_POST_VARS'];
62 if (empty($configurator))
63 $configurator = "configurator.php";
64 if (!strstr($_SERVER["SCRIPT_NAME"], $configurator) and defined('DATA_PATH'))
65 $configurator = DATA_PATH . "/" . $configurator;
66 $scriptname = str_replace('configurator.php', 'index.php', $_SERVER["SCRIPT_NAME"]);
67 if (strstr($_SERVER["SCRIPT_NAME"], "/php")) { // cgi got this different
68 if (defined('DATA_PATH'))
69 $scriptname = DATA_PATH . "/index.php";
71 $scriptname = str_replace('configurator.php', 'index.php', $_SERVER["PHP_SELF"]);
75 $config_file = (substr(PHP_OS, 0, 3) == 'WIN') ? 'config\\config.ini' : 'config/config.ini';
76 $fs_config_file = dirname(__FILE__) . (substr(PHP_OS, 0, 3) == 'WIN' ? '\\' : '/') . $config_file;
77 if (isset($_POST['create'])) header('Location: ' . $configurator . '?show=_part1&create=1#create');
79 // helpers from lib/WikiUser/HttpAuth.php
80 if (!function_exists('_http_user')) {
84 $_SERVER = $GLOBALS['HTTP_SERVER_VARS'];
85 if (!empty($_SERVER['PHP_AUTH_USER']))
86 return array($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']);
87 if (!empty($_SERVER['REMOTE_USER']))
88 return array($_SERVER['REMOTE_USER'], $_SERVER['PHP_AUTH_PW']);
89 if (!empty($GLOBALS['HTTP_ENV_VARS']['REMOTE_USER']))
90 return array($GLOBALS['HTTP_ENV_VARS']['REMOTE_USER'],
91 $GLOBALS['HTTP_ENV_VARS']['PHP_AUTH_PW']);
92 if (!empty($GLOBALS['REMOTE_USER']))
93 return array($GLOBALS['REMOTE_USER'], $GLOBALS['PHP_AUTH_PW']);
96 if (!empty($_SERVER['HTTP_AUTHORIZATION'])) {
97 list($userid, $passwd) = explode(':', base64_decode(substr($_SERVER['HTTP_AUTHORIZATION'], 6)));
98 return array($userid, $passwd);
100 return array('', '');
103 function _http_logout()
105 if (!isset($_SERVER))
106 $_SERVER =& $GLOBALS['HTTP_SERVER_VARS'];
107 // maybe we should random the realm to really force a logout. but the next login will fail.
108 header('WWW-Authenticate: Basic realm="' . WIKI_NAME . '"');
109 if (strstr(php_sapi_name(), 'apache'))
110 header('HTTP/1.0 401 Unauthorized');
112 header("Status: 401 Access Denied"); //IIS and CGI need that
113 unset($GLOBALS['REMOTE_USER']);
114 unset($_SERVER['PHP_AUTH_USER']);
115 unset($_SERVER['PHP_AUTH_PW']);
117 trigger_error("Permission denied. Require ADMIN_USER.", E_USER_ERROR);
122 // If config.ini exists, we require ADMIN_USER access by faking HttpAuth.
123 // So nobody can see or reset the password(s).
124 if (file_exists($fs_config_file)) {
125 // Require admin user
126 if (!defined('ADMIN_USER') or !defined('ADMIN_PASSWD')) {
127 if (!function_exists("IniConfig")) {
128 include_once 'lib/prepend.php';
129 include_once 'lib/IniConfig.php';
131 IniConfig($fs_config_file);
133 if (!defined('ADMIN_USER') or ADMIN_USER == '') {
134 trigger_error("Configuration problem:\nADMIN_USER not defined in \"$fs_config_file\".\n"
135 . "Cannot continue: You have to fix that manually.", E_USER_ERROR);
139 list($admin_user, $admin_pw) = _http_user();
140 //$required_user = ADMIN_USER;
141 if (empty($admin_user) or $admin_user != ADMIN_USER) {
145 if (ENCRYPTED_PASSWD) {
146 if (crypt($admin_pw, ADMIN_PASSWD) != ADMIN_PASSWD)
148 } elseif ($admin_pw != ADMIN_PASSWD) {
152 if (!function_exists("IniConfig")) {
153 include_once 'lib/prepend.php';
154 include_once 'lib/IniConfig.php';
156 $def_file = (substr(PHP_OS, 0, 3) == 'WIN') ? 'config\\config-default.ini' : 'config/config-default.ini';
157 $fs_def_file = dirname(__FILE__) . (substr(PHP_OS, 0, 3) == 'WIN' ? '\\' : '/') . $def_file;
158 IniConfig($fs_def_file);
165 <meta charset="UTF-8" />
166 <title>Configuration tool for PhpWiki <?php echo $config_file ?></title>
167 <style type="text/css" media="screen">
169 /* TABLE { border: thin solid black } */
171 font-family: Verdana, Arial, Helvetica, sans-serif;
180 border: thin solid black
188 background-color: #eeeeee;
197 background-color: #eeeeee;
202 background-color: #ffffee;
203 width: <?php echo $tdwidth ?>px;
207 td.unchangeable-variable-top {
209 background-color: #ffffee;
213 td.unchangeable-variable-left {
215 background-color: #ffffee;
221 <script type="text/javascript">
223 function update(accepted, error, value, output) {
224 var msg = document.getElementById(output);
226 /* MSIE 5.0 fails here */
227 if (msg && msg.innerHTML) {
228 msg.innerHTML = "<span color=\"green\">Input accepted.</span>";
232 while ((index = error.indexOf("%s")) > -1) {
233 error = error.substring(0, index) + value + error.substring(index + 2);
236 msg.innerHTML = "<span color=\"red\">" + error + "</span>";
240 if (submit = document.getElementById('submit')) submit.disabled = accepted ? false : true;
243 function validate(error, value, output, field) {
244 update(field.value == value, error, field.value, output);
247 function validate_ereg(error, ereg, output, field) {
248 var regex = new RegExp(ereg);
249 update(regex.test(field.value), error, field.value, output);
252 function validate_range(error, low, high, empty_ok, output, field) {
253 update((empty_ok == 1 && field.value == "") ||
254 (field.value >= low && field.value <= high),
255 error, field.value, output);
258 function toggle_group(id) {
259 var text = document.getElementById(id + "_text");
261 if (text.innerHTML == "Hide options.") {
263 text.innerHTML = "Show options.";
265 text.innerHTML = "Hide options.";
268 var rows = document.getElementsByTagName('tr');
271 for (i = 0; i < rows.length; i++) {
273 if (tr.className == 'header' && tr.id == id) {
278 for (; i < rows.length; i++) {
280 if (tr.className == 'header')
282 tr.className = do_hide ? 'hidden' : 'nonhidden';
287 // Hide all groups. We do this via JavaScript to avoid
288 // hiding the groups if JavaScript is not supported...
289 var rows = document.getElementsByTagName('tr');
290 var show = '<?php echo $_GET["show"] ?>';
291 for (var i = 0; i < rows.length; i++) {
293 if (tr.className == 'header')
294 if (!show || tr.id != show)
298 // Select text in textarea upon focus
299 var area = document.getElementById('config-output');
301 var listener = { handleEvent:function (e) {
304 area.addEventListener('focus', listener, false);
311 <body onload="do_init();">
313 <h1>Configuration for PhpWiki <?php echo $config_file ?></h1>
316 Using this configurator.php is experimental!<br/>
317 On any configuration problems, please edit the resulting config.ini manually.
322 //define('DEBUG', 1);
324 * The Configurator is a php script to aid in the configuration of PhpWiki.
325 * Parts of this file were based on PHPWeather's configurator.php file.
326 * http://sourceforge.net/projects/phpweather/
328 * TO CHANGE THE CONFIGURATION OF YOUR PHPWIKI, DO *NOT* MODIFY THIS FILE!
329 * more instructions go here
333 * * eval config.ini to get the actual settings.
336 //////////////////////////////
337 // begin configuration options
340 * Notes for the description parameter of $property:
342 * - Descriptive text will be changed into comments (preceeded by ; )
343 * for the final output to config.ini.
345 * - Only a limited set of html is allowed: pre, dl dt dd; it will be
346 * stripped from the final output.
348 * - Line breaks and spacing will be preserved for the final output.
350 * - Double line breaks are automatically converted to paragraphs
351 * for the html version of the descriptive text.
353 * - Double-quotes and dollar signs in the descriptive text must be
354 * escaped: \" and \$. Instead of escaping double-quotes you can use
355 * single (') quotes for the enclosing quotes.
357 * - Special characters like < and > must use html entities,
358 * they will be converted back to characters for the final output.
361 $SEPARATOR = ";=========================================================================";
364 ; This is the main configuration file for PhpWiki in INI-style format.
365 ; Note that certain characters are used as comment char and therefore
366 ; these entries must be in double-quotes. Such as \":\", \";\", \",\" and \"|\"
367 ; Take special care for DBAUTH_ sql statements. (Part 3a)
369 ; This file is divided into several parts: Each one has different configuration
370 ; settings you can change; in all cases the default should work on your system,
371 ; however, we recommend you tailor things to your particular setting.
372 ; Here undefined definitions get defined by config-default.ini settings.
375 // Detect not here listed configs:
376 // for x in `perl -ne 'print $1,"\n" if /^;(\w+) =/' config/config-dist.ini`; do \
377 // grep \'$x\' configurator.php >/dev/null || echo $x ; done
379 $properties["Part Zero"] =
380 new part('_part0', $SEPARATOR . "\n", "
381 Part Zero: (optional)
382 Latest Development and Tricky Options");
384 if (defined('INCLUDE_PATH'))
385 $include_path = INCLUDE_PATH;
387 if (substr(PHP_OS, 0, 3) == 'WIN') {
388 $include_path = dirname(__FILE__) . ';' . ini_get('include_path');
389 if (strchr(ini_get('include_path'), '/'))
390 $include_path = strtr($include_path, '\\', '/');
392 $include_path = dirname(__FILE__) . ':' . ini_get('include_path');
396 $properties["PHP include_path"] =
397 new _define('INCLUDE_PATH', $include_path);
399 // TODO: Convert this to a checkbox row as in tests/unit/test.php
400 $properties["DEBUG"] =
401 new numeric_define_optional('DEBUG', DEBUG);
403 $properties["ENABLE_EDIT_TOOLBAR"] =
404 new boolean_define_commented_optional('ENABLE_EDIT_TOOLBAR');
406 $properties["JS_SEARCHREPLACE"] =
407 new boolean_define_commented_optional('JS_SEARCHREPLACE');
409 // TESTME: use config-default: = false
410 $properties["ENABLE_DOUBLECLICKEDIT"] =
411 new boolean_define_commented_optional('ENABLE_DOUBLECLICKEDIT');
413 $properties["ENABLE_WYSIWYG"] =
414 new boolean_define_commented_optional('ENABLE_WYSIWYG');
416 $properties["WYSIWYG_BACKEND"] =
417 new _define_selection(
419 array('Wikiwyg' => 'Wikiwyg',
420 'tinymce' => 'tinymce',
421 'CKeditor' => 'CKeditor',
423 'htmlarea3' => 'htmlarea3',
424 'htmlarea2' => 'htmlarea2',
427 $properties["WYSIWYG_DEFAULT_PAGETYPE_HTML"] =
428 new boolean_define_commented_optional('WYSIWYG_DEFAULT_PAGETYPE_HTML');
430 $properties["UPLOAD_USERDIR"] =
431 new boolean_define_commented_optional('UPLOAD_USERDIR');
433 $properties["DISABLE_UNITS"] =
434 new boolean_define_commented_optional('DISABLE_UNITS');
436 $properties["UNITS_EXE"] =
437 new _define_commented_optional('UNITS_EXE');
439 $properties["ENABLE_XHTML_XML"] =
440 new boolean_define_commented_optional('ENABLE_XHTML_XML');
442 $properties["ENABLE_OPEN_GRAPH"] =
443 new boolean_define_commented_optional('ENABLE_OPEN_GRAPH');
445 $properties["ENABLE_SPAMASSASSIN"] =
446 new boolean_define_commented_optional('ENABLE_SPAMASSASSIN');
448 $properties["ENABLE_SPAMBLOCKLIST"] =
449 new boolean_define_optional('ENABLE_SPAMBLOCKLIST');
451 $properties["NUM_SPAM_LINKS"] =
452 new numeric_define_optional('NUM_SPAM_LINKS');
454 $properties["GOOGLE_LINKS_NOFOLLOW"] =
455 new boolean_define_commented_optional('GOOGLE_LINKS_NOFOLLOW');
457 $properties["ENABLE_DISCUSSION_LINK"] =
458 new boolean_define_commented_optional('ENABLE_DISCUSSION_LINK');
460 $properties["ENABLE_CAPTCHA"] =
461 new boolean_define_commented_optional('ENABLE_CAPTCHA');
463 $properties["USE_CAPTCHA_RANDOM_WORD"] =
464 new boolean_define_commented_optional('USE_CAPTCHA_RANDOM_WORD');
466 $properties["USE_SAFE_DBSESSION"] =
467 new boolean_define_commented_optional('USE_SAFE_DBSESSION');
469 $properties["BLOG_DEFAULT_EMPTY_PREFIX"] =
470 new boolean_define_commented_optional('BLOG_DEFAULT_EMPTY_PREFIX');
472 $properties["ENABLE_SEARCHHIGHLIGHT"] =
473 new boolean_define_commented_optional('ENABLE_SEARCHHIGHLIGHT');
475 $properties["Part One"] =
476 new part('_part1', $SEPARATOR . "\n", "
477 Part One: Authentication and security settings. See Part Three for more.");
479 $properties["Wiki Name"] =
480 new _define_optional('WIKI_NAME', WIKI_NAME);
482 $properties["Admin Username"] =
483 new _define_notempty('ADMIN_USER', ADMIN_USER, "
484 You must set this! Username and password of the administrator.",
485 "onchange=\"validate_ereg('Sorry, ADMIN_USER cannot be empty.', '^.+$', 'ADMIN_USER', this);\"");
487 $properties["Admin Password"] =
488 new _define_password('ADMIN_PASSWD', ADMIN_PASSWD, "
490 For heaven's sake pick a good password.
492 If your version of PHP supports encrypted passwords, your password will be
493 automatically encrypted within the generated config file.
494 Use the \"Create Random Password\" button to create a good (random) password.
496 ADMIN_PASSWD is ignored on HttpAuth",
497 "onchange=\"validate_ereg('Sorry, ADMIN_PASSWD must be at least 4 chars long.', '^....+$', 'ADMIN_PASSWD', this);\"");
499 $properties["Encrypted Passwords"] =
502 array('true' => "true. use crypt for all passwords",
503 'false' => "false. use plaintest passwords (not recommended)"));
505 $properties["Reverse DNS"] =
506 new boolean_define_optional
507 ('ENABLE_REVERSE_DNS',
508 array('true' => "true. perform additional reverse dns lookups",
509 'false' => "false. just record the address as given by the httpd server"));
511 $properties["ZIP Dump Authentication"] =
512 new boolean_define_optional('ZIPDUMP_AUTH',
513 array('false' => "false. Everyone may download zip dumps",
514 'true' => "true. Only admin may download zip dumps"));
516 $properties["Enable RawHtml Plugin"] =
517 new boolean_define_commented_optional('ENABLE_RAW_HTML');
519 $properties["Allow RawHtml Plugin only on locked pages"] =
520 new boolean_define_commented_optional('ENABLE_RAW_HTML_LOCKEDONLY');
522 $properties["Allow RawHtml Plugin if safe HTML code"] =
523 new boolean_define_commented_optional('ENABLE_RAW_HTML_SAFE', '', "
524 If this is set, all unsafe html code is stripped automatically (experimental!)
525 See <a href=\"http://chxo.com/scripts/safe_html-test.php\" target=\"_new\">chxo.com/scripts/safe_html-test.php</a>
528 $properties["Maximum Upload Size"] =
529 new numeric_define_optional('MAX_UPLOAD_SIZE', MAX_UPLOAD_SIZE);
531 $properties["Minor Edit Timeout"] =
532 new numeric_define_optional('MINOR_EDIT_TIMEOUT', MINOR_EDIT_TIMEOUT);
534 $properties["Disabled Actions"] =
535 new array_define('DISABLED_ACTIONS', DISABLED_ACTIONS /*array()*/);
537 $properties["Moderate all Pagechanges"] =
538 new boolean_define_commented_optional('ENABLE_MODERATEDPAGE_ALL');
540 $properties["Access Log File"] =
541 new _define_commented_optional('ACCESS_LOG', ACCESS_LOG);
543 $properties["Access Log SQL"] =
544 new _define_selection(
546 array('0' => 'disabled',
548 '2' => 'read + write'));
550 $properties["Compress Output"] =
551 new boolean_define_commented_optional
553 array('' => 'undefined - GZIP compress when appropriate.',
554 'false' => 'Never compress output.',
555 'true' => 'Always try to compress output.'));
557 $properties["HTTP Cache Control"] =
558 new _define_selection_optional
560 array('LOOSE' => 'LOOSE',
561 'STRICT' => 'STRICT',
562 'NO_CACHE' => 'NO_CACHE',
563 'ALLOW_STALE' => 'ALLOW_STALE'),
567 This controls how PhpWiki sets the HTTP cache control
568 headers (Expires: and Cache-Control:)
573 <dd>This is roughly the old (pre 1.3.4) behaviour. PhpWiki will
574 instruct proxies and browsers never to cache PhpWiki output.</dd>
576 <dd>Cached pages will be invalidated whenever the database global
577 timestamp changes. This should behave just like NONE (modulo
578 bugs in PhpWiki and your proxies and browsers), except that
579 things will be slightly more efficient.</dd>
581 <dd>Cached pages will be invalidated whenever they are edited,
582 or, if the pages include plugins, when the plugin output could
583 conceivably have changed.
584 <p>Behavior should be much like STRICT, except that sometimes
585 wikilinks will show up as undefined (with the question mark)
586 when in fact they refer to (recently) created pages.
587 (Hitting your browsers reload or perhaps shift-reload button
588 should fix the problem.)</p></dd>
590 <dd>Proxies and browsers will be allowed to used stale pages.
591 (The timeout for stale pages is controlled by CACHE_CONTROL_MAX_AGE.)
592 <p>This setting will result in quirky behavior. When you edit a
593 page your changes may not show up until you shift-reload the
595 <p>This setting is generally not advisable, however it may be useful
596 in certain cases (e.g. if your wiki gets lots of page views,
597 and few edits by knowledgeable people who won't freak over the quirks.)</p>
600 The default is currently LOOSE.");
602 $properties["HTTP Cache Control Max Age"] =
603 new numeric_define_optional('CACHE_CONTROL_MAX_AGE', CACHE_CONTROL_MAX_AGE);
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'));
611 $properties["COOKIE_EXPIRATION_DAYS"] =
612 new numeric_define_optional('COOKIE_EXPIRATION_DAYS', COOKIE_EXPIRATION_DAYS);
614 $properties["COOKIE_DOMAIN"] =
615 new _define_commented_optional('COOKIE_DOMAIN', COOKIE_DOMAIN);
617 $properties["Path for PHP Session Support"] =
618 new _define_optional('SESSION_SAVE_PATH', defined('SESSION_SAVE_PATH') ? SESSION_SAVE_PATH : ini_get('session.save_path'));
620 $properties["Force PHP Database Sessions"] =
621 new boolean_define_commented_optional
623 array('false' => 'Disable database sessions, use files',
624 'true' => 'Enable database sessions'));
626 ///////// database selection
628 $properties["Part Two"] =
629 new part('_part2', $SEPARATOR . "\n", "
632 Database Configuration
635 $properties["Database Type"] =
636 new _define_selection("DATABASE_TYPE",
637 array('dba' => "dba",
639 'ADODB' => "SQL ADODB",
640 'PDO' => "PDO (php5 only)",
641 'file' => "flatfile")/*, "
642 Select the database backend type:
643 Choose dba (default) to use one of the standard UNIX dba libraries. This is the fastest.
644 Choose ADODB or SQL to use an SQL database with ADODB or PEAR.
645 Choose PDO on php5 to use an SQL database. (experimental, no paging yet)
646 flatfile is simple and slow.
647 Recommended is dba or SQL: PEAR or ADODB."*/);
649 $properties["SQL DSN Setup"] =
650 new unchangeable_variable('_sqldsnstuff', "", "
651 For SQL based backends, specify the database as a DSN
652 The most general form of a DSN looks like:
654 phptype(dbsyntax)://username:password@protocol+hostspec/database?option=value
656 For a MySQL database, the following should work:
658 mysql://user:password@host/databasename
660 To connect over a unix socket, use something like
662 mysql://user:password@unix(/path/to/socket)/databasename
665 DATABASE_DSN = mysql://guest@:/var/lib/mysql/mysql.sock/phpwiki
666 DATABASE_DSN = mysql://guest@localhost/phpwiki
667 DATABASE_DSN = pgsql://localhost/user_phpwiki
670 // Choose ADODB or SQL to use an SQL database with ADODB or PEAR.
671 // Choose dba to use one of the standard UNIX dbm libraries.
673 $properties["SQL Type"] =
674 new _variable_selection('_dsn_sqltype',
675 array('mysql' => "MySQL",
676 'pgsql' => "PostgreSQL",
677 'mssql' => "Microsoft SQL Server",
678 'mssqlnative' => "Microsoft SQL Server (native)",
679 'oci8' => "Oracle 8",
680 'mysqli' => "mysqli (only ADODB)",
681 'mysqlt' => "mysqlt (only ADODB)",
682 'ODBC' => "ODBC (only ADODB or PDO)",
683 'firebird' => "Firebird (only PDO)",
684 'oracle' => "Oracle (only PDO)",
686 SQL DB types. The DSN hosttype.");
688 $properties["SQL User"] =
689 new _variable('_dsn_sqluser', "wikiuser", "
692 $properties["SQL Password"] =
693 new _variable('_dsn_sqlpass', "", "
696 $properties["SQL Database Host"] =
697 new _variable('_dsn_sqlhostorsock', "localhost", "
698 SQL Database Hostname:
700 To connect over a local named socket, use something like
702 unix(/var/lib/mysql/mysql.sock)
705 mysql on Windows via named pipes might need 127.0.0.1");
707 $properties["SQL Database Name"] =
708 new _variable('_dsn_sqldbname', "phpwiki", "
709 SQL Database Name:");
711 $dsn_sqltype = $properties["SQL Type"]->value();
712 $dsn_sqluser = $properties["SQL User"]->value();
713 $dsn_sqlpass = $properties["SQL Password"]->value();
714 $dsn_sqlhostorsock = $properties["SQL Database Host"]->value();
715 $dsn_sqldbname = $properties["SQL Database Name"]->value();
716 $dsn_sqlstring = $dsn_sqltype . "://{$dsn_sqluser}:{$dsn_sqlpass}@{$dsn_sqlhostorsock}/{$dsn_sqldbname}";
718 $properties["SQL dsn"] =
719 new unchangeable_define("DATABASE_DSN",
721 Calculated from the settings above:");
723 $properties["Filename / Table name Prefix"] =
724 new _define_commented('DATABASE_PREFIX', DATABASE_PREFIX, "
725 Used by all DB types:
727 Prefix for filenames or table names, e.g. \"phpwiki_\"
729 Currently <b>you MUST EDIT THE SQL file too!</b> (in the schemas/
730 directory because we aren't doing on the fly sql generation
731 during the installation.
733 Note: This prefix is NOT prepended to the default DBAUTH_
734 tables user, pref and member!
737 $properties["DATABASE_PERSISTENT"] =
738 new boolean_define_commented_optional
739 ('DATABASE_PERSISTENT',
740 array('false' => "Disabled",
741 'true' => "Enabled"));
743 $properties["DB Session table"] =
744 new _define_optional("DATABASE_SESSION_TABLE", DATABASE_SESSION_TABLE, "
745 Tablename to store session information. Only supported by SQL backends.
747 A word of warning - any prefix defined above will be prepended to whatever is given here.
751 $temp = !empty($_ENV['TEMP']) ? $_ENV['TEMP'] : "/tmp";
752 $properties["dba directory"] =
753 new _define("DATABASE_DIRECTORY", $temp);
755 // TODO: list the available methods
756 $properties["dba handler"] =
757 new _define_selection('DATABASE_DBA_HANDLER',
758 array('gdbm' => "gdbm - GNU database manager (not recommended anymore)",
759 'dbm' => "DBM - Redhat default. On sf.net there's dbm and not gdbm anymore",
760 'db2' => "DB2 - BerkeleyDB (Sleepycat) DB2",
761 'db3' => "DB3 - BerkeleyDB (Sleepycat) DB3. Default on Windows but not on every Linux",
762 'db4' => "DB4 - BerkeleyDB (Sleepycat) DB4."), "
763 Use 'gdbm', 'dbm', 'db2', 'db3' or 'db4' depending on your DBA handler methods supported: <br /> "
764 . join(", ", dba_handlers())
765 . "\n\nBetter not use other hacks such as inifile, flatfile or cdb");
767 $properties["dba timeout"] =
768 new numeric_define("DATABASE_TIMEOUT", DATABASE_TIMEOUT, "
769 Recommended values are 10-20 seconds. The more load the server has, the higher the timeout.");
771 $properties["DATABASE_OPTIMISE_FREQUENCY"] =
772 new numeric_define_optional('DATABASE_OPTIMISE_FREQUENCY', DATABASE_OPTIMISE_FREQUENCY);
774 $properties["DBADMIN_USER"] =
775 new _define_optional('DBADMIN_USER', DBADMIN_USER);
777 $properties["DBADMIN_PASSWD"] =
778 new _define_password_optional('DBADMIN_PASSWD', DBADMIN_PASSWD);
780 $properties["USECACHE"] =
781 new boolean_define_commented_optional('USECACHE');
785 $properties["Page Revisions"] =
786 new unchangeable_variable('_parttworevisions', "", "
788 Section 2a: Archive Cleanup
789 The next section controls how many old revisions of each page are kept in the database.
791 There are two basic classes of revisions: major and minor. Which
792 class a revision belongs in is determined by whether the author
793 checked the \"this is a minor revision\" checkbox when they saved the
796 There is, additionally, a third class of revisions: author
797 revisions. The most recent non-mergable revision from each distinct
798 author is and author revision.
800 The expiry parameters for each of those three classes of revisions
801 can be adjusted separately. For each class there are five
802 parameters (usually, only two or three of the five are actually
803 set) which control how long those revisions are kept in the
806 <dt>max_keep:</dt> <dd>If set, this specifies an absolute maximum for the
807 number of archived revisions of that class. This is
808 meant to be used as a safety cap when a non-zero
809 min_age is specified. It should be set relatively high,
810 and it's purpose is to prevent malicious or accidental
811 database overflow due to someone causing an
812 unreasonable number of edits in a short period of time.</dd>
814 <dt>min_age:</dt> <dd>Revisions younger than this (based upon the supplanted
815 date) will be kept unless max_keep is exceeded. The age
816 should be specified in days. It should be a
817 non-negative, real number,</dd>
819 <dt>min_keep:</dt> <dd>At least this many revisions will be kept.</dd>
821 <dt>keep:</dt> <dd>No more than this many revisions will be kept.</dd>
823 <dt>max_age:</dt> <dd>No revision older than this age will be kept.</dd>
825 Supplanted date: Revisions are timestamped at the instant that they
826 cease being the current revision. Revision age is computed using
827 this timestamp, not the edit time of the page.
829 Merging: When a minor revision is deleted, if the preceding
830 revision is by the same author, the minor revision is merged with
831 the preceding revision before it is deleted. Essentially: this
832 replaces the content (and supplanted timestamp) of the previous
833 revision with the content after the merged minor edit, the rest of
834 the page metadata for the preceding version (summary, mtime, ...)
838 // For now the expiration parameters are statically inserted as
839 // an unchangeable property. You'll have to edit the resulting
840 // config file if you really want to change these from the default.
842 $properties["Major Edits: keep minimum days"] =
843 new numeric_define('MAJOR_MIN_KEEP', MAJOR_MIN_KEEP, "
844 Default: Keep for unlimited time.
845 Set to 0 to enable archive cleanup");
846 $properties["Minor Edits: keep minumum days"] =
847 new numeric_define('MINOR_MIN_KEEP', MINOR_MIN_KEEP, "
848 Default: Keep for unlimited time.
849 Set to 0 to enable archive cleanup");
851 $properties["Major Edits: how many"] =
852 new numeric_define('MAJOR_KEEP', MAJOR_KEEP, "
853 Keep up to 8 major edits");
854 $properties["Major Edits: how many days"] =
855 new numeric_define('MAJOR_MAX_AGE', MAJOR_MAX_AGE, "
856 keep them no longer than a month");
858 $properties["Minor Edits: how many"] =
859 new numeric_define("MINOR_KEEP", MINOR_KEEP, "
860 Keep up to 4 minor edits");
861 $properties["Minor Edits: how many days"] =
862 new numeric_define("MINOR_MAX_AGE", "7", "
863 keep them no longer than a week");
865 $properties["per Author: how many"] =
866 new numeric_define("AUTHOR_KEEP", "8", "
867 Keep the latest contributions of the last 8 authors,");
868 $properties["per Author: how many days"] =
869 new numeric_define("AUTHOR_MAX_AGE", "365", "
871 $properties["per Author: keep minumum days"] =
872 new numeric_define("AUTHOR_MIN_AGE", "7", "
873 Additionally, (in the case of a particularly active page) try to
874 keep the latest contributions of all authors in the last week (even if there are more than eight of them,)");
875 $properties["per Author: max revisions"] =
876 new numeric_define("AUTHOR_MAX_KEEP", "20", "
877 but in no case keep more than twenty unique author revisions.");
879 /////////////////////////////////////////////////////////////////////
881 $properties["Part Three"] =
882 new part('_part3', $SEPARATOR . "\n", "
884 Part Three: (optional)
885 Basic User Authentication Setup
888 $properties["Publicly viewable"] =
889 new boolean_define_optional('ALLOW_ANON_USER',
890 array('true' => "true. Permit anonymous view. (Default)",
891 'false' => "false. Force login even on view (strictly private)"), "
892 If ALLOW_ANON_USER is false, you have to login before viewing any page or doing any other action on a page.");
894 $properties["Allow anonymous edit"] =
895 new boolean_define_optional('ALLOW_ANON_EDIT',
896 array('true' => "true. Permit anonymous users to edit. (Default)",
897 'false' => "false. Force login on edit (moderately locked)"), "
898 If ALLOW_ANON_EDIT is false, you have to login before editing or changing any page. See below.");
900 $properties["Allow Bogo Login"] =
901 new boolean_define_optional('ALLOW_BOGO_LOGIN',
902 array('true' => "true. Users may Sign In with any WikiWord, without password. (Default)",
903 'false' => "false. Require stricter authentication."), "
904 If ALLOW_BOGO_LOGIN is false, you may not login with any wikiword username and empty password.
905 If true, users are allowed to create themselves with any WikiWord username. See below.");
907 $properties["Allow User Passwords"] =
908 new boolean_define_optional('ALLOW_USER_PASSWORDS',
909 array('true' => "True user authentication with password checking. (Default)",
910 'false' => "false. Ignore authentication settings below."), "
911 If ALLOW_USER_PASSWORDS is true, the authentication settings below define where and how to
912 check against given username/passwords. For completely security disable BOGO_LOGIN and ANON_EDIT above.");
914 $properties["User Authentication Methods"] =
915 new array_define('USER_AUTH_ORDER', array("PersonalPage", "Db"), "
916 Many different methods can be used to check user's passwords.
917 Try any of these in the given order:
920 <dd>WikiWord username, with no *actual* password checking,
921 although the user will still have to enter one.</dd>
922 <dt>PersonalPage</dt>
923 <dd>Store passwords in the users homepage metadata (simple)</dd>
925 <dd>Use DBAUTH_AUTH_* (see below) with PearDB or ADODB only.</dd>
927 <dd>Authenticate against LDAP_AUTH_HOST with LDAP_BASE_DN.</dd>
929 <dd>Authenticate against IMAP_AUTH_HOST (email account)</dd>
931 <dd>Authenticate against POP3_AUTH_HOST (email account)</dd>
933 <dd>Get username and level from a PHP session variable. (e.g. for FusionForge)</dd>
935 <dd>Store username:crypted-passwords in .htaccess like files.
936 Use Apache's htpasswd to manage this file.</dd>
938 <dd>Use the protection by the webserver (.htaccess/.htpasswd) (experimental)
939 Enforcing HTTP Auth not yet. Note that the ADMIN_USER should exist also.
940 Using HttpAuth disables all other methods and no userauth sessions are used.</dd>
943 Several of these methods can be used together, in the manner specified by
944 USER_AUTH_POLICY, below. To specify multiple authentication methods,
945 separate the name of each one with colons.
947 USER_AUTH_ORDER = 'PersonalPage : Db'
948 USER_AUTH_ORDER = 'BogoLogin : PersonalPage'
951 $properties["ENABLE_AUTH_OPENID"] =
952 new boolean_define('ENABLE_AUTH_OPENID');
954 $properties["PASSWORD_LENGTH_MINIMUM"] =
955 new numeric_define('PASSWORD_LENGTH_MINIMUM', PASSWORD_LENGTH_MINIMUM);
957 $properties["USER_AUTH_POLICY"] =
958 new _define_selection('USER_AUTH_POLICY',
959 array('first-only' => "first-only - use only the first method in USER_AUTH_ORDER",
960 'old' => "old - ignore USER_AUTH_ORDER (legacy)",
961 'strict' => "strict - check all methods for userid + password (recommended)",
962 'stacked' => "stacked - check all methods for userid, and if found for password"), "
963 The following policies are available for user authentication:
966 <dd>use only the first method in USER_AUTH_ORDER</dd>
968 <dd>ignore USER_AUTH_ORDER and try to use all available
969 methods as in the previous PhpWiki releases (slow)</dd>
971 <dd>check if the user exists for all methods:
972 on the first existing user, try the password.
973 dont try the other methods on failure then</dd>
975 <dd>check the given user - password combination for all
976 methods and return true on the first success.</dd></dl>");
978 $properties["ENABLE_PAGEPERM"] =
979 new boolean_define_commented_optional('ENABLE_PAGEPERM');
983 $properties["Part Three A"] =
984 new part('_part3a', $SEPARATOR . "\n", "
986 Part Three A: (optional)
989 $properties["Group membership"] =
990 new _define_selection("GROUP_METHOD",
991 array('WIKIPAGE' => "WIKIPAGE - List at \"CategoryGroup\". (Slowest, but easiest to maintain)",
992 'NONE' => "NONE - Disable group membership (Fastest)",
993 'DB' => "DB - SQL Database, Optionally external. See USERS/GROUPS queries",
994 'FILE' => "Flatfile. See AUTH_GROUP_FILE below.",
995 'LDAP' => "LDAP - See \"LDAP authentication options\" above. (Experimental)"), "
996 Group membership. PhpWiki supports defining permissions for a group as
997 well as for individual users. This defines how group membership information
998 is obtained. Supported values are:
1001 <dd>Disable group membership (Fastest). Note the required quoting.</dd>
1003 <dd>Define groups as list at \"CategoryGroup\". (Slowest, but easiest to maintain)</dd>
1005 <dd>Stored in an SQL database. Optionally external. See USERS/GROUPS queries</dd>
1007 <dd>Flatfile. See AUTH_GROUP_FILE below.</dd>
1009 <dd>LDAP groups. See \"LDAP authentication options\" above and
1010 lib/WikiGroup.php. (experimental)</dd></dl>");
1012 $properties["CATEGORY_GROUP_PAGE"] =
1013 new _define_optional('CATEGORY_GROUP_PAGE', _("CategoryGroup"), "
1014 If GROUP_METHOD = WIKIPAGE:
1016 Page where all groups are listed.");
1018 $properties["AUTH_GROUP_FILE"] =
1019 new _define_optional('AUTH_GROUP_FILE', "/etc/groups", "
1020 For GROUP_METHOD = FILE, the file given below is referenced to obtain
1021 group membership information. It should be in the same format as the
1022 standard unix /etc/groups(5) file.");
1024 $properties["Part Three B"] =
1025 new part('_part3b', $SEPARATOR . "\n", "
1027 Part Three B: (optional)
1028 External database authentication and authorization.
1030 If USER_AUTH_ORDER includes Db, or GROUP_METHOD = DB, the options listed
1031 below define the SQL queries used to obtain the information out of the
1032 database, and (optionally) store the information back to the DB.");
1034 $properties["DBAUTH_AUTH_DSN"] =
1035 new _define_optional('DBAUTH_AUTH_DSN', $dsn_sqlstring, "
1036 A database DSN to connect to. Defaults to the DSN specified for the Wiki as a whole.");
1038 $properties["User Exists Query"] =
1039 new _define('DBAUTH_AUTH_USER_EXISTS', "SELECT userid FROM user WHERE userid='\$userid'", "
1040 USER/PASSWORD queries:
1042 For USER_AUTH_POLICY=strict and the Db method is required");
1044 $properties["Check Query"] =
1045 new _define_optional('DBAUTH_AUTH_CHECK', "SELECT IF(passwd='\$password',1,0) AS ok FROM user WHERE userid='\$userid'", "
1047 Check to see if the supplied username/password pair is OK
1049 Plaintext passwords: (DBAUTH_AUTH_CRYPT_METHOD = plain)<br />
1050 ; DBAUTH_AUTH_CHECK = \"SELECT IF(passwd='\$password',1,0) AS ok FROM user WHERE userid='\$userid'\"
1052 database-hashed passwords (more secure):<br />
1053 ; DBAUTH_AUTH_CHECK = \"SELECT IF(passwd=PASSWORD('\$password'),1,0) AS ok FROM user WHERE userid='\$userid'\"");
1055 $properties["Crypt Method"] =
1056 new _define_selection_optional
1057 ('DBAUTH_AUTH_CRYPT_METHOD',
1058 array('plain' => 'plain',
1059 'crypt' => 'crypt'), "
1060 If you want to use Unix crypt()ed passwords, you can use DBAUTH_AUTH_CHECK
1061 to get the password out of the database with a simple SELECT query, and
1062 specify DBAUTH_AUTH_USER_EXISTS and DBAUTH_AUTH_CRYPT_METHOD:
1064 ; DBAUTH_AUTH_CHECK = \"SELECT passwd FROM user where userid='\$userid'\" <br />
1065 ; DBAUTH_AUTH_CRYPT_METHOD = crypt");
1067 $properties["Update the user's authentication credential"] =
1068 new _define('DBAUTH_AUTH_UPDATE', "UPDATE user SET passwd='\$password' WHERE userid='\$userid'", "
1069 If this is not defined but DBAUTH_AUTH_CHECK is, then the user will be unable to update their
1072 Plaintext passwords:<br />
1073 DBAUTH_AUTH_UPDATE = \"UPDATE user SET passwd='\$password' WHERE userid='\$userid'\"<br />
1074 Database-hashed passwords:<br />
1075 DBAUTH_AUTH_UPDATE = \"UPDATE user SET passwd=PASSWORD('\$password') WHERE userid='\$userid'\"");
1077 $properties["Allow the user to create their own account"] =
1078 new _define_optional('DBAUTH_AUTH_CREATE', "INSERT INTO user SET passwd=PASSWORD('\$password'),userid='\$userid'", "
1079 If this is empty, Db users cannot subscribe by their own.");
1081 $properties["USER/PREFERENCE queries"] =
1082 new _define_optional('DBAUTH_PREF_SELECT', "SELECT prefs FROM user WHERE userid='\$userid'", "
1083 If you choose to store your preferences in an external database, enable
1084 the following queries. Note that if you choose to store user preferences
1085 in the 'user' table, only registered users get their prefs from the database,
1086 self-created users do not. Better to use the special 'pref' table.
1088 The prefs field stores the serialized form of the user's preferences array,
1089 to ease the complication of storage.
1091 DBAUTH_PREF_SELECT = \"SELECT prefs FROM user WHERE userid='\$userid'\"
1092 DBAUTH_PREF_SELECT = \"SELECT prefs FROM pref WHERE userid='\$userid'\"
1095 $properties["Update the user's preferences"] =
1096 new _define_optional('DBAUTH_PREF_UPDATE', "UPDATE user SET prefs='\$pref_blob' WHERE userid='\$userid'", "
1097 Note that REPLACE works only with mysql and destroy all other columns!
1099 Mysql: DBAUTH_PREF_UPDATE = \"REPLACE INTO pref SET prefs='\$pref_blob',userid='\$userid'\"");
1101 $properties["Create new user's preferences"] =
1102 new _define_optional('DBAUTH_PREF_INSERT', "INSERT INTO pref (userid,prefs) VALUES ('\$userid','\$pref_blob')", "
1103 Define this if new user can be create by themselves.
1106 $properties["USERS/GROUPS queries"] =
1107 new _define_optional('DBAUTH_IS_MEMBER', "SELECT user FROM user WHERE user='\$userid' AND group='\$groupname'", "
1108 You can define 1:n or n:m user<=>group relations, as you wish.
1110 Sample configurations:
1112 only one group per user (1:n):<br />
1113 DBAUTH_IS_MEMBER = \"SELECT user FROM user WHERE user='\$userid' AND group='\$groupname'\"<br />
1114 DBAUTH_GROUP_MEMBERS = \"SELECT user FROM user WHERE group='\$groupname'\"<br />
1115 DBAUTH_USER_GROUPS = \"SELECT group FROM user WHERE user='\$userid'\"<br />
1116 multiple groups per user (n:m):<br />
1117 DBAUTH_IS_MEMBER = \"SELECT userid FROM member WHERE userid='\$userid' AND groupname='\$groupname'\"<br />
1118 DBAUTH_GROUP_MEMBERS = \"SELECT DISTINCT userid FROM member WHERE groupname='\$groupname'\"<br />
1119 DBAUTH_USER_GROUPS = \"SELECT groupname FROM member WHERE userid='\$userid'\"<br />");
1120 $properties["DBAUTH_GROUP_MEMBERS"] =
1121 new _define_optional('DBAUTH_GROUP_MEMBERS', "SELECT user FROM user WHERE group='\$groupname'", "");
1122 $properties["DBAUTH_USER_GROUPS"] =
1123 new _define_optional('DBAUTH_USER_GROUPS', "SELECT group FROM user WHERE user='\$userid'", "");
1125 $properties["LDAP AUTH Host"] =
1126 new _define_optional('LDAP_AUTH_HOST', "ldap://localhost:389", "
1127 If USER_AUTH_ORDER contains Ldap:
1129 The LDAP server to connect to. Can either be a hostname, or a complete
1130 URL to the server (useful if you want to use ldaps or specify a different
1133 $properties["LDAP BASE DN"] =
1134 new _define_optional('LDAP_BASE_DN', "ou=mycompany.com,o=My Company", "
1135 The organizational or domain BASE DN: e.g. \"dc=mydomain,dc=com\".
1137 Note: ou=Users and ou=Groups are used for GroupLdap Membership
1138 Better use LDAP_OU_USERS and LDAP_OU_GROUP with GROUP_METHOD=LDAP.");
1140 $properties["LDAP SET OPTION"] =
1141 new _define_optional('LDAP_SET_OPTION', "LDAP_OPT_PROTOCOL_VERSION=3:LDAP_OPT_REFERRALS=0", "
1142 Some LDAP servers need some more options, such as the Windows Active
1143 Directory Server. Specify the options (as allowed by the PHP LDAP module)
1144 and their values as NAME=value pairs separated by colons.");
1146 $properties["LDAP AUTH USER"] =
1147 new _define_optional('LDAP_AUTH_USER', "CN=ldapuser,ou=Users,o=Development,dc=mycompany.com", "
1148 DN to initially bind to the LDAP server as. This is needed if the server doesn't
1149 allow anonymous queries. (Windows Active Directory Server)");
1151 $properties["LDAP AUTH PASSWORD"] =
1152 new _define_optional('LDAP_AUTH_PASSWORD', "secret", "
1153 Password to use to initially bind to the LDAP server, as the DN
1154 specified in the LDAP_AUTH_USER option (above).");
1156 $properties["LDAP SEARCH FIELD"] =
1157 new _define_optional('LDAP_SEARCH_FIELD', "uid", "
1158 If you want to match usernames against an attribute other than uid,
1159 specify it here. Default: uid
1161 e.g.: LDAP_SEARCH_FIELD = sAMAccountName");
1163 $properties["LDAP OU USERS"] =
1164 new _define_optional('LDAP_OU_USERS', "ou=Users", "
1165 If you have an organizational unit for all users, define it here.
1166 This narrows the search, and is needed for LDAP group membership (if GROUP_METHOD=LDAP)
1167 Default: ou=Users");
1169 $properties["LDAP OU GROUP"] =
1170 new _define_optional('LDAP_OU_GROUP', "ou=Groups", "
1171 If you have an organizational unit for all groups, define it here.
1172 This narrows the search, and is needed for LDAP group membership (if GROUP_METHOD=LDAP)
1173 The entries in this ou must have a gidNumber and cn attribute.
1174 Default: ou=Groups");
1176 $properties["IMAP Auth Host"] =
1177 new _define_optional('IMAP_AUTH_HOST', 'localhost:143/imap/notls', "
1178 If USER_AUTH_ORDER contains IMAP:
1180 The IMAP server to check usernames from. Defaults to localhost.
1182 Some IMAP_AUTH_HOST samples:
1183 localhost, localhost:143/imap/notls,
1184 localhost:993/imap/ssl/novalidate-cert (SuSE refuses non-SSL conections)");
1186 $properties["POP3 Authentication"] =
1187 new _define_optional('POP3_AUTH_HOST', 'localhost:110', "
1188 If USER_AUTH_ORDER contains POP3:
1190 The POP3 mail server to check usernames and passwords against.");
1191 $properties["File Authentication"] =
1192 new _define_optional('AUTH_USER_FILE', '/etc/shadow', "
1193 If USER_AUTH_ORDER contains File:
1195 File to read for authentication information.
1196 Popular choices are /etc/shadow and /etc/httpd/.htpasswd");
1198 $properties["File Storable?"] =
1199 new boolean_define_commented_optional('AUTH_USER_FILE_STORABLE');
1201 $properties["Session Auth USER"] =
1202 new _define_optional('AUTH_SESS_USER', 'userid', "
1203 If USER_AUTH_ORDER contains Session:
1205 Name of the session variable which holds the already authenticated username.
1206 Sample: 'userid', 'user[username]', 'user->username'");
1208 $properties["Session Auth LEVEL"] =
1209 new numeric_define('AUTH_SESS_LEVEL', '2', "
1210 Which level will the user be? 1 = Bogo or 2 = Pass");
1212 /////////////////////////////////////////////////////////////////////
1214 $properties["Part Four"] =
1215 new part('_part4', $SEPARATOR . "\n", "
1218 Page appearance and layout");
1220 $properties["Theme"] =
1221 new _define_selection_optional('THEME',
1222 array('default' => "default",
1223 'MacOSX' => "MacOSX",
1224 'smaller' => 'smaller',
1225 'Wordpress' => 'Wordpress',
1226 'Portland' => "Portland",
1227 'Sidebar' => "Sidebar",
1229 'wikilens' => 'wikilens (Ratings)',
1230 'shamino_com' => 'shamino_com',
1231 'SpaceWiki' => "SpaceWiki",
1232 'Hawaiian' => "Hawaiian",
1233 'MonoBook' => 'MonoBook [experimental]',
1234 'blog' => 'blog [experimental]',
1238 Most of the page appearance is controlled by files in the theme
1241 There are a number of pre-defined themes shipped with PhpWiki.
1242 Or you may create your own, deriving from existing ones.
1244 THEME = Sidebar (default)
1247 THEME = MonoBook (WikiPedia)
1252 THEME = wikilens (with Ratings)
1256 THEME = blog (Kubrick) [experimental]
1259 $properties["Language"] =
1260 new _define_selection_optional('DEFAULT_LANGUAGE',
1261 array('en' => "English",
1262 '' => "<empty> (user-specific)",
1265 'nl' => "Nederlands",
1270 'zh' => "Chinese"), "
1271 Select your language/locale - default language is \"en\" for English.
1272 Other languages available:<pre>
1273 English \"en\" (English - HomePage)
1274 German \"de\" (Deutsch - StartSeite)
1275 French \"fr\" (Français - PageAccueil)
1276 Dutch \"nl\" (Nederlands - ThuisPagina)
1277 Spanish \"es\" (Español - PáginaPrincipal)
1278 Swedish \"sv\" (Svenska - Framsida)
1279 Italian \"it\" (Italiano - PaginaPrincipale)
1280 Japanese \"ja\" (Japanese - ホームページ)
1281 Chinese \"zh\" (Chinese - 首頁)
1283 If you set DEFAULT_LANGUAGE to the empty string, your systems default language
1284 (as determined by the applicable environment variables) will be
1287 $properties["Wiki Page Source"] =
1288 new _define_optional('WIKI_PGSRC', 'pgsrc', "
1289 WIKI_PGSRC -- specifies the source for the initial page contents of
1290 the Wiki. The setting of WIKI_PGSRC only has effect when the wiki is
1291 accessed for the first time (or after clearing the database.)
1292 WIKI_PGSRC can either name a directory or a zip file. In either case
1293 WIKI_PGSRC is scanned for files -- one file per page.
1295 // Default (old) behavior:
1296 define('WIKI_PGSRC', 'pgsrc');
1298 define('WIKI_PGSRC', 'wiki.zip');
1299 define('WIKI_PGSRC',
1300 '../Logs/Hamwiki/hamwiki-20010830.zip');
1303 $properties["Default Wiki Page Source"] =
1304 new _define('DEFAULT_WIKI_PGSRC', 'pgsrc', "
1305 DEFAULT_WIKI_PGSRC is only used when the language is *not* the
1306 default (English) and when reading from a directory: in that case
1307 some English pages are inserted into the wiki as well.
1308 DEFAULT_WIKI_PGSRC defines where the English pages reside.
1311 $properties["Generic Pages"] =
1312 new array_variable('DEFAULT_WIKI_PAGES', array('ReleaseNotes', 'TestPage'), "
1313 These are ':'-separated pages which will get loaded untranslated from DEFAULT_WIKI_PGSRC.
1318 $properties["Part Five"] =
1319 new part('_part5', $SEPARATOR . "\n", "
1324 $properties["Allowed Protocols"] =
1325 new list_define('ALLOWED_PROTOCOLS', 'http|https|mailto|ftp|news|nntp|ssh|gopher', "
1326 Allowed protocols for links - be careful not to allow \"javascript:\"
1327 URL of these types will be automatically linked.
1328 within a named link [name|uri] one more protocol is defined: phpwiki");
1330 $properties["Inline Images"] =
1331 new list_define('INLINE_IMAGES', 'png|jpg|jpeg|gif|swf');
1333 $properties["WikiName Regexp"] =
1334 new _define('WIKI_NAME_REGEXP', "(?<![[:alnum:]])(?:[[:upper:]][[:lower:]]+){2,}(?![[:alnum:]])", "
1335 Perl regexp for WikiNames (\"bumpy words\")
1336 (?<!..) & (?!...) used instead of '\b' because \b matches '_' as well");
1338 $properties["InterWiki Map File"] =
1339 new _define('INTERWIKI_MAP_FILE', 'lib/interwiki.map', "
1340 InterWiki linking -- wiki-style links to other wikis on the web
1342 The map will be taken from a page name InterWikiMap.
1343 If that page is not found (or is not locked), or map
1344 data can not be found in it, then the file specified
1345 by INTERWIKI_MAP_FILE (if any) will be used.");
1347 $properties["WARN_NONPUBLIC_INTERWIKIMAP"] =
1348 new boolean_define('WARN_NONPUBLIC_INTERWIKIMAP');
1350 $properties["Keyword Link Regexp"] =
1351 new _define_optional('KEYWORDS', '\"Category* OR Topic*\"', "
1352 Search term used for automatic page classification by keyword extraction.
1354 Any links on a page to pages whose names match this search
1355 will be used keywords in the keywords html meta tag. This is an aid to
1356 classification by search engines. The value of the match is
1357 used as the keyword.
1359 The default behavior is to match Category* or Topic* links.");
1361 $properties["Author and Copyright Site Navigation Links"] =
1362 new _define_commented_optional('COPYRIGHTPAGE_TITLE', "GNU General Public License", "
1364 These will be inserted as <link rel> tags in the html header of
1365 every page, for search engines and for browsers like Mozilla which
1366 take advantage of link rel site navigation.
1368 If you have your own copyright and contact information pages change
1369 these as appropriate.");
1371 $properties["COPYRIGHTPAGE URL"] =
1372 new _define_commented_optional('COPYRIGHTPAGE_URL', "http://www.gnu.org/copyleft/gpl.html#SEC1", "
1374 Other useful alternatives to consider:
1376 COPYRIGHTPAGE_TITLE = \"GNU Free Documentation License\"
1377 COPYRIGHTPAGE_URL = \"http://www.gnu.org/copyleft/fdl.html\"
1378 COPYRIGHTPAGE_TITLE = \"Creative Commons License 2.0\"
1379 COPYRIGHTPAGE_URL = \"http://creativecommons.org/licenses/by/2.0/\"</pre>
1380 See http://creativecommons.org/learn/licenses/ for variations");
1382 $properties["AUTHORPAGE_TITLE"] =
1383 new _define_commented_optional('AUTHORPAGE_TITLE', "The PhpWiki Programming Team", "
1384 Default Author Names");
1385 $properties["AUTHORPAGE_URL"] =
1386 new _define_commented_optional('AUTHORPAGE_URL', "http://phpwiki.fr/The%20PhpWiki%20programming%20team", "
1387 Default Author URL");
1389 $properties["TOC_FULL_SYNTAX"] =
1390 new boolean_define_optional('TOC_FULL_SYNTAX');
1392 $properties["ENABLE_MARKUP_COLOR"] =
1393 new boolean_define_optional('ENABLE_MARKUP_COLOR');
1395 $properties["DISABLE_MARKUP_WIKIWORD"] =
1396 new boolean_define_optional('DISABLE_MARKUP_WIKIWORD');
1398 $properties["ENABLE_MARKUP_DIVSPAN"] =
1399 new boolean_define_optional('ENABLE_MARKUP_DIVSPAN');
1403 $properties["Part Six"] =
1404 new part('_part6', $SEPARATOR . "\n", "
1406 Part Six (optional):
1407 URL options -- you can probably skip this section.
1409 For a pretty wiki (no index.php in the url) set a separate DATA_PATH.");
1411 $properties["Server Name"] =
1412 new _define_commented_optional('SERVER_NAME', $_SERVER['SERVER_NAME'], "
1413 Canonical name of the server on which this PhpWiki resides.");
1415 $properties["Server Port"] =
1416 new numeric_define_commented('SERVER_PORT', $_SERVER['SERVER_PORT'], "
1417 Canonical httpd port of the server on which this PhpWiki resides.",
1418 "onchange=\"validate_ereg('Sorry, \'%s\' is no valid port number.', '^[0-9]+$', 'SERVER_PORT', this);\"");
1420 $properties["Server Protocol"] =
1421 new _define_selection_optional_commented('SERVER_PROTOCOL',
1422 array('http' => 'http',
1423 'https' => 'https'));
1425 $properties["Script Name"] =
1426 new _define_commented_optional('SCRIPT_NAME', $scriptname);
1428 $properties["Data Path"] =
1429 new _define_commented_optional('DATA_PATH', dirname($scriptname));
1431 $properties["PhpWiki Install Directory"] =
1432 new _define_commented_optional('PHPWIKI_DIR', dirname(__FILE__));
1434 $properties["Use PATH_INFO"] =
1435 new _define_selection_optional_commented('USE_PATH_INFO',
1436 array('' => 'automatic',
1437 'true' => 'use PATH_INFO',
1438 'false' => 'do not use PATH_INFO'), "
1439 PhpWiki will try to use short urls to pages, eg
1440 http://www.example.com/index.php/HomePage
1441 If you want to use urls like
1442 http://www.example.com/index.php?pagename=HomePage
1443 then define 'USE_PATH_INFO' as false by uncommenting the line below.
1444 NB: If you are using Apache >= 2.0.30, then you may need to to use
1445 the directive \"AcceptPathInfo On\" in your Apache configuration file
1446 (or in an appropriate <.htaccess> file) for the short urls to work:
1447 See http://httpd.apache.org/docs-2.0/mod/core.html#acceptpathinfo
1449 See also http://phpwiki.sourceforge.net/phpwiki/PrettyWiki for more ideas
1450 on prettifying your urls.
1452 Default: PhpWiki will try to divine whether use of PATH_INFO
1453 is supported in by your webserver/PHP configuration, and will
1454 use PATH_INFO if it thinks that is possible.");
1456 $properties["Virtual Path"] =
1457 new _define_commented_optional('VIRTUAL_PATH', '/SomeWiki', "
1458 VIRTUAL_PATH is the canonical URL path under which your your wiki
1459 appears. Normally this is the same as dirname(SCRIPT_NAME), however
1460 using e.g. separate starter scripts, apaches mod_actions (or mod_rewrite),
1461 you can make it something different.
1463 If you do this, you should set VIRTUAL_PATH here or in the starter scripts.
1465 E.g. your phpwiki might be installed at at /scripts/phpwiki/index.php,
1466 but you've made it accessible through eg. /wiki/HomePage.
1468 One way to do this is to create a directory named 'wiki' in your
1469 server root. The directory contains only one file: an .htaccess
1470 file which reads something like:
1472 Action x-phpwiki-page /scripts/phpwiki/index.php
1473 SetHandler x-phpwiki-page
1474 DirectoryIndex /scripts/phpwiki/index.php
1476 In that case you should set VIRTUAL_PATH to '/wiki'.
1478 (VIRTUAL_PATH is only used if USE_PATH_INFO is true.)
1481 $upload_file_path = defined('UPLOAD_FILE_PATH') ? UPLOAD_FILE_PATH : getUploadFilePath();
1482 new _define_optional('UPLOAD_FILE_PATH', $temp);
1484 $upload_data_path = defined('UPLOAD_DATA_PATH') ? UPLOAD_DATA_PATH : getUploadDataPath();
1485 new _define_optional('UPLOAD_DATA_PATH', $temp);
1487 $temp = !empty($_ENV['TEMP']) ? $_ENV['TEMP'] : "/tmp";
1488 $properties["TEMP_DIR"] =
1489 new _define_optional('TEMP_DIR', $temp);
1493 $properties["Part Seven"] =
1494 new part('_part7', $SEPARATOR . "\n", "
1498 Miscellaneous settings
1501 $properties["Strict Mailable Pagedumps"] =
1502 new boolean_define_optional('STRICT_MAILABLE_PAGEDUMPS',
1503 array('false' => "binary",
1504 'true' => "quoted-printable"));
1506 $properties["Default local Dump Directory"] =
1507 new _define_optional('DEFAULT_DUMP_DIR');
1509 $properties["Default local HTML Dump Directory"] =
1510 new _define_optional('HTML_DUMP_DIR');
1512 $properties["HTML Dump Filename Suffix"] =
1513 new _define_optional('HTML_DUMP_SUFFIX');
1515 $properties["Pagename of Recent Changes"] =
1516 new _define_optional('RECENT_CHANGES',
1519 $properties["Disable HTTP Redirects"] =
1520 new boolean_define_commented_optional('DISABLE_HTTP_REDIRECT');
1522 $properties["Disable GETIMAGESIZE"] =
1523 new boolean_define_commented_optional('DISABLE_GETIMAGESIZE');
1525 $properties["EDITING_POLICY"] =
1526 new _define_optional('EDITING_POLICY');
1528 $properties["TOOLBAR_PAGELINK_PULLDOWN"] =
1529 new _define_commented_optional('TOOLBAR_PAGELINK_PULLDOWN');
1530 $properties["TOOLBAR_TEMPLATE_PULLDOWN"] =
1531 new _define_commented_optional('TOOLBAR_TEMPLATE_PULLDOWN');
1532 $properties["TOOLBAR_IMAGE_PULLDOWN"] =
1533 new _define_commented_optional('TOOLBAR_IMAGE_PULLDOWN');
1534 $properties["FULLTEXTSEARCH_STOPLIST"] =
1535 new _define_commented_optional('FULLTEXTSEARCH_STOPLIST');
1537 $properties["Part Seven A"] =
1538 new part('_part7a', $SEPARATOR . "\n", "
1542 Optional Plugin Settings and external executables
1545 $properties["FORTUNE_DIR"] =
1546 new _define_commented_optional('FORTUNE_DIR', "/usr/share/fortune");
1547 $properties["USE_EXTERNAL_HTML2PDF"] =
1548 new _define_commented_optional('USE_EXTERNAL_HTML2PDF', "htmldoc --quiet --format pdf14 --no-toc --no-title %s");
1549 $properties["EXTERNAL_HTML2PDF_PAGELIST"] =
1550 new _define_commented_optional('EXTERNAL_HTML2PDF_PAGELIST');
1551 $properties["BABYCART_PATH"] =
1552 new _define_commented_optional('BABYCART_PATH', "/usr/local/bin/babycart");
1553 $properties["GOOGLE_LICENSE_KEY"] =
1554 new _define_commented_optional('GOOGLE_LICENSE_KEY');
1555 $properties["RATEIT_IMGPREFIX"] =
1556 new _define_commented_optional('RATEIT_IMGPREFIX'); //BStar
1557 $properties["GRAPHVIZ_EXE"] =
1558 new _define_commented_optional('GRAPHVIZ_EXE', "/usr/bin/dot");
1560 if (PHP_OS == "Darwin") // Mac OS X
1561 $ttfont = "/System/Library/Frameworks/JavaVM.framework/Versions/1.3.1/Home/lib/fonts/LucidaSansRegular.ttf";
1562 elseif (isWindows()) {
1563 $ttfont = $_ENV['windir'] . '\Fonts\Arial.ttf';
1565 $ttfont = 'luximr'; // This is the only what sourceforge offered.
1566 //$ttfont = 'Helvetica';
1568 $properties["TTFONT"] =
1569 new _define_commented_optional('TTFONT', $ttfont);
1570 $properties["VISUALWIKIFONT"] =
1571 new _define_commented_optional('VISUALWIKIFONT'); // Arial
1572 $properties["VISUALWIKI_ALLOWOPTIONS"] =
1573 new boolean_define_commented_optional('VISUALWIKI_ALLOWOPTIONS'); // false
1574 $properties["PLOTICUS_EXE"] =
1575 new _define_commented_optional('PLOTICUS_EXE'); // /usr/local/bin/pl
1576 $properties["PLOTICUS_PREFABS"] =
1577 new _define_commented_optional('PLOTICUS_PREFABS'); // /usr/share/ploticus
1578 $properties["MY_JABBER_ID"] =
1579 new _define_commented_optional('MY_JABBER_ID'); //
1580 $properties["PHPWEATHER_BASE_DIR"] =
1581 new _define_commented_optional('PHPWEATHER_BASE_DIR'); //
1583 $properties["Part Eight"] =
1584 new part('_part8', $SEPARATOR . "\n", "
1588 Cached Plugin Settings. (pear Cache)
1591 $properties["pear Cache USECACHE"] =
1592 new boolean_define_optional('PLUGIN_CACHED_USECACHE',
1593 array('true' => 'Enabled',
1594 'false' => 'Disabled'), "
1595 Enable or disable pear caching of plugins.");
1596 $properties["pear Cache Database Container"] =
1597 new _define_selection_optional('PLUGIN_CACHED_DATABASE',
1598 array('file' => 'file'), "
1599 Curently only file is supported.
1600 db, trifile and imgfile might be supported, but you must hack that by yourself.");
1602 $properties["pear Cache cache directory"] =
1603 new _define_commented_optional('PLUGIN_CACHED_CACHE_DIR', "/tmp/cache", "
1604 Should be writable to the webserver.");
1605 $properties["pear Cache Filename Prefix"] =
1606 new _define_optional('PLUGIN_CACHED_FILENAME_PREFIX', "phpwiki", "");
1607 $properties["pear Cache HIGHWATER"] =
1608 new numeric_define_optional('PLUGIN_CACHED_HIGHWATER', "4194304", "
1609 Garbage collection parameter.");
1610 $properties["pear Cache LOWWATER"] =
1611 new numeric_define_optional('PLUGIN_CACHED_LOWWATER', "3145728", "
1612 Garbage collection parameter.");
1613 $properties["pear Cache MAXLIFETIME"] =
1614 new numeric_define_optional('PLUGIN_CACHED_MAXLIFETIME', "2592000", "
1615 Garbage collection parameter.");
1616 $properties["pear Cache MAXARGLEN"] =
1617 new numeric_define_optional('PLUGIN_CACHED_MAXARGLEN', "1000", "
1618 max. generated url length.");
1619 $properties["pear Cache FORCE_SYNCMAP"] =
1620 new boolean_define_optional('PLUGIN_CACHED_FORCE_SYNCMAP',
1621 array('true' => 'Enabled',
1622 'false' => 'Disabled'), "");
1623 $properties["pear Cache IMGTYPES"] =
1624 new list_define('PLUGIN_CACHED_IMGTYPES', "png|gif|gd|gd2|jpeg|wbmp|xbm|xpm", "
1625 Handle those image types via GD handles. Check your GD supported image types.");
1627 $end = "\n" . $SEPARATOR . "\n";
1630 text_from_dist("_MAGIC_CLOSE_FILE");
1632 // end of configuration options
1633 ///////////////////////////////
1634 // begin class definitions
1637 * A basic config-dist.ini configuration line in the form of a variable.
1638 * (not needed anymore, we have only defines)
1640 * Produces a string in the form "$name = value;"
1642 * $WikiNameRegexp = "value";
1647 var $config_item_name;
1653 function _variable($config_item_name, $default_value = '', $description = '', $jscheck = '')
1655 $this->config_item_name = $config_item_name;
1657 $description = text_from_dist($config_item_name);
1658 $this->description = $description;
1659 if (defined($config_item_name)
1660 and !preg_match("/(selection|boolean)/", get_class($this))
1661 and !preg_match("/^(SCRIPT_NAME|VIRTUAL_PATH|TEMP_DIR)$/", $config_item_name)
1663 $this->default_value = constant($config_item_name); // ignore given default value
1664 elseif ($config_item_name == $default_value)
1665 $this->default_value = ''; else
1666 $this->default_value = $default_value;
1667 $this->jscheck = $jscheck;
1668 if (preg_match("/variable/i", get_class($this)))
1669 $this->prefix = "\$";
1670 elseif (preg_match("/ini_set/i", get_class($this)))
1671 $this->prefix = "ini_get: "; else
1675 function _define($config_item_name, $default_value = '', $description = '', $jscheck = '')
1677 $this->_variable($config_item_name, $default_value, $description, $jscheck);
1682 global $HTTP_POST_VARS;
1683 if (isset($HTTP_POST_VARS[$this->config_item_name]))
1684 return $HTTP_POST_VARS[$this->config_item_name];
1686 return $this->default_value;
1689 function _config_format($value)
1693 $v = $this->get_config_item_name();
1694 // handle arrays: a|b --> a['b']
1695 if (strpos($v, '|')) {
1696 list($a, $b) = explode('|', $v);
1697 $v = sprintf("%s['%s']", $a, $b);
1699 if (preg_match("/[\"']/", $value))
1700 $value = '"' . $value . '"';
1701 return sprintf("%s = \"%s\"", $v, $value);
1705 function get_config_item_name()
1707 return $this->config_item_name;
1710 function get_config_item_id()
1712 return str_replace('|', '-', $this->config_item_name);
1715 function get_config_item_header()
1717 if (strchr($this->config_item_name, '|')) {
1718 list($var, $param) = explode('|', $this->config_item_name);
1719 return "<b>" . $this->prefix . $var . "['" . $param . "']</b><br />";
1720 } elseif ($this->config_item_name[0] != '_')
1721 return "<b>" . $this->prefix . $this->config_item_name . "</b><br />"; else
1725 function _get_description()
1727 return $this->description;
1730 function _get_config_line($posted_value)
1732 return "\n" . $this->_config_format($posted_value);
1735 function get_config($posted_value)
1737 $d = stripHtml($this->_get_description());
1738 $d = str_replace("\n", "\n; ", $d) . $this->_get_config_line($posted_value) . "\n";
1742 function get_instructions($title)
1745 $i = "<h3>" . $title . "</h3>\n " . nl2p($this->_get_description()) . "\n";
1746 return "<tr>\n<td width=\"$tdwidth\" class=\"instructions\">\n" . $i . "</td>\n";
1751 $size = strlen($this->default_value) > 45 ? 90 : 50;
1752 return $this->get_config_item_header() .
1753 "<input type=\"text\" size=\"$50\" name=\"" . $this->get_config_item_name() . "\" value=\"" . htmlspecialchars($this->default_value) . "\" " .
1754 $this->jscheck . " />" . "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: green\">Input accepted.</p>";
1758 class unchangeable_variable
1761 function _config_format($value)
1766 // function get_html() { return false; }
1769 return $this->get_config_item_header() .
1770 "<em>Not editable.</em>" .
1771 "<pre>" . $this->default_value . "</pre>";
1774 function _get_config_line($posted_value)
1776 if ($this->description)
1778 return "${n}" . $this->default_value;
1781 function get_instructions($title)
1784 $i = "<h3>" . $title . "</h3>\n " . nl2p($this->_get_description()) . "\n";
1785 // $i .= "<em>Not editable.</em><br />\n<pre>" . $this->default_value."</pre>";
1786 return '<tr><td style="width:100%" class="unchangeable-variable-top" colspan="2">' . "\n" . $i . "</td></tr>\n"
1787 . '<tr style="border-top: none;"><td class="unchangeable-variable-left" width="' . $tdwidth . '"> </td>';
1791 class unchangeable_define
1792 extends unchangeable_variable
1794 function _get_config_line($posted_value)
1796 if ($this->description)
1799 $posted_value = $this->default_value;
1800 return "${n}" . $this->_config_format($posted_value);
1803 function _config_format($value)
1805 return sprintf("%s = \"%s\"", $this->get_config_item_name(), $value);
1808 class unchangeable_ini_set
1809 extends unchangeable_variable
1811 function _config_format($value)
1817 class _variable_selection
1822 global $HTTP_POST_VARS;
1823 if (!empty($HTTP_POST_VARS[$this->config_item_name]))
1824 return $HTTP_POST_VARS[$this->config_item_name];
1826 list($option, $label) = each($this->default_value);
1833 $output = $this->get_config_item_header();
1834 $output .= '<select name="' . $this->get_config_item_name() . "\">\n";
1835 /* The first option is the default */
1836 $values = $this->default_value;
1837 if (defined($this->get_config_item_name()))
1838 $this->default_value = constant($this->get_config_item_name());
1840 $this->default_value = null;
1842 foreach ($values as $option => $label) {
1843 if (!is_null($this->default_value) && $this->default_value === $option)
1844 $output .= " <option value=\"$option\" selected=\"selected\">$label</option>\n";
1846 $output .= " <option value=\"$option\">$label</option>\n";
1848 $output .= "</select>\n";
1856 function _config_format($value)
1858 return sprintf("%s = \"%s\"", $this->get_config_item_name(), $value);
1861 function _get_config_line($posted_value)
1863 if ($this->description)
1865 if ($posted_value == '')
1866 return "${n};" . $this->_config_format("");
1868 return "${n}" . $this->_config_format($posted_value);
1873 $size = strlen($this->default_value) > 45 ? 90 : 50;
1874 return $this->get_config_item_header()
1875 . "<input type=\"text\" size=\"$size\" name=\"" . htmlentities($this->get_config_item_name())
1876 . "\" value=\"" . htmlentities($this->default_value) . "\" {$this->jscheck} />"
1877 . "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: green\">Input accepted.</p>";
1881 class _define_commented
1884 function _get_config_line($posted_value)
1886 if ($this->description)
1888 if ($posted_value == $this->default_value)
1889 return "${n};" . $this->_config_format($posted_value);
1890 elseif ($posted_value == '')
1891 return "${n};" . $this->_config_format(""); else
1892 return "${n}" . $this->_config_format($posted_value);
1897 * We don't use _optional anymore, because INI-style config's don't need that.
1898 * IniConfig.php does the optional logic now.
1899 * But we use _optional for config-default.ini options
1901 class _define_commented_optional
1902 extends _define_commented
1906 class _define_optional
1911 class _define_notempty
1916 $s = $this->get_config_item_header()
1917 . "<input type=\"text\" size=\"50\" name=\"" . $this->get_config_item_name()
1918 . "\" value=\"" . $this->default_value . "\" {$this->jscheck} />";
1919 if (empty($this->default_value))
1920 return $s . "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: red\">Cannot be empty.</p>";
1922 return $s . "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: green\">Input accepted.</p>";
1926 class _variable_commented
1929 function _get_config_line($posted_value)
1931 if ($this->description)
1933 if ($posted_value == $this->default_value)
1934 return "${n};" . $this->_config_format($posted_value);
1935 elseif ($posted_value == '')
1936 return "${n};" . $this->_config_format(""); else
1937 return "${n}" . $this->_config_format($posted_value);
1941 class numeric_define
1945 function numeric_define($config_item_name, $default_value = '', $description = '', $jscheck = '')
1947 $this->_define($config_item_name, $default_value, $description, $jscheck);
1949 $this->jscheck = "onchange=\"validate_ereg('Sorry, \'%s\' is not an integer.', '^[-+]?[0-9]+$', '" . $this->get_config_item_name() . "', this);\"";
1952 function _config_format($value)
1954 //return sprintf("define('%s', %s);", $this->get_config_item_name(), $value);
1955 return sprintf("%s = %s", $this->get_config_item_name(), $value);
1958 function _get_config_line($posted_value)
1960 if ($this->description)
1962 if ($posted_value == '')
1963 return "${n};" . $this->_config_format('0');
1965 return "${n}" . $this->_config_format($posted_value);
1969 class numeric_define_optional
1970 extends numeric_define
1974 class numeric_define_commented
1975 extends numeric_define
1977 function _get_config_line($posted_value)
1979 if ($this->description)
1981 if ($posted_value == $this->default_value)
1982 return "${n};" . $this->_config_format($posted_value);
1983 elseif ($posted_value == '')
1984 return "${n};" . $this->_config_format('0'); else
1985 return "${n}" . $this->_config_format($posted_value);
1989 class _define_selection
1990 extends _variable_selection
1992 function _config_format($value)
1994 return sprintf("%s = %s", $this->get_config_item_name(), $value);
1997 function _get_config_line($posted_value)
1999 return _define::_get_config_line($posted_value);
2004 return _variable_selection::get_html();
2008 class _define_selection_optional
2009 extends _define_selection
2013 class _variable_selection_optional
2014 extends _variable_selection
2018 class _define_selection_optional_commented
2019 extends _define_selection_optional
2021 function _get_config_line($posted_value)
2023 if ($this->description)
2025 if ($posted_value == $this->default_value)
2026 return "${n};" . $this->_config_format($posted_value);
2027 elseif ($posted_value == '')
2028 return "${n};" . $this->_config_format(""); else
2029 return "${n}" . $this->_config_format($posted_value);
2033 class _define_password
2037 function _define_password($config_item_name, $default_value = '', $description = '', $jscheck = '')
2039 if ($config_item_name == $default_value) $default_value = '';
2040 $this->_define($config_item_name, $default_value, $description, $jscheck);
2042 $this->jscheck = "onchange=\"validate_ereg('Sorry, \'%s\' cannot be empty.', '^.+$', '"
2043 . $this->get_config_item_name() . "', this);\"";
2046 function _get_config_line($posted_value)
2048 if ($this->description)
2050 if ($posted_value == '') {
2051 $p = "${n};" . $this->_config_format("");
2052 $p .= "\n; If you used the passencrypt.php utility to encode the password";
2053 $p .= "\n; then uncomment this line:";
2054 $p .= "\n;ENCRYPTED_PASSWD = true";
2057 $salt_length = max(CRYPT_SALT_LENGTH,
2061 16 * CRYPT_BLOWFISH);
2062 // generate an encrypted password
2063 $crypt_pass = crypt($posted_value, rand_ascii($salt_length));
2064 $p = "${n}" . $this->_config_format($crypt_pass);
2065 return $p . "\nENCRYPTED_PASSWD = true";
2071 return _variable_password::get_html();
2075 class _define_password_optional
2076 extends _define_password
2079 function _define_password_optional($config_item_name, $default_value = '', $description = '', $jscheck = '')
2081 if ($config_item_name == $default_value) $default_value = '';
2082 if (!$jscheck) $this->jscheck = " ";
2083 $this->_define($config_item_name, $default_value, $description, $jscheck);
2086 function _get_config_line($posted_value)
2088 if ($this->description)
2090 if ($posted_value == '') {
2091 return "${n};" . $this->_config_format("");
2093 return "${n}" . $this->_config_format($posted_value);
2099 $s = $this->get_config_item_header();
2100 // dont re-encrypt already encrypted passwords
2101 $value = $this->value();
2102 $encrypted = !empty($GLOBALS['properties']["Encrypted Passwords"]) and
2103 $GLOBALS['properties']["Encrypted Passwords"]->value();
2106 $s .= "<input type=\"" . ($encrypted ? "text" : "password") . "\" name=\"" . $this->get_config_item_name()
2107 . "\" value=\"" . $value . "\" {$this->jscheck} />";
2112 class _define_password_commented_optional
2113 extends _define_password_optional
2117 class _variable_password
2120 function _variable_password($config_item_name, $default_value = '', $description = '', $jscheck = '')
2122 if ($config_item_name == $default_value) $default_value = '';
2123 $this->_define($config_item_name, $default_value, $description, $jscheck);
2125 $this->jscheck = "onchange=\"validate_ereg('Sorry, \'%s\' cannot be empty.', '^.+$', '" . $this->get_config_item_name() . "', this);\"";
2130 global $HTTP_POST_VARS, $HTTP_GET_VARS;
2131 $s = $this->get_config_item_header();
2132 if (isset($HTTP_POST_VARS['create']) or isset($HTTP_GET_VARS['create'])) {
2133 $new_password = random_good_password();
2134 $this->default_value = $new_password;
2135 $s .= "Created password: <strong>$new_password</strong><br /> <br />";
2137 // dont re-encrypt already encrypted passwords
2138 $value = $this->value();
2139 $encrypted = !empty($GLOBALS['properties']["Encrypted Passwords"]) and
2140 $GLOBALS['properties']["Encrypted Passwords"]->value();
2143 $s .= "<input type=\"" . ($encrypted ? "text" : "password") . "\" name=\"" . $this->get_config_item_name()
2144 . "\" value=\"" . $value . "\" {$this->jscheck} />"
2145 . " <input type=\"submit\" name=\"create\" value=\"Create Random Password\" />";
2147 $s .= "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: red\">Cannot be empty.</p>";
2148 elseif (strlen($this->default_value) < 4)
2149 $s .= "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: red\">Must be longer than 4 chars.</p>"; else
2150 $s .= "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: green\">Input accepted.</p>";
2158 function _get_config_line($posted_value)
2160 // split the phrase by any number of commas or space characters,
2161 // which include " ", \r, \t, \n and \f
2162 $list_values = preg_split("/[\s,]+/", $posted_value, -1, PREG_SPLIT_NO_EMPTY);
2164 $list_values = join("|", $list_values);
2165 return _variable::_get_config_line($list_values);
2170 $list_values = explode("|", $this->default_value);
2171 $rows = max(3, count($list_values) + 1);
2172 $list_values = join("\n", $list_values);
2173 $ta = $this->get_config_item_header();
2174 $ta .= "<textarea cols=\"18\" rows=\"" . $rows . "\" name=\"" . $this->get_config_item_name() . "\" {$this->jscheck}>";
2175 $ta .= $list_values . "</textarea>";
2176 $ta .= "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: green\">Input accepted.</p>";
2184 function _get_config_line($posted_value)
2186 $list_values = preg_split("/[\s,]+/", $posted_value, -1, PREG_SPLIT_NO_EMPTY);
2188 $list_values = join("|", $list_values);
2189 return _variable::_get_config_line($list_values);
2194 $list_values = explode("|", $this->default_value);
2195 $rows = max(3, count($list_values) + 1);
2197 $list_values = join("\n", $list_values);
2198 $ta = $this->get_config_item_header();
2199 $ta .= "<textarea cols=\"18\" rows=\"" . $rows . "\" name=\"" . $this->get_config_item_name() . "\" {$this->jscheck}>";
2200 $ta .= $list_values . "</textarea>";
2201 $ta .= "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: green\">Input accepted.</p>";
2206 class array_variable
2209 function _config_format($value)
2211 return sprintf("%s = \"%s\"", $this->get_config_item_name(),
2212 is_array($value) ? join(':', $value) : $value);
2215 function _get_config_line($posted_value)
2217 // split the phrase by any number of commas or space characters,
2218 // which include " ", \r, \t, \n and \f
2219 $list_values = preg_split("/[\s,]+/", $posted_value, -1, PREG_SPLIT_NO_EMPTY);
2220 if (!empty($list_values)) {
2221 $list_values = "'" . join("', '", $list_values) . "'";
2222 return "\n" . $this->_config_format($list_values);
2224 return "\n;" . $this->_config_format('');
2229 if (is_array($this->default_value))
2230 $list_values = join("\n", $this->default_value);
2232 $list_values = $this->default_value;
2233 $rows = max(3, count($this->default_value) + 1);
2234 $ta = $this->get_config_item_header();
2235 $ta .= "<textarea cols=\"18\" rows=\"" . $rows . "\" name=\"" . $this->get_config_item_name() . "\" {$this->jscheck}>";
2236 $ta .= $list_values . "</textarea>";
2237 $ta .= "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: green\">Input accepted.</p>";
2245 function _config_format($value)
2247 return sprintf("%s = \"%s\"", $this->get_config_item_name(),
2248 is_array($value) ? join(' : ', $value) : $value);
2251 function _get_config_line($posted_value)
2253 // split the phrase by any number of commas or space characters,
2254 // which include " ", \r, \t, \n and \f
2255 $list_values = preg_split("/[\s,:]+/", $posted_value, -1, PREG_SPLIT_NO_EMPTY);
2256 if (!empty($list_values)) {
2257 $list_values = join(" : ", $list_values);
2258 return "\n" . $this->_config_format($list_values);
2260 return "\n;" . $this->_config_format('');
2265 if (!$this->default_value)
2266 $this->default_value = array();
2267 elseif (is_string($this->default_value))
2268 $this->default_value = preg_split("/[\s,:]+/", $this->default_value, -1, PREG_SPLIT_NO_EMPTY);
2269 $list_values = join(" : \n", $this->default_value);
2270 $rows = max(3, count($this->default_value) + 1);
2271 $ta = $this->get_config_item_header();
2272 $ta .= "<textarea cols=\"18\" rows=\"" . $rows . "\" name=\"" . $this->get_config_item_name() . "\" {$this->jscheck}>";
2273 $ta .= $list_values . "</textarea>";
2274 $ta .= "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: green\">Input accepted.</p>";
2283 global $HTTP_POST_VARS;
2284 if ($v = $HTTP_POST_VARS[$this->config_item_name])
2287 return ini_get($this->get_config_item_name);
2290 function _config_format($value) {
2291 return sprintf("ini_set('%s', '%s');", $this->get_config_item_name(), $value);
2293 function _get_config_line($posted_value) {
2294 if ($posted_value && ! $posted_value == $this->default_value)
2295 return "\n" . $this->_config_format($posted_value);
2297 return "\n;" . $this->_config_format($this->default_value);
2302 class boolean_define
2306 // adds ->values property, instead of ->default_value
2307 function boolean_define($config_item_name, $values = false, $description = '', $jscheck = '')
2309 $this->config_item_name = $config_item_name;
2311 $description = text_from_dist($config_item_name);
2312 $this->description = $description;
2313 // TESTME: get boolean default value from config-default.ini
2314 if (defined($config_item_name))
2315 $this->default_value = constant($config_item_name); // ignore given default value
2316 elseif (is_array($values))
2317 list($this->default_value, $dummy) = $values[0];
2319 $values = array('false' => "Disabled",
2320 'true' => "Enabled");
2321 $this->values = $values;
2322 $this->jscheck = $jscheck;
2326 function _get_config_line($posted_value)
2328 if ($this->description)
2330 return "${n}" . $this->_config_format($posted_value);
2333 function _config_format($value)
2335 if (strtolower(trim($value)) == 'false')
2337 return sprintf("%s = %s", $this->get_config_item_name(),
2338 (bool)$value ? 'true' : 'false');
2341 //TODO: radiobuttons, no list
2344 $output = $this->get_config_item_header();
2345 $name = $this->get_config_item_name();
2346 $output .= '<select name="' . $name . "\" {$this->jscheck}>\n";
2347 $values = $this->values;
2348 $default_value = $this->default_value ? 'true' : 'false';
2349 /* There can usually only be two options, there can be
2350 * three options in the case of a boolean_define_commented_optional */
2351 while (list($option, $label) = each($values)) {
2352 if (!is_null($this->default_value) and $option === $default_value)
2353 $output .= " <option value=\"$option\" selected=\"selected\">$label</option>\n";
2355 $output .= " <option value=\"$option\">$label</option>\n";
2357 $output .= "</select>\n";
2362 class boolean_define_optional
2363 extends boolean_define
2367 class boolean_define_commented
2368 extends boolean_define
2370 function _get_config_line($posted_value)
2372 if ($this->description)
2374 list($default_value, $label) = each($this->default_value);
2375 if ($posted_value == $default_value)
2376 return "${n};" . $this->_config_format($posted_value);
2377 elseif ($posted_value == '')
2378 return "${n};" . $this->_config_format('false'); else
2379 return "${n}" . $this->_config_format($posted_value);
2383 class boolean_define_commented_optional
2384 extends boolean_define_commented
2396 function get_config($posted_value)
2398 $d = stripHtml($this->_get_description());
2400 return "\n" . $SEPARATOR . str_replace("\n", "\n; ", $d) . "\n" . $this->default_value;
2403 function get_instructions($title)
2405 $id = preg_replace("/\W/", "", $this->config_item_name);
2406 $group_name = preg_replace("/\W/", "", $title);
2407 $i = '<tr class="header" id="'.$id.'">'."\n";
2408 $i .= '<td class="part" style="width:100%;background-color:#eee" colspan="2">'."\n";
2409 $i .= "<h2>" . $title . "</h2>\n " . nl2p($this->_get_description()) . "\n";
2410 $i .= "<p><a href=\"javascript:toggle_group('$id')\" id=\"{$id}_text\">Hide options.</a></p>";
2411 return $i . "</td>\n";
2420 // html utility functions
2421 function nl2p($text)
2423 preg_match_all("@\s*(<pre>.*?</pre>|<dl>.*?</dl>|.*?(?=\n\n|<pre>|<dl>|$))@s",
2424 $text, $m, PREG_PATTERN_ORDER);
2427 foreach ($m[1] as $par) {
2428 if (!($par = trim($par)))
2430 if (!preg_match('/^<(pre|dl)>/', $par))
2431 $par = "<p>$par</p>";
2437 function text_from_dist($var)
2439 static $distfile = 0;
2443 $sep = (substr(PHP_OS, 0, 3) == 'WIN' ? '\\' : '/');
2444 $distfile = dirname(__FILE__) . $sep . "config" . $sep . "config-dist.ini";
2445 $f = fopen($distfile, "r");
2447 if ($var == '_MAGIC_CLOSE_FILE') {
2451 // if all vars would be in natural order as in the config-dist this would not be needed.
2456 if (preg_match("/^; \w/", $s)) {
2457 $par .= (substr($s, 2) . " ");
2458 } elseif (preg_match("/^;\s*$/", $s)) {
2461 if (preg_match("/^;?" . preg_quote($var) . "\s*=/", $s))
2463 if (preg_match("/^\s*$/", $s)) // new paragraph
2469 function stripHtml($text)
2471 $d = str_replace("<pre>", "", $text);
2472 $d = str_replace("</pre>", "", $d);
2473 $d = str_replace("<dl>", "", $d);
2474 $d = str_replace("</dl>", "", $d);
2475 $d = str_replace("<dt>", "", $d);
2476 $d = str_replace("</dt>", "", $d);
2477 $d = str_replace("<dd>", "", $d);
2478 $d = str_replace("</dd>", "", $d);
2479 $d = str_replace("<p>", "", $d);
2480 $d = str_replace("</p>", "", $d);
2481 //restore html entities into characters
2482 // http://www.php.net/manual/en/function.htmlentities.php
2483 $trans = get_html_translation_table(HTML_ENTITIES);
2484 $trans = array_flip($trans);
2485 $d = strtr($d, $trans);
2489 include_once(dirname(__FILE__) . "/lib/stdlib.php");
2492 // Function to create better user passwords (much larger keyspace),
2493 // suitable for user passwords.
2494 // Sequence of random ASCII numbers, letters and some special chars.
2495 // Note: There exist other algorithms for easy-to-remember passwords.
2496 function random_good_password($minlength = 5, $maxlength = 8)
2499 // assume ASCII ordering (not valid on EBCDIC systems!)
2500 $valid_chars = "!#%&+-.0123456789=@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz";
2501 $start = ord($valid_chars);
2502 $end = ord(substr($valid_chars, -1));
2503 $length = mt_rand($minlength, $maxlength);
2504 while ($length > 0) {
2505 $newchar = mt_rand($start, $end);
2506 if (!strrpos($valid_chars, $newchar)) continue; // skip holes
2507 $newpass .= sprintf("%c", $newchar);
2514 function printArray($a)
2516 echo "<hr />\n<pre>\n";
2518 echo "\n</pre>\n<hr />\n";
2521 // end of class definitions
2522 /////////////////////////////
2523 // begin auto generation code
2525 if (!empty($HTTP_POST_VARS['action'])
2526 and $HTTP_POST_VARS['action'] == 'make_config'
2527 and !empty($HTTP_POST_VARS['ADMIN_USER'])
2528 and !empty($HTTP_POST_VARS['ADMIN_PASSWD'])
2531 $timestamp = date('dS \of F, Y H:i:s');
2534 ; This is a local configuration file for PhpWiki.
2535 ; It was automatically generated by the configurator script
2536 ; on the $timestamp.
2541 $posted = $GLOBALS['HTTP_POST_VARS'];
2542 /*if (defined('DEBUG'))
2543 printArray($GLOBALS['HTTP_POST_VARS']);*/
2545 foreach ($properties as $option_name => $a) {
2546 $posted_value = stripslashes($posted[$a->config_item_name]);
2547 $config .= $properties[$option_name]->get_config($posted_value);
2552 if (is_writable($fs_config_file)) {
2553 // We first check if the config-file exists.
2554 if (file_exists($fs_config_file)) {
2555 // We make a backup copy of the file
2556 $new_filename = preg_replace('/\.ini$/', '-' . time() . '.ini', $fs_config_file);
2557 if (@copy($fs_config_file, $new_filename)) {
2558 $fp = @fopen($fs_config_file, 'w');
2561 $fp = @fopen($fs_config_file, 'w');
2568 fputs($fp, utf8_encode($config));
2570 echo "<p>The configuration was written to <code><b>$config_file</b></code>.</p>\n";
2571 if ($new_filename) {
2572 echo "<p>A backup was made to <code><b>$new_filename</b></code>.</p>\n";
2574 ; //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";
2577 echo "<p>The configuration file could <b>not</b> be written.<br />\n",
2578 " You should copy the above configuration to a file, ",
2579 "and manually save it as <code><b>config/config.ini</b></code>.</p>\n";
2582 echo "<hr />\n<p>Here's the configuration file based on your answers:</p>\n";
2583 echo "<form method=\"get\" action=\"", $configurator, "\">\n";
2584 echo "<textarea id='config-output' readonly='readonly' style='width:100%;' rows='30' cols='100'>\n";
2585 echo htmlentities($config, ENT_COMPAT, "UTF-8");
2586 echo "</textarea></form>\n";
2589 echo "<p>To make any corrections, <a href=\"configurator.php\">edit the settings again</a>.</p>\n";
2591 } else { // first time or create password
2592 $posted = $GLOBALS['HTTP_POST_VARS'];
2593 // No action has been specified - we make a form.
2595 if (!empty($GLOBALS['HTTP_GET_VARS']['start_debug']))
2596 $configurator .= ("?start_debug=" . $GLOBALS['HTTP_GET_VARS']['start_debug']);
2598 <form action="', $configurator, '" method="post">
2599 <input type="hidden" name="action" value="make_config" />
2600 <table cellpadding="4" cellspacing="0">
2603 while (list($property, $obj) = each($properties)) {
2604 echo $obj->get_instructions($property);
2605 if ($h = $obj->get_html()) {
2606 if (defined('DEBUG') and DEBUG) $h = get_class($obj) . "<br />\n" . $h;
2607 echo "<td>" . $h . "</td>\n";
2614 <p><input type="submit" id="submit" value="Save ', $config_file, '" /> <input type="reset" value="Clear" /></p>