2 // $Id: configurator.php,v 1.24 2005-02-15 15:58:37 rurban Exp $
4 * Started automatically the first time by IniConfig("config/config.ini") if it doesn't exist
7 * fix SQL quotes, AUTH_ORDER quotes and file forward slashes
8 * read config-default.ini
9 * read config-dist.ini into sections, comments, and optional/required settings
12 * validate input (fix javascript, add POST checks)
13 * start this automatically the first time
15 * eval index-user.php or index.php to get the actual settings.
16 * ask to store it in index.php or index-user.php
18 * A file config/config.ini will be generated.
22 $config_file = (substr(PHP_OS,0,3) == 'WIN') ? 'config\\config.ini' : 'config/config.ini';
23 $fs_config_file = dirname(__FILE__) . (substr(PHP_OS,0,3) == 'WIN' ? '\\' : '/') . $config_file;
24 if (isset($HTTP_POST_VARS['create'])) header('Location: configurator.php?create=1#create');
25 printf("<?xml version=\"1.0\" encoding=\"%s\"?>\n", 'iso-8859-1');
27 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
28 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
29 <html xmlns="http://www.w3.org/1999/xhtml">
31 <!-- $Id: configurator.php,v 1.24 2005-02-15 15:58:37 rurban Exp $ -->
32 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
33 <title>Configuration tool for PhpWiki <?php echo $config_file ?></title>
34 <style type="text/css" media="screen">
36 /* TABLE { border: thin solid black } */
37 body { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 80%; }
38 pre { font-size: 120%; }
39 td { border: thin solid black }
41 tr.hidden { border: none; display: none; }
42 td.part { background-color: #eeeeee; color: inherit; }
43 td.instructions { background-color: #ffffee; width: <?php echo $tdwidth ?>px; color: inherit; }
44 td.unchangeable-variable-top { border-bottom: none; background-color: #ffffee; color:inherit; }
45 td.unchangeable-variable-left { border-top: none; background-color: #ffffee; color:inherit; }
48 <script language="JavaScript" type="text/javascript">
50 function update(accepted, error, value, output) {
52 document.getElementById(output).innerHTML = "<font color=\"green\">Input accepted.</font>";
54 while ((index = error.indexOf("%s")) > -1) {
55 error = error.substring(0, index) + value + error.substring(index+2);
57 document.getElementById(output).innerHTML = "<font color=\"red\">" + error + "</font>";
61 function validate(error, value, output, field) {
62 update(field.value == value, error, field.value, output);
65 function validate_ereg(error, ereg, output, field) {
66 regex = new RegExp(ereg);
67 update(regex.test(field.value), error, field.value, output);
70 function validate_range(error, low, high, empty_ok, output, field) {
71 update((empty_ok == 1 && field.value == "") ||
72 (field.value >= low && field.value <= high),
73 error, field.value, output);
76 function toggle_group(id) {
77 var text = document.getElementById(id + "_text");
79 if (text.innerHTML == "Hide options.") {
81 text.innerHTML = "Show options.";
83 text.innerHTML = "Hide options.";
86 var rows = document.getElementsByTagName('tr');
88 for (i = 0; i < rows.length; i++) {
90 if (tr.className == 'header' && tr.id == id) {
95 for (; i < rows.length; i++) {
97 if (tr.className == 'header')
99 tr.className = do_hide ? 'hidden': 'nonhidden';
104 // Hide all groups. We do this via JavaScript to avoid
105 // hiding the groups if JavaScript is not supported...
106 var rows = document.getElementsByTagName('tr');
107 for (var i = 0; i < rows.length; i++) {
109 if (tr.className == 'header')
113 // Select text in textarea upon focus
114 var area = document.getElementById('config-output');
116 listener = { handleEvent: function (e) { area.select(); } };
117 area.addEventListener('focus', listener, false);
124 <body onload="do_init();">
126 <h1>Configuration for PhpWiki <?php echo $config_file ?></h1>
129 //define('DEBUG', 1);
131 * The Configurator is a php script to aid in the configuration of PhpWiki.
132 * Parts of this file are based on PHPWeather's configurator.php file.
133 * http://sourceforge.net/projects/phpweather/
135 * TO CHANGE THE CONFIGURATION OF YOUR PHPWIKI, DO *NOT* MODIFY THIS FILE!
136 * more instructions go here
139 * * start this automatically the first time
141 * * eval index.php to get the actual settings.
142 * * ask to store it in index.php or settings.php
145 //////////////////////////////
146 // begin configuration options
149 * Notes for the description parameter of $property:
151 * - Descriptive text will be changed into comments (preceeded by //)
152 * for the final output to index.php.
154 * - Only a limited set of html is allowed: pre, dl dt dd; it will be
155 * stripped from the final output.
157 * - Line breaks and spacing will be preserved for the final output.
159 * - Double line breaks are automatically converted to paragraphs
160 * for the html version of the descriptive text.
162 * - Double-quotes and dollar signs in the descriptive text must be
163 * escaped: \" and \$. Instead of escaping double-quotes you can use
164 * single (') quotes for the enclosing quotes.
166 * - Special characters like < and > must use html entities,
167 * they will be converted back to characters for the final output.
170 $SEPARATOR = ";=========================================================================";
173 ; This is the main configuration file for PhpWiki.
174 ; Note that certain characters are used as comment char and therefore
175 ; these entries must be in double-quotes. Such as \":\", \";\", \",\" and \"|\"
177 ; This file is divided into eight parts: Parts Zero, One, Two, Three,
178 ; Four, Five, Six and Seven. Each one has different configuration settings you can
179 ; change; in all cases the default should work on your system,
180 ; however, we recommend you tailor things to your particular setting.
183 $properties["Part Zero"] =
184 new part('_part0', $SEPARATOR."\n", "
185 Part Zero: (optional)
186 Latest Development and Tricky Options");
188 if (substr(PHP_OS,0,3) == 'WIN') {
189 $include_path = dirname(__FILE__) . ';' . ini_get('include_path');
190 if (strchr(ini_get('include_path'),'/'))
191 $include_path = strtr($include_path,'\\','/');
193 $include_path = dirname(__FILE__) . ':' . ini_get('include_path');
196 $properties["PHP include_path"] =
197 new _define_optional('INCLUDE_PATH', ini_get('include_path'), "
198 If PHP needs help in finding where you installed the rest of the PhpWiki
199 code, you can set the include_path here.
201 Override the PHP include path so that it can find some needed additional libraries.
202 You shouldn't need to do this unless your system include_path esp. your
203 system pear libs are broken or oudated. The PHPWIKI_DIR is automatically
204 put to the front and the local lib/pear path is automatically added to the end.
205 But if you define it, be sure to include either the system pear path or
206 the phpwiki/lib/pear path to override your Pear_DB.
207 Note that on Windows-based servers, you should use ; rather than :
208 as the path separator.");
210 $properties["DEBUG"] =
211 new _define_optional('DEBUG', '0', "
212 Set DEBUG to 1 to view the XHTML and CSS validator icons, page
213 processing timer, and possibly other debugging messages at the
214 bottom of each page. 65 for a more verbose level.
215 See lib/config.php for all supported values.");
217 $properties["ENABLE_USER_NEW"] =
218 new boolean_define_commented_optional
220 array('true' => "Enabled",
221 'false' => "Disabled."), "
222 Enable the new method of handling WikiUser Authetincation and Preferences.
223 It's best to leave it on, and only disable it if you have problems with it.
224 Servers with memory-limit problems might want to turn it off. It costs ~300KB
227 $properties["ENABLE_PAGEPERM"] =
228 new boolean_define_commented_optional
230 array('true' => "Enabled",
231 'false' => "Disabled."), "
232 I suspect ACL page permissions to degrade speed by 10%. Default: true");
234 $properties["ENABLE_EDIT_TOOLBAR"] =
235 new boolean_define_commented_optional
236 ('ENABLE_EDIT_TOOLBAR',
237 array('true' => "Enabled",
238 'false' => "Disabled."), "
239 Graphical buttons on edit. Default: true
240 Reportedly broken on MacOSX Safari");
242 $properties["JS_SEARCHREPLACE"] =
243 new boolean_define_commented_optional
245 array('true' => "Enabled",
246 'false' => "Disabled."), "
247 Adds two additional buttons in EDIT_TOOLBAR, Search&Replace and Undo.
248 Undo is experimental.");
250 $properties["ENABLE_DOUBLECLICKEDIT"] =
251 new boolean_define_commented_optional
252 ('ENABLE_DOUBLECLICKEDIT',
253 array('true' => "Enabled",
254 'false' => "Disabled."), "
257 $properties["ENABLE_XHTML_XML"] =
258 new boolean_define_commented_optional
260 array('true' => "Enabled",
261 'false' => "Disabled."), "
262 Needed for inlined SVG and MathM, but may conflict with document.write().
263 Experimental. Default: false");
265 $properties["USECACHE"] =
266 new boolean_define_commented_optional
268 array('true' => "Enabled",
269 'false' => "Disabled."), "
270 Store DB query results in memory to avoid duplicate queries.
271 Disable only for old php's with low memory or memory_limit=8MB.
274 $properties["ENABLE_SPAMASSASSIN"] =
275 new boolean_define_commented_optional
276 ('ENABLE_SPAMASSASSIN',
277 array('true' => "Enabled",
278 'false' => "Disabled."), "
279 Needs babycart installed. See http://phpwiki.org/SpamAssassinIntegration
280 Optionally define BABYCART_PATH. Default: /usr/local/bin/babycart");
282 $properties["GOOGLE_LINKS_NOFOLLOW"] =
283 new boolean_define_commented_optional
284 ('GOOGLE_LINKS_NOFOLLOW',
285 array('true' => "Enabled",
286 'false' => "Disabled."), "
287 If enabled ref=nofollow is added to all external links to discourage spam.
288 You might want to turn it off, if you want to improve pageranks on external links.");
290 $properties["ENABLE_LIVESEARCH"] =
291 new boolean_define_commented_optional
292 ('ENABLE_LIVESEARCH',
293 array('true' => "Enabled",
294 'false' => "Disabled."), "
295 LiveSearch enables immediate title search results via XMLHttpRequest.
296 Displays the results in a dropdown under the titlesearch inputbox
297 while typing. (experimental, only with certain themes)
298 You'll have to copy livesearch.js from http://blog.bitflux.ch/wiki/LiveSearch
299 to themes/default/ and define ENABLE_LIVESEARCH in config.ini to true.
300 See themes/blog/themeinfo.php.
301 Currently we use the bitflux.ch library, but we will change to
302 the russian acdropdown soon. http://momche.net/publish/article.php?page=acdropdown");
304 $properties["Part One"] =
305 new part('_partone', $SEPARATOR."\n", "
306 Part One: Authentication and security settings. See Part Three for more.");
308 $properties["Admin Username"] =
309 new _define_optional_notempty('ADMIN_USER', "", "
310 You must set this! Username and password of the administrator.",
311 "onchange=\"validate_ereg('Sorry, ADMIN_USER cannot be empty.', '^.+$', 'ADMIN_USER', this);\"");
313 $properties["Admin Password"] =
314 new _define_password_optional('ADMIN_PASSWD', "", "
315 For heaven's sake pick a good password.
316 If your version of PHP supports encrypted passwords, your password will be
317 automatically encrypted within the generated config file.
318 Use the \"Create Random Password\" button to create a good (random) password.",
319 "onchange=\"validate_ereg('Sorry, ADMIN_PASSWD must be at least 4 chars long.', '^....+$', 'ADMIN_PASSWD', this);\"");
322 $properties["Wiki Name"] =
323 new _define_optional('WIKI_NAME', 'PhpWiki', "
324 The name of your wiki.
326 This is used to generate a keywords meta tag in the HTML templates,
327 in bookmark titles for any bookmarks made to pages in your wiki,
328 and during RSS generation for the title of the RSS channel.
330 It is recommended this be a relatively short WikiWord like the
331 InterWiki monikers found in the InterWikiMap. (For examples, see
335 $properties["Reverse DNS"] =
336 new boolean_define_optional
337 ('ENABLE_REVERSE_DNS',
338 array('true' => "true. perform additional reverse dns lookups",
339 'false' => "false. just record the address as given by the httpd server"),
341 If set, we will perform reverse dns lookups to try to convert the
342 users IP number to a host name, even if the http server didn't do it for us.");
344 $properties["ZIPdump Authentication"] =
345 new boolean_define_optional('ZIPDUMP_AUTH',
346 array('false' => "false. Everyone may download zip dumps",
347 'true' => "true. Only admin may download zip dumps"), "
348 If true, only the admin user can make zip dumps, else zip dumps
349 require no authentication.");
351 $properties["Enable RawHtml Plugin"] =
352 new boolean_define_commented_optional
354 array('true' => "Enabled",
355 'false' => "Disabled."), "
356 The RawHtml plugin allows page authors to embed real, raw HTML into Wiki
357 pages. This is a possible security threat, as much HTML (or, rather,
358 JavaScript) can be very risky. If you are in a controlled environment,
359 however, it could be of use.");
361 $properties["Allow RawHtml Plugin only on locked pages"] =
362 new boolean_define_commented_optional
363 ('ENABLE_RAW_HTML_LOCKEDONLY',
364 array('true' => "Enabled",
365 'false' => "Disabled."), "
366 If this is set, only pages locked by the Administrator may contain the RawHtml plugin.");
368 $properties["Allow RawHtml Plugin if safe HTML code"] =
369 new boolean_define_commented_optional
370 ('ENABLE_RAW_HTML_SAFE',
371 array('true' => "Enabled",
372 'false' => "Disabled."), "
373 If this is set, all unsafe html code is stripped automatically (experimental!)
374 See <a href=\"http://chxo.com/scripts/safe_html-test.php\" target=\"_new\">chxo.com/scripts/safe_html-test.php</a>
377 $properties["Strict Mailable Pagedumps"] =
378 new boolean_define_optional
379 ('STRICT_MAILABLE_PAGEDUMPS',
380 array('false' => "binary",
381 'true' => "quoted-printable"),
383 If you define this to true, (MIME-type) page-dumps (either zip dumps,
384 or \"dumps to directory\" will be encoded using the quoted-printable
385 encoding. If you're actually thinking of mailing the raw page dumps,
386 then this might be useful, since (among other things,) it ensures
387 that all lines in the message body are under 80 characters in length.
389 Also, setting this will cause a few additional mail headers
390 to be generated, so that the resulting dumps are valid
391 RFC 2822 e-mail messages.
393 Probably, you can just leave this set to false, in which case you get
394 raw ('binary' content-encoding) page dumps.");
396 $properties["HTML Dump Filename Suffix"] =
397 new _variable('HTML_DUMP_SUFFIX', ".html", "
398 Here you can change the filename suffix used for XHTML page dumps.
399 If you don't want any suffix just comment this out.");
401 //FIXME: should be numeric_define_optional
402 $properties["Maximum Upload Size"] =
403 new numeric_define('MAX_UPLOAD_SIZE', "16 * 1024 * 1024", "
404 The maximum file upload size.");
406 //FIXME: should be numeric_define_optional
407 $properties["Minor Edit Timeout"] =
408 new numeric_define('MINOR_EDIT_TIMEOUT', "7 * 24 * 3600", "
409 If the last edit is older than MINOR_EDIT_TIMEOUT seconds, the
410 default state for the \"minor edit\" checkbox on the edit page form
413 $properties["Disabled Actions"] =
414 new array_variable('DisabledActions', array(), "
415 Actions listed in this array will not be allowed. Actions are:
416 browse, create, diff, dumphtml, dumpserial, edit, loadfile, lock, remove,
417 unlock, upload, viewsource, zip, ziphtml");
419 $properties["Access Log"] =
420 new _define_commented('ACCESS_LOG', "/var/logs/wiki_access.log", "
421 PhpWiki can generate an access_log (in \"NCSA combined log\" format)
422 for you. If you want one, define this to the name of the log file,
423 such as /tmp/wiki_access_log.");
425 $properties["Compress Output"] =
426 new boolean_define_commented_optional
428 array('' => 'Compress when PhpWiki thinks appropriate.',
429 'false' => 'Never compress output.',
430 'true' => 'Always try to compress output.'),
432 By default PhpWiki will try to have PHP compress it's output
433 before sending it to the browser (if you have a recent enough
434 version of PHP and the browser supports it.)
436 Define COMPRESS_OUTPUT to false to prevent output compression.
438 Define COMPRESS_OUTPUT to true to force output compression,
439 even if we think your version of PHP does this in a buggy
442 Leave it undefined to leave the choice up to PhpWiki.");
444 $properties["HTTP Cache Control"] =
445 new _define_selection_optional
447 array('LOOSE' => 'LOOSE',
448 'STRICT' => 'STRICT',
449 'NO_CACHE' => 'NO_CACHE',
450 'ALLOW_STALE' => 'ALLOW_STALE'),
454 This controls how PhpWiki sets the HTTP cache control
455 headers (Expires: and Cache-Control:)
461 <dd>This is roughly the old (pre 1.3.4) behaviour. PhpWiki will
462 instruct proxies and browsers never to cache PhpWiki output.</dd>
465 <dd>Cached pages will be invalidated whenever the database global
466 timestamp changes. This should behave just like NONE (modulo
467 bugs in PhpWiki and your proxies and browsers), except that
468 things will be slightly more efficient.</dd>
471 <dd>Cached pages will be invalidated whenever they are edited,
472 or, if the pages include plugins, when the plugin output could
473 concievably have changed.
475 <p>Behavior should be much like STRICT, except that sometimes
476 wikilinks will show up as undefined (with the question mark)
477 when in fact they refer to (recently) created pages.
478 (Hitting your browsers reload or perhaps shift-reload button
479 should fix the problem.)</p></dd>
482 <dd>Proxies and browsers will be allowed to used stale pages.
483 (The timeout for stale pages is controlled by CACHE_CONTROL_MAX_AGE.)
485 <p>This setting will result in quirky behavior. When you edit a
486 page your changes may not show up until you shift-reload the
489 <p>This setting is generally not advisable, however it may be useful
490 in certain cases (e.g. if your wiki gets lots of page views,
491 and few edits by knowledgable people who won't freak over the quirks.)</p>
494 The default is currently LOOSE.");
496 // FIXME: should be numeric_define_optional
497 $properties["HTTP Cache Control Max Age"] =
498 new numeric_define('CACHE_CONTROL_MAX_AGE', 600,
500 Maximum page staleness, in seconds.");
502 $properties["Markup Caching"] =
503 new boolean_define_commented_optional
504 ('WIKIDB_NOCACHE_MARKUP',
505 array('false' => 'Enable markup cache',
506 'true' => 'Disable markup cache'),
510 PhpWiki normally caches a preparsed version (i.e. mostly
511 converted to HTML) of the most recent version of each page.
512 (Parsing the wiki-markup takes a fair amount of CPU.)
514 Define WIKIDB_NOCACHE_MARKUP to true to disable the
515 caching of marked-up page content.
517 Note that you can also disable markup caching on a per-page
518 temporary basis by addinging a query arg of '?nocache=1'
519 to the URL to the page. (Use '?nocache=purge' to completely
520 discard the cached version of the page.)
522 You can also purge the cached markup globally by using the
523 \"Purge Markup Cache\" button on the PhpWikiAdministration page.");
525 $properties["Path for PHP Session Support"] =
526 new _define_optional('SESSION_SAVE_PATH', ini_get('session.save_path'), "
527 The login code now uses PHP session support. Usually, the default
528 configuration of PHP is to store the session state information in
529 /tmp. That probably will work fine, but fails e.g. on clustered
530 servers where each server has their own distinct /tmp (this is the
531 case on SourceForge's project web server.) You can specify an
532 alternate directory in which to store state information like so
533 (whatever user your httpd runs as must have read/write permission
535 on USE_DB_SESSION = true you can ignore this.
538 ///////// database selection
540 $properties["Part Two"] =
541 new part('_parttwo', $SEPARATOR."\n", "
544 Database Configuration
547 $properties["Database Type"] =
548 new _define_selection("DATABASE_TYPE",
549 array('dba' => "dba",
551 'ADODB' => "SQL ADODB",
552 'PDO' => "PDO (php5 only)",
553 'file' => "flatfile",
554 'cvs' => "CVS File handler"), "
555 Select the database backend type:
556 Choose dba (default) to use one of the standard UNIX dba libraries. This is the fastest.
557 Choose ADODB or SQL to use an SQL database with ADODB or PEAR.
558 Choose PDO on php5 to use an SQL database.
559 flatfile is simple and slow.
560 CVS is highly experimental and slow.
561 Recommended is dba or SQL: PEAR or ADODB.");
563 $properties["SQL DSN Setup"] =
564 new unchangeable_variable('_sqldsnstuff', "", "
565 For SQL based backends, specify the database as a DSN
566 The most general form of a DSN looks like:
568 phptype(dbsyntax)://username:password@protocol+hostspec/database?option=value
570 For a MySQL database, the following should work:
572 mysql://user:password@host/databasename
574 To connect over a unix socket, use something like
576 mysql://user:password@unix(/path/to/socket)/databasename
579 DATABASE_DSN = mysql://guest@:/var/lib/mysql/mysql.sock/phpwiki
580 DATABASE_DSN = mysql://guest@localhost/phpwiki
581 DATABASE_DSN = pgsql://localhost/user_phpwiki
584 // Choose ADODB or SQL to use an SQL database with ADODB or PEAR.
585 // Choose dba to use one of the standard UNIX dbm libraries.
587 $properties["SQL Type"] =
588 new _variable_selection('_dsn_sqltype',
589 array('mysql' => "MySQL",
590 'pgsql' => "PostgreSQL",
591 'mssql' => "Microsoft SQL Server",
592 'oci8' => "Oracle 8",
593 'mysqli' => "mysqli (only ADODB)",
594 'mysqlt' => "mysqlt (only ADODB)",
595 'ODBC' => "ODBC (only ADODB or PDO)",
596 'firebird' => "Firebird (only PDO)",
597 'oracle' => "Oracle (only PDO)",
599 SQL DB types. The DSN hosttype.");
601 $properties["SQL User"] =
602 new _variable('_dsn_sqluser', "wikiuser", "
605 $properties["SQL Password"] =
606 new _variable('_dsn_sqlpass', "", "
609 $properties["SQL Database Host"] =
610 new _variable('_dsn_sqlhostorsock', "localhost", "
611 SQL Database Hostname:
613 To connect over a local named socket, use something like
615 unix(/var/lib/mysql/mysql.sock)
618 mysql on Windows via named pipes might need 127.0.0.1");
620 $properties["SQL Database Name"] =
621 new _variable('_dsn_sqldbname', "phpwiki", "
622 SQL Database Name:");
624 $dsn_sqltype = $properties["SQL Type"]->value();
625 $dsn_sqluser = $properties["SQL User"]->value();
626 $dsn_sqlpass = $properties["SQL Password"]->value();
627 $dsn_sqlhostorsock = $properties["SQL Database Host"]->value();
628 $dsn_sqldbname = $properties["SQL Database Name"]->value();
629 $dsn_sqlstring = $dsn_sqltype."://{$dsn_sqluser}:{$dsn_sqlpass}@{$dsn_sqlhostorsock}/{$dsn_sqldbname}";
631 $properties["SQL dsn"] =
632 new unchangeable_define("DATABASE_DSN",
633 "DATABASE_DSN = \"$dsn_sqlstring\"", "
634 Calculated from the settings above:");
636 $properties["Filename / Table name Prefix"] =
637 new _define_commented("DATABASE_PREFIX", "", "
638 Used by all DB types:
640 Prefix for filenames or table names, e.g. \"phpwiki_\"
642 Currently <b>you MUST EDIT THE SQL file too!</b> (in the schemas/
643 directory because we aren't doing on the fly sql generation
644 during the installation.");
646 $properties["DB Session table"] =
647 new _define_optional("DATABASE_SESSION_TABLE", "session", "
648 Tablename to store session information. Only supported by SQL backends.
650 A word of warning - any prefix defined above will be prepended to whatever is given here.
654 $temp = !empty($_ENV['TEMP']) ? $_ENV['TEMP'] : "/tmp";
655 $properties["dba directory"] =
656 new _define("DATABASE_DIRECTORY", $temp, "
659 // TODO: list the available methods
660 $properties["dba handler"] =
661 new _define_selection('DATABASE_DBA_HANDLER',
662 array('gdbm' => "Gdbm - GNU database manager (recommended)",
663 'dbm' => "DBM - Redhat default. On sf.net there's dbm and gdbm",
664 'db2' => "DB2 - Sleepycat Software's DB2",
665 'db3' => "DB3 - Sleepycat Software's DB3. Default on Windows but not on every Linux",
666 'db4' => "DB4 - Sleepycat Software's DB4."), "
667 Use 'gdbm', 'dbm', 'db2', 'db3' or 'db4' depending on your DBA handler methods supported: <br > "
668 . (function_exists("dba_handlers") ? join(", ",dba_handlers()) : ""));
670 $properties["dba timeout"] =
671 new numeric_define("DATABASE_TIMEOUT", "12", "
672 Recommended values are 10-20.");
676 $properties["Page Revisions"] =
677 new unchangeable_variable('_parttworevisions', "", "
679 Section 2a: Archive Cleanup
680 The next section controls how many old revisions of each page are kept in the database.
682 There are two basic classes of revisions: major and minor. Which
683 class a revision belongs in is determined by whether the author
684 checked the \"this is a minor revision\" checkbox when they saved the
687 There is, additionally, a third class of revisions: author
688 revisions. The most recent non-mergable revision from each distinct
689 author is and author revision.
691 The expiry parameters for each of those three classes of revisions
692 can be adjusted seperately. For each class there are five
693 parameters (usually, only two or three of the five are actually
694 set) which control how long those revisions are kept in the
697 <dt>max_keep:</dt> <dd>If set, this specifies an absolute maximum for the
698 number of archived revisions of that class. This is
699 meant to be used as a safety cap when a non-zero
700 min_age is specified. It should be set relatively high,
701 and it's purpose is to prevent malicious or accidental
702 database overflow due to someone causing an
703 unreasonable number of edits in a short period of time.</dd>
705 <dt>min_age:</dt> <dd>Revisions younger than this (based upon the supplanted
706 date) will be kept unless max_keep is exceeded. The age
707 should be specified in days. It should be a
708 non-negative, real number,</dd>
710 <dt>min_keep:</dt> <dd>At least this many revisions will be kept.</dd>
712 <dt>keep:</dt> <dd>No more than this many revisions will be kept.</dd>
714 <dt>max_age:</dt> <dd>No revision older than this age will be kept.</dd>
716 Supplanted date: Revisions are timestamped at the instant that they
717 cease being the current revision. Revision age is computed using
718 this timestamp, not the edit time of the page.
720 Merging: When a minor revision is deleted, if the preceding
721 revision is by the same author, the minor revision is merged with
722 the preceding revision before it is deleted. Essentially: this
723 replaces the content (and supplanted timestamp) of the previous
724 revision with the content after the merged minor edit, the rest of
725 the page metadata for the preceding version (summary, mtime, ...)
729 // For now the expiration parameters are statically inserted as
730 // an unchangeable property. You'll have to edit the resulting
731 // config file if you really want to change these from the default.
733 $properties["Major Edits: keep minumum days"] =
734 new numeric_define("MAJOR_MIN_KEEP", "2147483647", "
735 Default: Keep at least for unlimited time.
736 Set to 0 to enable archive cleanup");
737 $properties["Minor Edits: keep minumum days"] =
738 new numeric_define("MINOR_MIN_KEEP", "2147483647", "
739 Default: Keep at least for unlimited time.
740 Set to 0 to enable archive cleanup");
742 $properties["Major Edits: how many"] =
743 new numeric_define("MAJOR_KEEP", "8", "
744 Keep up to 8 major edits");
745 $properties["Major Edits: how many days"] =
746 new numeric_define("MAJOR_MAX_AGE", "32", "
747 keep them no longer than a month");
749 $properties["Minor Edits: how many"] =
750 new numeric_define("MINOR_KEEP", "4", "
751 Keep up to 4 minor edits");
752 $properties["Minor Edits: how many days"] =
753 new numeric_define("MINOR_MAX_AGE", "7", "
754 keep them no longer than a week");
756 $properties["per Author: how many"] =
757 new numeric_define("AUTHOR_KEEP", "8", "
758 Keep the latest contributions of the last 8 authors,");
759 $properties["per Author: how many days"] =
760 new numeric_define("AUTHOR_MAX_AGE", "365", "
762 $properties["per Author: keep minumum days"] =
763 new numeric_define("AUTHOR_MIN_AGE", "7", "
764 Additionally, (in the case of a particularly active page) try to
765 keep the latest contributions of all authors in the last week (even if there are more than eight of them,)");
766 $properties["per Author: max revisions"] =
767 new numeric_define("AUTHOR_MAX_KEEP", "20", "
768 but in no case keep more than twenty unique author revisions.");
770 /////////////////////////////////////////////////////////////////////
772 $properties["Part Three"] =
773 new part('_partthree', $SEPARATOR."\n", "
775 Part Three: (optional)
776 Basic User Authentication Setup
779 $properties["Publicly viewable"] =
780 new boolean_define_optional('ALLOW_ANON_USER',
781 array('true' => "true. Permit anonymous view. (Default)",
782 'false' => "false. Force login even on view (strictly private)"), "
783 If ALLOW_ANON_USER is false, you have to login before viewing any page or doing any other action on a page.");
785 $properties["Allow anonymous edit"] =
786 new boolean_define_optional('ALLOW_ANON_EDIT',
787 array('true' => "true. Permit anonymous users to edit. (Default)",
788 'false' => "false. Force login on edit (moderately locked)"), "
789 If ALLOW_ANON_EDIT is false, you have to login before editing or changing any page. See below.");
791 $properties["Allow Bogo Login"] =
792 new boolean_define_optional('ALLOW_BOGO_LOGIN',
793 array('true' => "true. Users may Sign In with any WikiWord, without password. (Default)",
794 'false' => "false. Require stricter authentication."), "
795 If ALLOW_BOGO_LOGIN is false, you may not login with any wikiword username and empty password.
796 If true, users are allowed to create themselves with any WikiWord username. See below.");
798 $properties["Allow User Passwords"] =
799 new boolean_define_optional('ALLOW_USER_PASSWORDS',
800 array('true' => "True user authentication with password checking. (Default)",
801 'false' => "false. Ignore authentication settings below."), "
802 If ALLOW_USER_PASSWORDS is true, the authentication settings below define where and how to
803 check against given username/passwords. For completely security disable BOGO_LOGIN and ANON_EDIT above.");
805 $properties["Allow User Passwords"] =
806 new array_define('USER_AUTH_ORDER', array("PersonalPage", "Db"), "
807 Many different methods can be used to check user's passwords.
808 Try any of these in the given order:
811 <dd>WikiWord username, with no *actual* password checking,
812 although the user will still have to enter one.</dd>
813 <dt>PersonalPage</dt>
814 <dd>Store passwords in the users homepage metadata (simple)</dd>
816 <dd>Use DBAUTH_AUTH_* (see below) with PearDB or ADODB only.</dd>
818 <dd>Authenticate against LDAP_AUTH_HOST with LDAP_BASE_DN</dd>
820 <dd>Authenticate against IMAP_AUTH_HOST (email account)</dd>
822 <dd>Authenticate against POP3_AUTH_HOST (email account)</dd>
824 <dd>Get username and level from a PHP session variable. (e.g. for gforge)</dd>
826 <dd>Store username:crypted-passwords in .htaccess like files.
827 Use Apache's htpasswd to manage this file.</dd>
829 <dd>Use the protection by the webserver (.htaccess/.htpasswd) (experimental)
830 Enforcing HTTP Auth not yet. Note that the ADMIN_USER should exist also.
831 Using HttpAuth disables all other methods and no userauth sessions are used.</dd>
834 Several of these methods can be used together, in the manner specified by
835 USER_AUTH_POLICY, below. To specify multiple authentication methods,
836 separate the name of each one with colons.
838 USER_AUTH_ORDER = 'PersonalPage : Db'
839 USER_AUTH_ORDER = 'BogoLogin : PersonalPage'</pre>");
841 $properties["PASSWORD_LENGTH_MINIMUM"] =
842 new numeric_define("PASSWORD_LENGTH_MINIMUM", "6", "
843 For 'security' purposes, you can specify that a password be at least a
844 certain number of characters long. This applies even to the BogoLogin method.
845 Default: 0 (to allow immediate passwordless BogoLogin)");
847 $properties["USER_AUTH_POLICY"] =
848 new _define_selection('USER_AUTH_POLICY',
849 array('first-only' => "first-only - use only the first method in USER_AUTH_ORDER",
850 'old' => "old - ignore USER_AUTH_ORDER (legacy)",
851 'strict' => "strict - check all methods for userid + password (recommended)",
852 'stacked' => "stacked - check all methods for userid, and if found for password"), "
853 The following policies are available for user authentication:
856 <dd>use only the first method in USER_AUTH_ORDER</dd>
858 <dd>ignore USER_AUTH_ORDER and try to use all available
859 methods as in the previous PhpWiki releases (slow)</dd>
861 <dd>check if the user exists for all methods:
862 on the first existing user, try the password.
863 dont try the other methods on failure then</dd>
865 <dd>check the given user - password combination for all
866 methods and return true on the first success.</dd></dl>");
870 $properties["Part Three A"] =
871 new part('_partthree_a', $SEPARATOR."\n", "
873 Part Three A: (optional)
876 $properties["Group membership"] =
877 new _define_selection("GROUP_METHOD",
878 array('WIKIPAGE' => "WIKIPAGE - List at \"CategoryGroup\". (Slowest, but easiest to maintain)",
879 '"NONE"' => "NONE - Disable group membership (Fastest)",
880 'DB' => "DB - SQL Database, Optionally external. See USERS/GROUPS queries",
881 'FILE' => "Flatfile. See AUTH_GROUP_FILE below.",
882 'LDAP' => "LDAP - See \"LDAP authentication options\" above. (Experimental)"), "
883 Group membership. PhpWiki supports defining permissions for a group as
884 well as for individual users. This defines how group membership information
885 is obtained. Supported values are:
888 <dd>Disable group membership (Fastest). Note the required quoting.</dd>
890 <dd>Define groups as list at \"CategoryGroup\". (Slowest, but easiest to maintain)</dd>
892 <dd>Stored in an SQL database. Optionally external. See USERS/GROUPS queries</dd>
894 <dd>Flatfile. See AUTH_GROUP_FILE below.</dd>
896 <dd>LDAP groups. See \"LDAP authentication options\" above and
897 lib/WikiGroup.php. (experimental)</dd></dl>");
899 $properties["CATEGORY_GROUP_PAGE"] =
900 new _define_optional('CATEGORY_GROUP_PAGE', _("CategoryGroup"), "
901 If GROUP_METHOD = WIKIPAGE:
903 Page where all groups are listed.");
905 $properties["AUTH_GROUP_FILE"] =
906 new _define_optional('AUTH_GROUP_FILE', _("/etc/groups"), "
907 For GROUP_METHOD = FILE, the file given below is referenced to obtain
908 group membership information. It should be in the same format as the
909 standard unix /etc/groups(5) file.");
911 $properties["Part Three B"] =
912 new part('_partthree_b', $SEPARATOR."\n", "
914 Part Three B: (optional)
915 External database authentication and authorization.
917 If USER_AUTH_ORDER includes Db, or GROUP_METHOD = DB, the options listed
918 below define the SQL queries used to obtain the information out of the
919 database, and (optionally) store the information back to the DB.");
921 $properties["DBAUTH_AUTH_DSN"] =
922 new _define_optional('DBAUTH_AUTH_DSN', $dsn_sqlstring, "
923 A database DSN to connect to. Defaults to the DSN specified for the Wiki as a whole.");
925 $properties["User Exists Query"] =
926 new _define('DBAUTH_AUTH_USER_EXISTS', "\"SELECT userid FROM user WHERE userid='\$userid'\"", "
927 USER/PASSWORD queries:
929 For USER_AUTH_POLICY=strict and the Db method is required");
931 $properties["Check Query"] =
932 new _define_optional('DBAUTH_AUTH_CHECK', "\"SELECT IF(passwd='\$password',1,0) AS ok FROM user WHERE userid='\$userid'\"", "
934 Check to see if the supplied username/password pair is OK
936 Plaintext passwords: (DBAUTH_AUTH_CRYPT_METHOD = plain)<br>
937 ; DBAUTH_AUTH_CHECK = \"SELECT IF(passwd='\$password',1,0) AS ok FROM user WHERE userid='\$userid'\"
939 database-hashed passwords (more secure):<br>
940 ; DBAUTH_AUTH_CHECK = \"SELECT IF(passwd=PASSWORD('\$password'),1,0) AS ok FROM user WHERE userid='\$userid'\"");
942 $properties["Crypt Method"] =
943 new _define_selection_optional
944 ('DBAUTH_AUTH_CRYPT_METHOD',
945 array('plain' => 'plain',
946 'crypt' => 'crypt'), "
947 If you want to use Unix crypt()ed passwords, you can use DBAUTH_AUTH_CHECK
948 to get the password out of the database with a simple SELECT query, and
949 specify DBAUTH_AUTH_USER_EXISTS and DBAUTH_AUTH_CRYPT_METHOD:
951 ; DBAUTH_AUTH_CHECK = \"SELECT passwd FROM user where userid='\$userid'\" <br>
952 ; DBAUTH_AUTH_CRYPT_METHOD = crypt");
954 $properties["Update the user's authentication credential"] =
955 new _define('DBAUTH_AUTH_UPDATE', "\"UPDATE user SET passwd='\$password' WHERE userid='\$userid'\"", "
956 If this is not defined but DBAUTH_AUTH_CHECK is, then the user will be unable to update their
959 Plaintext passwords:<br>
960 DBAUTH_AUTH_UPDATE = \"UPDATE user SET passwd='\$password' WHERE userid='\$userid'\"<br>
961 Database-hashed passwords:<br>
962 DBAUTH_AUTH_UPDATE = \"UPDATE user SET passwd=PASSWORD('\$password') WHERE userid='\$userid'\"");
964 $properties["Allow the user to create their own account"] =
965 new _define_optional('DBAUTH_AUTH_CREATE', "\"INSERT INTO user SET passwd=PASSWORD('\$password'),userid='\$userid'\"", "
966 If this is empty, Db users cannot subscribe by their own.");
968 $properties["USER/PREFERENCE queries"] =
969 new _define_optional('DBAUTH_PREF_SELECT', "\"SELECT prefs FROM user WHERE userid='\$userid'\"", "
970 If you choose to store your preferences in an external database, enable
971 the following queries. Note that if you choose to store user preferences
972 in the 'user' table, only registered users get their prefs from the database,
973 self-created users do not. Better to use the special 'pref' table.
975 The prefs field stores the serialized form of the user's preferences array,
976 to ease the complication of storage.
978 DBAUTH_PREF_SELECT = \"SELECT prefs FROM user WHERE userid='\$userid'\"
979 DBAUTH_PREF_SELECT = \"SELECT prefs FROM pref WHERE userid='\$userid'\"
982 $properties["Update the user's preferences"] =
983 new _define_optional('DBAUTH_PREF_UPDATE', "\"UPDATE user SET prefs='\$pref_blob' WHERE userid='\$userid'\"", "
984 Note that REPLACE works only with mysql and destroy all other columns!
986 Mysql: DBAUTH_PREF_UPDATE = \"REPLACE INTO pref SET prefs='\$pref_blob',userid='\$userid'\"");
988 $properties["USERS/GROUPS queries"] =
989 new _define_optional('DBAUTH_IS_MEMBER', "\"SELECT user FROM user WHERE user='\$userid' AND group='\$groupname'\"", "
990 You can define 1:n or n:m user<=>group relations, as you wish.
992 Sample configurations:
994 only one group per user (1:n):<br>
995 DBAUTH_IS_MEMBER = \"SELECT user FROM user WHERE user='\$userid' AND group='\$groupname'\"<br>
996 DBAUTH_GROUP_MEMBERS = \"SELECT user FROM user WHERE group='\$groupname'\"<br>
997 DBAUTH_USER_GROUPS = \"SELECT group FROM user WHERE user='\$userid'\"<br>
998 multiple groups per user (n:m):<br>
999 DBAUTH_IS_MEMBER = \"SELECT userid FROM member WHERE userid='\$userid' AND groupname='\$groupname'\"<br>
1000 DBAUTH_GROUP_MEMBERS = \"SELECT DISTINCT userid FROM member WHERE groupname='\$groupname'\"<br>
1001 DBAUTH_USER_GROUPS = \"SELECT groupname FROM member WHERE userid='\$userid'\"<br>");
1002 $properties["DBAUTH_GROUP_MEMBERS"] =
1003 new _define_optional('DBAUTH_GROUP_MEMBERS', "\"SELECT user FROM user WHERE group='\$groupname'\"", "");
1004 $properties["DBAUTH_USER_GROUPS"] =
1005 new _define_optional('DBAUTH_USER_GROUPS', "\"SELECT group FROM user WHERE user='\$userid'\"", "");
1007 if (function_exists('ldap_connect')) {
1009 $properties["LDAP AUTH Host"] =
1010 new _define_optional('LDAP_AUTH_HOST', "ldap://localhost:389", "
1011 If USER_AUTH_ORDER contains Ldap:
1013 The LDAP server to connect to. Can either be a hostname, or a complete
1014 URL to the server (useful if you want to use ldaps or specify a different
1017 $properties["LDAP BASE DN"] =
1018 new _define_optional('LDAP_BASE_DN', "ou=mycompany.com,o=My Company", "
1019 The organizational or domain BASE DN: e.g. \"dc=mydomain,dc=com\".
1021 Note: ou=Users and ou=Groups are used for GroupLdap Membership
1022 Better use LDAP_OU_USERS and LDAP_OU_GROUP with GROUP_METHOD=LDAP.");
1024 $properties["LDAP SET OPTION"] =
1025 new _define_optional('LDAP_SET_OPTION', "LDAP_OPT_PROTOCOL_VERSION=3:LDAP_OPT_REFERRALS=0", "
1026 Some LDAP servers need some more options, such as the Windows Active
1027 Directory Server. Specify the options (as allowed by the PHP LDAP module)
1028 and their values as NAME=value pairs separated by colons.");
1030 $properties["LDAP AUTH USER"] =
1031 new _define_optional('LDAP_AUTH_USER', "CN=ldapuser,ou=Users,o=Development,dc=mycompany.com", "
1032 DN to initially bind to the LDAP server as. This is needed if the server doesn't
1033 allow anonymous queries. (Windows Active Directory Server)");
1035 $properties["LDAP AUTH PASSWORD"] =
1036 new _define_optional('LDAP_AUTH_PASSWORD', "secret", "
1037 Password to use to initially bind to the LDAP server, as the DN
1038 specified in the LDAP_AUTH_USER option (above).");
1040 $properties["LDAP SEARCH FIELD"] =
1041 new _define_optional('LDAP_SEARCH_FIELD', "uid", "
1042 If you want to match usernames against an attribute other than uid,
1043 specify it here. Default: uid
1045 e.g.: LDAP_SEARCH_FIELD = sAMAccountName");
1047 $properties["LDAP OU USERS"] =
1048 new _define_optional('LDAP_OU_USERS', "ou=Users", "
1049 If you have an organizational unit for all users, define it here.
1050 This narrows the search, and is needed for LDAP group membership (if GROUP_METHOD=LDAP)
1051 Default: ou=Users");
1053 $properties["LDAP OU GROUP"] =
1054 new _define_optional('LDAP_OU_GROUP', "ou=Groups", "
1055 If you have an organizational unit for all groups, define it here.
1056 This narrows the search, and is needed for LDAP group membership (if GROUP_METHOD=LDAP)
1057 The entries in this ou must have a gidNumber and cn attribute.
1058 Default: ou=Groups");
1062 $properties["LDAP Authentication"] =
1063 new unchangeable_define('LDAP Authentication', "
1064 If USER_AUTH_ORDER contains Ldap:
1066 The LDAP server to connect to. Can either be a hostname, or a complete
1067 URL to the server (useful if you want to use ldaps or specify a different
1069 ;LDAP_AUTH_HOST = \"ldap://localhost:389\"
1071 ; The organizational or domain BASE DN: e.g. \"dc=mydomain,dc=com\".
1073 ; Note: ou=Users and ou=Groups are used for GroupLdap Membership
1074 ; Better use LDAP_OU_USERS and LDAP_OU_GROUP with GROUP_METHOD=LDAP.
1075 ;LDAP_BASE_DN = \"ou=Users,o=Development,dc=mycompany.com\"
1077 ; Some LDAP servers need some more options, such as the Windows Active
1078 ; Directory Server. Specify the options (as allowed by the PHP LDAP module)
1079 ; and their values as NAME=value pairs separated by colons.
1080 ; LDAP_SET_OPTION = \"LDAP_OPT_PROTOCOL_VERSION=3:LDAP_OPT_REFERRALS=0\"
1082 ; DN to initially bind to the LDAP server as. This is needed if the server doesn't
1083 ; allow anonymous queries. (Windows Active Directory Server)
1084 ; LDAP_AUTH_USER = \"CN=ldapuser,ou=Users,o=Development,dc=mycompany.com\"
1086 ; Password to use to initially bind to the LDAP server, as the DN
1087 ; specified in the LDAP_AUTH_USER option (above).
1088 ; LDAP_AUTH_PASSWORD = secret
1090 ; If you want to match usernames against an attribute other than uid,
1091 ; specify it here. Default: uid
1092 ; LDAP_SEARCH_FIELD = sAMAccountName
1094 ; If you have an organizational unit for all users, define it here.
1095 ; This narrows the search, and is needed for LDAP group membership (if GROUP_METHOD=LDAP)
1097 ; LDAP_OU_USERS = ou=Users
1099 ; If you have an organizational unit for all groups, define it here.
1100 ; This narrows the search, and is needed for LDAP group membership (if GROUP_METHOD=LDAP)
1101 ; The entries in this ou must have a gidNumber and cn attribute.
1102 ; Default: ou=Groups
1103 ; LDAP_OU_GROUP = ou=Groups", "
1104 ; Ignored. No LDAP support in this php. configure --with-ldap");
1107 if (function_exists('imap_open')) {
1109 $properties["IMAP Auth Host"] =
1110 new _define_optional('IMAP_AUTH_HOST', 'localhost:143/imap/notls', "
1111 If USER_AUTH_ORDER contains IMAP:
1113 The IMAP server to check usernames from. Defaults to localhost.
1115 Some IMAP_AUTH_HOST samples:
1116 localhost, localhost:143/imap/notls,
1117 localhost:993/imap/ssl/novalidate-cert (SuSE refuses non-SSL conections)");
1121 $properties["IMAP Authentication"] =
1122 new unchangeable_define('IMAP_AUTH_HOST',"
1123 ; If USER_AUTH_ORDER contains IMAP:
1124 ; The IMAP server to check usernames from. Defaults to localhost.
1126 ; Some IMAP_AUTH_HOST samples:
1127 ; localhost, localhost:143/imap/notls,
1128 ; localhost:993/imap/ssl/novalidate-cert (SuSE refuses non-SSL conections)
1129 ;IMAP_AUTH_HOST = localhost:143/imap/notls", "
1130 Ignored. No IMAP support in this php. configure --with-imap");
1134 $properties["POP3 Authentication"] =
1135 new _define_optional('POP3_AUTH_HOST', 'localhost:110', "
1136 If USER_AUTH_ORDER contains POP3:
1138 The POP3 mail server to check usernames and passwords against.");
1139 $properties["File Authentication"] =
1140 new _define_optional('AUTH_USER_FILE', '/etc/shadow', "
1141 If USER_AUTH_ORDER contains File:
1143 File to read for authentication information.
1144 Popular choices are /etc/shadow and /etc/httpd/.htpasswd");
1146 $properties["File Storable?"] =
1147 new boolean_define_commented_optional
1148 ('AUTH_USER_FILE_STORABLE',
1149 array('false' => "Disabled",
1150 'true' => "Enabled"), "
1151 Defines whether the user is able to change their own password via PhpWiki.
1152 Note that this means that the webserver user must be able to write to the
1153 file specified in AUTH_USER_FILE.");
1155 $properties["Session Auth USER"] =
1156 new _define_optional('AUTH_SESS_USER', 'userid', "
1157 If USER_AUTH_ORDER contains Session:
1159 Name of the session variable which holds the already authenticated username.
1160 Sample: 'userid', 'user[username]', 'user->username'");
1162 $properties["Session Auth LEVEL"] =
1163 new numeric_define('AUTH_SESS_LEVEL', '2', "
1164 Which level will the user be? 1 = Bogo or 2 = Pass");
1166 /////////////////////////////////////////////////////////////////////
1168 $properties["Part Four"] =
1169 new part('_partfour', $SEPARATOR."\n", "
1172 Page appearance and layout");
1174 $properties["Theme"] =
1175 new _define_selection_optional('THEME',
1176 array('default' => "default",
1177 'MacOSX' => "MacOSX",
1178 'smaller' => 'smaller',
1179 'Wordpress'=> 'Wordpress',
1180 'Portland' => "Portland",
1181 'Hawaiian' => "Hawaiian",
1182 'Sidebar' => "Sidebar",
1184 'wikilens' => 'wikilens (Ratings)',
1185 'SpaceWiki' => "SpaceWiki",
1186 'shamino_com' => 'shamino_com',
1187 'MonoBook' => 'MonoBook [experimental]',
1188 'blog' => 'blog [experimental]',
1192 Most of the page appearance is controlled by files in the theme
1195 There are a number of pre-defined themes shipped with PhpWiki.
1196 Or you may create your own (e.g. by copying and then modifying one of
1201 THEME = MonoBook (WikiPedia) [experimental. MSIE problems]
1202 THEME = blog (Kubrick) [experimental. Several links missing]
1205 $properties["Character Set"] =
1206 new _define_optional('CHARSET', 'iso-8859-1', "
1207 Select a valid charset name to be inserted into the xml/html pages,
1208 and to reference links to the stylesheets (css). For more info see:
1209 http://www.iana.org/assignments/character-sets. Note that PhpWiki
1210 has been extensively tested only with the latin1 (iso-8859-1)
1213 If you change the default from iso-8859-1 PhpWiki may not work
1214 properly and it will require code modifications. However, character
1215 sets similar to iso-8859-1 may work with little or no modification
1216 depending on your setup. The database must also support the same
1217 charset, and of course the same is true for the web browser. (Some
1218 work is in progress hopefully to allow more flexibility in this
1219 area in the future).");
1221 $properties["Language"] =
1222 new _define_selection_optional('DEFAULT_LANGUAGE',
1223 array('en' => "English",
1224 '' => "<empty> (user-specific)",
1225 'fr' => "Français",
1227 'nl' => "Nederlands",
1232 'zh' => "Chinese"), "
1233 Select your language/locale - default language is \"en\" for English.
1234 Other languages available:<pre>
1235 English \"en\" (English - HomePage)
1236 German \"de\" (Deutsch - StartSeite)
1237 French \"fr\" (Français - Accueil)
1238 Dutch \"nl\" (Nederlands - ThuisPagina)
1239 Spanish \"es\" (Español - PáginaPrincipal)
1240 Swedish \"sv\" (Svenska - Framsida)
1241 Italian \"it\" (Italiano - PaginaPrincipale)
1242 Japanese \"ja\" (Japanese - ¥Û¡¼¥à ¥Ú¡¼¥¸)
1243 Chinese \"zh\" (Chinese)
1245 If you set DEFAULT_LANGUAGE to the empty string, your systems default language
1246 (as determined by the applicable environment variables) will be
1249 $properties["Wiki Page Source"] =
1250 new _define_optional('WIKI_PGSRC', 'pgsrc', "
1251 WIKI_PGSRC -- specifies the source for the initial page contents of
1252 the Wiki. The setting of WIKI_PGSRC only has effect when the wiki is
1253 accessed for the first time (or after clearing the database.)
1254 WIKI_PGSRC can either name a directory or a zip file. In either case
1255 WIKI_PGSRC is scanned for files -- one file per page.
1257 // Default (old) behavior:
1258 define('WIKI_PGSRC', 'pgsrc');
1260 define('WIKI_PGSRC', 'wiki.zip');
1261 define('WIKI_PGSRC',
1262 '../Logs/Hamwiki/hamwiki-20010830.zip');
1266 $properties["Default Wiki Page Source"] =
1267 new _define('DEFAULT_WIKI_PGSRC', 'pgsrc', "
1268 DEFAULT_WIKI_PGSRC is only used when the language is *not* the
1269 default (English) and when reading from a directory: in that case
1270 some English pages are inserted into the wiki as well.
1271 DEFAULT_WIKI_PGSRC defines where the English pages reside.
1273 FIXME: is this really needed?
1276 $properties["Generic Pages"] =
1277 new array_variable('GenericPages', array('ReleaseNotes', 'SteveWainstead', 'TestPage'), "
1278 These are the pages which will get loaded from DEFAULT_WIKI_PGSRC.
1280 FIXME: is this really needed? Cannot we just copy these pages into
1281 the localized pgsrc?
1287 $properties["Part Five"] =
1288 new part('_partfive', $SEPARATOR."\n", "
1293 $properties["Allowed Protocols"] =
1294 new list_define('ALLOWED_PROTOCOLS', 'http|https|mailto|ftp|news|nntp|ssh|gopher', "
1295 Allowed protocols for links - be careful not to allow \"javascript:\"
1296 URL of these types will be automatically linked.
1297 within a named link [name|uri] one more protocol is defined: phpwiki");
1299 $properties["Inline Images"] =
1300 new list_define('INLINE_IMAGES', 'png|jpg|gif', "
1301 URLs ending with the following extension should be inlined as images");
1303 $properties["WikiName Regexp"] =
1304 new _define('WIKI_NAME_REGEXP', "(?<![[:alnum:]])(?:[[:upper:]][[:lower:]]+){2,}(?![[:alnum:]])", "
1305 Perl regexp for WikiNames (\"bumpy words\")
1306 (?<!..) & (?!...) used instead of '\b' because \b matches '_' as well");
1308 $properties["Subpage Separator"] =
1309 new _define_optional('SUBPAGE_SEPARATOR', '/', "
1310 One character which seperates pages from subpages. Defaults to '/', but '.' or ':' were also used.",
1311 "onchange=\"validate_ereg('Sorry, \'%s\' must be a single character. Currently only :, / or .', '^[/:.]$', 'SUBPAGE_SEPARATOR', this);\""
1314 $properties["InterWiki Map File"] =
1315 new _define('INTERWIKI_MAP_FILE', 'lib/interwiki.map', "
1316 InterWiki linking -- wiki-style links to other wikis on the web
1318 The map will be taken from a page name InterWikiMap.
1319 If that page is not found (or is not locked), or map
1320 data can not be found in it, then the file specified
1321 by INTERWIKI_MAP_FILE (if any) will be used.");
1323 $properties["WARN_NONPUBLIC_INTERWIKIMAP"] =
1324 new boolean_define('WARN_NONPUBLIC_INTERWIKIMAP',
1325 array('true' => "true",
1326 'false' => "false"), "
1327 Display a warning if the internal lib/interwiki.map is used, and
1328 not the public InterWikiMap page. This map is not readable from outside.");
1331 $properties["Keyword Link Regexp"] =
1332 new _define_optional('KEYWORDS', '\"Category* OR Topic*\"', "
1333 Search term used for automatic page classification by keyword extraction.
1335 Any links on a page to pages whose names match this search
1336 will be used keywords in the keywords html meta tag. This is an aid to
1337 classification by search engines. The value of the match is
1338 used as the keyword.
1340 The default behavior is to match Category* or Topic* links.");
1342 $properties["Author and Copyright Site Navigation Links"] =
1343 new _define_commented_optional('COPYRIGHTPAGE_TITLE', "GNU General Public License", "
1345 These will be inserted as <link rel> tags in the html header of
1346 every page, for search engines and for browsers like Mozilla which
1347 take advantage of link rel site navigation.
1349 If you have your own copyright and contact information pages change
1350 these as appropriate.");
1352 $properties["COPYRIGHTPAGE URL"] =
1353 new _define_commented_optional('COPYRIGHTPAGE_URL', "http://www.gnu.org/copyleft/gpl.html#SEC1", "
1355 Other useful alternatives to consider:
1357 COPYRIGHTPAGE_TITLE = \"GNU Free Documentation License\"
1358 COPYRIGHTPAGE_URL = \"http://www.gnu.org/copyleft/fdl.html\"
1359 COPYRIGHTPAGE_TITLE = \"Creative Commons License 2.0\"
1360 COPYRIGHTPAGE_URL = \"http://creativecommons.org/licenses/by/2.0/\"</pre>
1361 See http://creativecommons.org/learn/licenses/ for variations");
1363 $properties["AUTHORPAGE_TITLE"] =
1364 new _define_commented_optional('AUTHORPAGE_TITLE', "The PhpWiki Programming Team", "
1365 Default Author Names");
1366 $properties["AUTHORPAGE_URL"] =
1367 new _define_commented_optional('AUTHORPAGE_URL', "http://phpwiki.org/ThePhpWikiProgrammingTeam", "
1368 Default Author URL");
1370 new boolean_define_optional
1372 array('true' => "Enabled",
1373 'false' => "Disabled."), "
1374 Allow full markup in headers to be parsed by the CreateToc plugin.
1376 If false you may not use WikiWords or [] links or any other markup in
1377 headers in pages with the CreateToc plugin. But if false the parsing is
1378 faster and more stable.");
1382 $properties["Part Six"] =
1383 new part('_partsix', $SEPARATOR."\n", "
1385 Part Six (optional):
1386 URL options -- you can probably skip this section.
1388 For a pretty wiki (no index.php in the url) set a seperate DATA_PATH.");
1390 global $HTTP_SERVER_VARS;
1391 $properties["Server Name"] =
1392 new _define_commented_optional('SERVER_NAME', $HTTP_SERVER_VARS['SERVER_NAME'], "
1393 Canonical name and httpd port of the server on which this PhpWiki
1397 $properties["Server Port"] =
1398 new numeric_define_commented('SERVER_PORT', $HTTP_SERVER_VARS['SERVER_PORT'], "",
1399 "onchange=\"validate_ereg('Sorry, \'%s\' is no valid port number.', '^[0-9]+$', 'SERVER_PORT', this);\"");
1401 $scriptname = str_replace('configurator.php','index.php',$HTTP_SERVER_VARS["SCRIPT_NAME"]);
1403 $properties["Script Name"] =
1404 new _define_commented_optional('SCRIPT_NAME', $scriptname, "
1405 Relative URL (from the server root) of the PhpWiki script.");
1407 $properties["Data Path"] =
1408 new _define_commented_optional('DATA_PATH', dirname($scriptname), "
1409 URL of the PhpWiki install directory. (You only need to set this
1410 if you've moved index.php out of the install directory.) This can
1411 be either a relative URL (from the directory where the top-level
1412 PhpWiki script is) or an absolute one.");
1415 $properties["PhpWiki Install Directory"] =
1416 new _define_commented_optional('PHPWIKI_DIR', dirname(__FILE__), "
1417 Path to the PhpWiki install directory. This is the local
1418 filesystem counterpart to DATA_PATH. (If you have to set
1419 DATA_PATH, your probably have to set this as well.) This can be
1420 either an absolute path, or a relative path interpreted from the
1421 directory where the top-level PhpWiki script (normally index.php)
1424 $properties["Use PATH_INFO"] =
1425 new boolean_define_commented_optional('USE_PATH_INFO',
1426 array('true' => 'use PATH_INFO',
1427 'false' => 'do not use PATH_INFO'), "
1428 PhpWiki will try to use short urls to pages, eg
1429 http://www.example.com/index.php/HomePage
1430 If you want to use urls like
1431 http://www.example.com/index.php?pagename=HomePage
1432 then define 'USE_PATH_INFO' as false by uncommenting the line below.
1433 NB: If you are using Apache >= 2.0.30, then you may need to to use
1434 the directive \"AcceptPathInfo On\" in your Apache configuration file
1435 (or in an appropriate <.htaccess> file) for the short urls to work:
1436 See http://httpd.apache.org/docs-2.0/mod/core.html#acceptpathinfo
1438 See also http://phpwiki.sourceforge.net/phpwiki/PrettyWiki for more ideas
1439 on prettifying your urls.
1441 Default: PhpWiki will try to divine whether use of PATH_INFO
1442 is supported in by your webserver/PHP configuration, and will
1443 use PATH_INFO if it thinks that is possible.");
1446 $properties["Virtual Path"] =
1447 new _define_commented_optional('VIRTUAL_PATH', '/SomeWiki', "
1448 VIRTUAL_PATH is the canonical URL path under which your your wiki
1449 appears. Normally this is the same as dirname(SCRIPT_NAME), however
1450 using, e.g. seperate starter scripts, apaches mod_actions (or mod_rewrite), you can make it
1451 something different.
1453 If you do this, you should set VIRTUAL_PATH here or in the starter scripts.
1455 E.g. your phpwiki might be installed at at /scripts/phpwiki/index.php,
1456 but you've made it accessible through eg. /wiki/HomePage.
1458 One way to do this is to create a directory named 'wiki' in your
1459 server root. The directory contains only one file: an .htaccess
1460 file which reads something like:
1462 Action x-phpwiki-page /scripts/phpwiki/index.php
1463 SetHandler x-phpwiki-page
1464 DirectoryIndex /scripts/phpwiki/index.php
1466 In that case you should set VIRTUAL_PATH to '/wiki'.
1468 (VIRTUAL_PATH is only used if USE_PATH_INFO is true.)
1473 $properties["Part Seven"] =
1474 new part('_partseven', $SEPARATOR."\n", "
1478 Miscellaneous settings
1481 $properties["Pagename of Recent Changes"] =
1482 new _define_optional('RECENT_CHANGES', 'RecentChanges', "
1483 Page name of RecentChanges page. Used for RSS Auto-discovery.");
1485 $properties["Disable HTTP Redirects"] =
1486 new boolean_define_commented_optional
1487 ('DISABLE_HTTP_REDIRECT',
1488 array('false' => 'Enable HTTP Redirects',
1489 'true' => 'Disable HTTP Redirects'),
1491 (You probably don't need to touch this.)
1493 PhpWiki uses HTTP redirects for some of it's functionality.
1494 (e.g. after saving changes, PhpWiki redirects your browser to
1495 view the page you just saved.)
1497 Some web service providers (notably free European Lycos) don't seem to
1498 allow these redirects. (On Lycos the result in an \"Internal Server Error\"
1499 report.) In that case you can set DISABLE_HTTP_REDIRECT to true.
1500 (In which case, PhpWiki will revert to sneakier tricks to try to
1501 redirect the browser...)");
1503 $properties["EDITING_POLICY"] =
1504 new _define_optional('EDITING_POLICY', "EditingPolicy", "
1505 An interim page which gets displayed on every edit attempt, if it exists.");
1508 $end = "\n".$SEPARATOR."\n";
1510 // end of configuration options
1511 ///////////////////////////////
1512 // begin class definitions
1515 * A basic index.php configuration line in the form of a variable.
1517 * Produces a string in the form "$name = value;"
1519 * $WikiNameRegexp = "value";
1523 var $config_item_name;
1529 function _variable($config_item_name, $default_value, $description, $jscheck = '') {
1530 $this->config_item_name = $config_item_name;
1531 $this->description = $description;
1532 $this->default_value = $default_value;
1533 $this->jscheck = $jscheck;
1534 if (preg_match("/variable/i",get_class($this)))
1535 $this->prefix = "\$";
1536 elseif (preg_match("/ini_set/i",get_class($this)))
1537 $this->prefix = "ini_get: ";
1543 global $HTTP_POST_VARS;
1544 if (isset($HTTP_POST_VARS[$this->config_item_name]))
1545 return $HTTP_POST_VARS[$this->config_item_name];
1547 return $this->default_value;
1550 function _config_format($value) {
1551 $v = $this->get_config_item_name();
1552 // handle arrays: a|b --> a['b']
1553 if (strpos($v, '|')) {
1554 list($a, $b) = explode('|', $v);
1555 $v = sprintf("%s['%s']", $a, $b);
1557 if (preg_match("/[\"']/", $value))
1558 $value = '"' . $value . '"';
1559 return sprintf("%s = %s", $v, $value);
1562 function get_config_item_name() {
1563 return $this->config_item_name;
1566 function get_config_item_id() {
1567 return str_replace('|', '-', $this->config_item_name);
1570 function get_config_item_header() {
1571 if (strchr($this->config_item_name,'|')) {
1572 list($var,$param) = explode('|',$this->config_item_name);
1573 return "<b>" . $this->prefix . $var . "['" . $param . "']</b><br />";
1575 elseif ($this->config_item_name[0] != '_')
1576 return "<b>" . $this->prefix . $this->config_item_name . "</b><br />";
1581 function _get_description() {
1582 return $this->description;
1585 function _get_config_line($posted_value) {
1586 return "\n" . $this->_config_format($posted_value);
1589 function get_config($posted_value) {
1590 $d = stripHtml($this->_get_description());
1591 $d = str_replace("\n", "\n; ", $d) . $this->_get_config_line($posted_value) ."\n";
1595 function get_instructions($title) {
1597 $i = "<h3>" . $title . "</h3>\n " . nl2p($this->_get_description()) . "\n";
1598 return "<tr>\n<td width=\"$tdwidth\" class=\"instructions\">\n" . $i . "</td>\n";
1601 function get_html() {
1602 $size = strlen($this->default_value) > 45 ? 90 : 50;
1603 return $this->get_config_item_header() .
1604 "<input type=\"text\" size=\"$50\" name=\"" . $this->get_config_item_name() . "\" value=\"" . htmlspecialchars($this->default_value) . "\" " .
1605 $this->jscheck . " />" . "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: green\">Input accepted.</p>";
1609 class unchangeable_variable
1611 function _config_format($value) {
1614 // function get_html() { return false; }
1615 function get_html() {
1616 return $this->get_config_item_header() .
1617 "<em>Not editable.</em>" .
1618 "<pre>" . $this->default_value."</pre>";
1620 function _get_config_line($posted_value) {
1621 if ($this->description)
1623 return "${n}".$this->default_value;
1625 function get_instructions($title) {
1627 $i = "<h3>" . $title . "</h3>\n " . nl2p($this->_get_description()) . "\n";
1628 // $i .= "<em>Not editable.</em><br />\n<pre>" . $this->default_value."</pre>";
1629 return '<tr><td width="100%" class="unchangeable-variable-top" colspan="2">'."\n".$i."</td></tr>\n"
1630 . '<tr style="border-top: none;"><td class="unchangeable-variable-left" width="'.$tdwidth.'"> </td>';
1634 class unchangeable_define
1635 extends unchangeable_variable {
1636 function _config_format($value) {
1640 class unchangeable_ini_set
1641 extends unchangeable_variable {
1642 function _config_format($value) {
1647 class _variable_selection
1650 global $HTTP_POST_VARS;
1651 if (!empty($HTTP_POST_VARS[$this->config_item_name]))
1652 return $HTTP_POST_VARS[$this->config_item_name];
1654 list($option, $label) = each($this->default_value);
1658 function get_html() {
1659 $output = $this->get_config_item_header();
1660 $output .= '<select name="' . $this->get_config_item_name() . "\">\n";
1661 /* The first option is the default */
1662 while(list($option, $label) = each($this->default_value)) {
1663 $output .= " <option value=\"$option\">$label</option>\n";
1665 $output .= "</select>\n";
1673 function _config_format($value) {
1674 return sprintf("%s = %s", $this->get_config_item_name(), $value);
1676 function _get_config_line($posted_value) {
1677 if ($this->description)
1679 if ($posted_value == '')
1680 return "${n};" . $this->_config_format("");
1682 return "${n}" . $this->_config_format($posted_value);
1684 function get_html() {
1685 $size = strlen($this->default_value) > 45 ? 90 : 50;
1686 return $this->get_config_item_header()
1687 . "<input type=\"text\" size=\"$size\" name=\"" . htmlentities($this->get_config_item_name())
1688 . "\" value=\"" . htmlentities($this->default_value) . "\" {$this->jscheck} />"
1689 . "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: green\">Input accepted.</p>";
1693 class _define_commented
1695 function _get_config_line($posted_value) {
1696 if ($this->description)
1698 if ($posted_value == $this->default_value)
1699 return "${n};" . $this->_config_format($posted_value);
1700 elseif ($posted_value == '')
1701 return "${n};" . $this->_config_format("");
1703 return "${n}" . $this->_config_format($posted_value);
1707 class _define_commented_optional
1708 extends _define_commented {
1709 /*function _config_format($value) {
1710 $name = $this->get_config_item_name();
1711 return sprintf("if (!defined('%s')) define('%s', '%s');", $name, $name, $value);
1715 class _define_optional
1717 /*function _config_format($value) {
1718 $name = $this->get_config_item_name();
1719 return sprintf("if (!defined('%s')) define('%s', '%s');", $name, $name, $value);
1723 class _define_optional_notempty
1724 extends _define_optional {
1725 function get_html() {
1726 $s = $this->get_config_item_header()
1727 . "<input type=\"text\" size=\"50\" name=\"" . $this->get_config_item_name()
1728 . "\" value=\"" . $this->default_value . "\" {$this->jscheck} />";
1729 if (empty($this->default_value))
1730 return $s . "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: red\">Cannot be empty.</p>";
1732 return $s . "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: green\">Input accepted.</p>";
1736 class _variable_commented
1738 function _get_config_line($posted_value) {
1739 if ($this->description)
1741 if ($posted_value == $this->default_value)
1742 return "${n};" . $this->_config_format($posted_value);
1743 elseif ($posted_value == '')
1744 return "${n};" . $this->_config_format("");
1746 return "${n}" . $this->_config_format($posted_value);
1750 class numeric_define_commented
1752 function numeric_define_commented($config_item_name, $default_value, $description, $jscheck = '') {
1753 $this->_define($config_item_name, $default_value, $description, $jscheck);
1755 $this->jscheck = "onchange=\"validate_ereg('Sorry, \'%s\' is not an integer.', '^[-+]?[0-9]+$', '" . $this->get_config_item_name() . "', this);\"";
1757 function get_html() {
1758 return numeric_define::get_html();
1760 function _get_config_line($posted_value) {
1761 if ($this->description)
1763 if ($posted_value == $this->default_value)
1764 return "${n};" . $this->_config_format($posted_value);
1765 elseif ($posted_value == '')
1766 return "${n};" . $this->_config_format('0');
1768 return "${n}" . $this->_config_format($posted_value);
1772 class _define_selection
1773 extends _variable_selection {
1774 function _config_format($value) {
1775 return sprintf("%s = %s", $this->get_config_item_name(), $value);
1777 function _get_config_line($posted_value) {
1778 return _define::_get_config_line($posted_value);
1780 function get_html() {
1781 return _variable_selection::get_html();
1785 class _define_selection_optional
1786 extends _define_selection {
1787 /* function _config_format($value) {
1788 $name = $this->get_config_item_name();
1789 return sprintf("if (!defined('%s')) define('%s', '%s');", $name, $name, $value);
1793 class _variable_selection_optional
1794 extends _variable_selection {
1796 function _config_format($value) {
1797 $v = $this->get_config_item_name();
1798 // handle arrays: a|b --> a['b']
1799 if (strpos($v, '|')) {
1800 list($a, $b) = explode('|', $v);
1801 $v = sprintf("%s['%s']", $a, $b);
1803 return sprintf("if (!isset(\$%s)) { \$%s = \"%s\"; }", $v, $v, $value);
1807 class _define_password
1810 function _define_password($config_item_name, $default_value, $description, $jscheck = '') {
1811 $this->_define($config_item_name, $default_value, $description, $jscheck);
1813 $this->jscheck = "onchange=\"validate_ereg('Sorry, \'%s\' cannot be empty.', '^.+$', '" . $this->get_config_item_name() . "', this);\"";
1815 function _get_config_line($posted_value) {
1816 if ($this->description)
1818 if ($posted_value == '') {
1819 $p = "${n};" . $this->_config_format("");
1820 $p .= "\n; If you used the passencrypt.php utility to encode the password";
1821 $p .= "\n; then uncomment this line:";
1822 $p .= "\n;ENCRYPTED_PASSWD = true";
1825 if (function_exists('crypt')) {
1826 $salt_length = max(CRYPT_SALT_LENGTH,
1830 16 * CRYPT_BLOWFISH);
1831 // generate an encrypted password
1832 $crypt_pass = crypt($posted_value, rand_ascii($salt_length));
1833 $p = "${n}" . $this->_config_format($crypt_pass);
1834 return $p . "\nENCRYPTED_PASSWD = true";
1836 $p = "${n}" . $this->_config_format($posted_value);
1837 $p .= "\n; Encrypted passwords cannot be used:";
1838 $p .= "\n; 'function crypt()' not available in this version of php";
1839 $p .= "\nENCRYPTED_PASSWD = false";
1844 function get_html() {
1845 return _variable_password::get_html();
1849 class _define_password_optional
1850 extends _define_password {
1853 class _variable_password
1855 function _variable_password($config_item_name, $default_value, $description, $jscheck = '') {
1856 $this->_define($config_item_name, $default_value, $description, $jscheck);
1858 $this->jscheck = "onchange=\"validate_ereg('Sorry, \'%s\' cannot be empty.', '^.+$', '" . $this->get_config_item_name() . "', this);\"";
1860 function get_html() {
1861 global $HTTP_POST_VARS, $HTTP_GET_VARS;
1862 $s = $this->get_config_item_header();
1863 if (isset($HTTP_POST_VARS['create']) or isset($HTTP_GET_VARS['create'])) {
1864 $new_password = random_good_password();
1865 $this->default_value = $new_password;
1866 $s .= "Created password: <strong>$new_password</strong><br /> <br />";
1868 $s .= "<input type=\"password\" name=\"" . $this->get_config_item_name()
1869 . "\" value=\"" . $this->default_value
1870 . "\" {$this->jscheck} />"
1871 . " <input type=\"submit\" name=\"create\" value=\"Create Random Password\" />";
1872 if (empty($this->default_value))
1873 $s .= "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: red\">Cannot be empty.</p>";
1874 elseif (strlen($this->default_value) < 4)
1875 $s .= "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: red\">Must be longer than 4 chars.</p>";
1877 $s .= "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: green\">Input accepted.</p>";
1882 class numeric_define
1885 function numeric_define($config_item_name, $default_value, $description, $jscheck = '') {
1886 $this->_define($config_item_name, $default_value, $description, $jscheck);
1888 $this->jscheck = "onchange=\"validate_ereg('Sorry, \'%s\' is not an integer.', '^[-+]?[0-9]+$', '" . $this->get_config_item_name() . "', this);\"";
1890 function _config_format($value) {
1891 //return sprintf("define('%s', %s);", $this->get_config_item_name(), $value);
1892 return sprintf("%s = %s", $this->get_config_item_name(), $value);
1894 function _get_config_line($posted_value) {
1895 if ($this->description)
1897 if ($posted_value == '')
1898 return "${n};" . $this->_config_format('0');
1900 return "${n}" . $this->_config_format($posted_value);
1906 function _get_config_line($posted_value) {
1907 // split the phrase by any number of commas or space characters,
1908 // which include " ", \r, \t, \n and \f
1909 $list_values = preg_split("/[\s,]+/", $posted_value, -1, PREG_SPLIT_NO_EMPTY);
1910 $list_values = join("|", $list_values);
1911 return _variable::_get_config_line($list_values);
1913 function get_html() {
1914 $list_values = explode("|", $this->default_value);
1915 $rows = max(3, count($list_values) +1);
1916 $list_values = join("\n", $list_values);
1917 $ta = $this->get_config_item_header();
1918 $ta .= "<textarea cols=\"18\" rows=\"". $rows ."\" name=\"".$this->get_config_item_name()."\" {$this->jscheck}>";
1919 $ta .= $list_values . "</textarea>";
1920 $ta .= "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: green\">Input accepted.</p>";
1927 function _get_config_line($posted_value) {
1928 $list_values = preg_split("/[\s,]+/", $posted_value, -1, PREG_SPLIT_NO_EMPTY);
1929 $list_values = join("|", $list_values);
1930 return _variable::_get_config_line($list_values);
1932 function get_html() {
1933 $list_values = explode("|", $this->default_value);
1934 $rows = max(3, count($list_values) +1);
1935 $list_values = join("\n", $list_values);
1936 $ta = $this->get_config_item_header();
1937 $ta .= "<textarea cols=\"18\" rows=\"". $rows ."\" name=\"".$this->get_config_item_name()."\" {$this->jscheck}>";
1938 $ta .= $list_values . "</textarea>";
1939 $ta .= "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: green\">Input accepted.</p>";
1944 class array_variable
1946 function _config_format($value) {
1947 return sprintf("%s = \"%s\"", $this->get_config_item_name(),
1948 is_array($value) ? join(':', $value) : $value);
1950 function _get_config_line($posted_value) {
1951 // split the phrase by any number of commas or space characters,
1952 // which include " ", \r, \t, \n and \f
1953 $list_values = preg_split("/[\s,]+/", $posted_value, -1, PREG_SPLIT_NO_EMPTY);
1954 if (!empty($list_values)) {
1955 $list_values = "'".join("', '", $list_values)."'";
1956 return "\n" . $this->_config_format($list_values);
1958 return "\n;" . $this->_config_format('');
1960 function get_html() {
1961 $list_values = join("\n", $this->default_value);
1962 $rows = max(3, count($this->default_value) +1);
1963 $ta = $this->get_config_item_header();
1964 $ta .= "<textarea cols=\"18\" rows=\"". $rows ."\" name=\"".$this->get_config_item_name()."\" {$this->jscheck}>";
1965 $ta .= $list_values . "</textarea>";
1966 $ta .= "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: green\">Input accepted.</p>";
1973 function _config_format($value) {
1974 return sprintf("%s = \"%s\"", $this->get_config_item_name(),
1975 is_array($value) ? join(' : ', $value) : $value);
1977 function _get_config_line($posted_value) {
1978 // split the phrase by any number of commas or space characters,
1979 // which include " ", \r, \t, \n and \f
1980 $list_values = preg_split("/[\s,:]+/", $posted_value, -1, PREG_SPLIT_NO_EMPTY);
1981 if (!empty($list_values)) {
1982 $list_values = "'".join("' : '", $list_values)."'";
1983 return "\n" . $this->_config_format($list_values);
1985 return "\n;" . $this->_config_format('');
1987 function get_html() {
1988 $list_values = join("\n", $this->default_value);
1989 $rows = max(3, count($this->default_value) +1);
1990 $ta = $this->get_config_item_header();
1991 $ta .= "<textarea cols=\"18\" rows=\"". $rows ."\" name=\"".$this->get_config_item_name()."\" {$this->jscheck}>";
1992 $ta .= $list_values . "</textarea>";
1993 $ta .= "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: green\">Input accepted.</p>";
2002 global $HTTP_POST_VARS;
2003 if ($v = $HTTP_POST_VARS[$this->config_item_name])
2006 return ini_get($this->get_config_item_name);
2009 function _config_format($value) {
2010 return sprintf("ini_set('%s', '%s');", $this->get_config_item_name(), $value);
2012 function _get_config_line($posted_value) {
2013 if ($posted_value && ! $posted_value == $this->default_value)
2014 return "\n" . $this->_config_format($posted_value);
2016 return "\n;" . $this->_config_format($this->default_value);
2021 class boolean_define
2023 function _get_config_line($posted_value) {
2024 if ($this->description)
2026 return "${n}" . $this->_config_format($posted_value);
2028 function _config_format($value) {
2029 if (strtolower(trim($value)) == 'false')
2031 return sprintf("%s = %s", $this->get_config_item_name(),
2032 (bool)$value ? 'true' : 'false');
2034 function get_html() {
2035 $output = $this->get_config_item_header();
2036 $output .= '<select name="' . $this->get_config_item_name() . "\" {$this->jscheck}>\n";
2037 /* The first option is the default */
2038 list($option, $label) = each($this->default_value);
2039 $output .= " <option value=\"$option\" selected='selected'>$label</option>\n";
2040 /* There can usually, only be two options, there can be
2041 * three options in the case of a boolean_define_commented_optional */
2042 while (list($option, $label) = each($this->default_value))
2043 $output .= " <option value=\"$option\">$label</option>\n";
2044 $output .= "</select>\n";
2049 class boolean_define_optional
2050 extends boolean_define {}
2052 class boolean_define_commented
2053 extends boolean_define {
2054 function _get_config_line($posted_value) {
2055 if ($this->description)
2057 list($default_value, $label) = each($this->default_value);
2058 if ($posted_value == $default_value)
2059 return "${n};" . $this->_config_format($posted_value);
2060 elseif ($posted_value == '')
2061 return "${n};" . $this->_config_format('false');
2063 return "${n}" . $this->_config_format($posted_value);
2067 class boolean_define_commented_optional
2068 extends boolean_define_commented {}
2072 function value () { return; }
2073 function get_config($posted_value) {
2074 $d = stripHtml($this->_get_description());
2076 return "\n".$SEPARATOR . str_replace("\n", "\n; ", $d) ."\n".$this->default_value;
2078 function get_instructions($title) {
2079 $group_name = preg_replace("/\W/","",$title);
2080 $i = "<tr class='header' id='$group_name'>\n<td class=\"part\" width=\"100%\" colspan=\"2\" bgcolor=\"#eeeeee\">\n";
2081 $i .= "<h2>" . $title . "</h2>\n " . nl2p($this->_get_description()) ."\n";
2082 $i .= "<p><a href=\"javascript:toggle_group('$group_name')\" id=\"{$group_name}_text\">Hide options.</a></p>";
2083 return $i ."</td>\n";
2085 function get_html() {
2090 // html utility functions
2091 function nl2p($text) {
2092 preg_match_all("@\s*(<pre>.*?</pre>|<dl>.*?</dl>|.*?(?=\n\n|<pre>|<dl>|$))@s",
2093 $text, $m, PREG_PATTERN_ORDER);
2096 foreach ($m[1] as $par) {
2097 if (!($par = trim($par)))
2099 if (!preg_match('/^<(pre|dl)>/', $par))
2100 $par = "<p>$par</p>";
2106 function stripHtml($text) {
2107 $d = str_replace("<pre>", "", $text);
2108 $d = str_replace("</pre>", "", $d);
2109 $d = str_replace("<dl>", "", $d);
2110 $d = str_replace("</dl>", "", $d);
2111 $d = str_replace("<dt>", "", $d);
2112 $d = str_replace("</dt>", "", $d);
2113 $d = str_replace("<dd>", "", $d);
2114 $d = str_replace("</dd>", "", $d);
2115 $d = str_replace("<p>", "", $d);
2116 $d = str_replace("</p>", "", $d);
2117 //restore html entities into characters
2118 // http://www.php.net/manual/en/function.htmlentities.php
2119 $trans = get_html_translation_table (HTML_ENTITIES);
2120 $trans = array_flip ($trans);
2121 $d = strtr($d, $trans);
2125 include_once(dirname(__FILE__)."/lib/stdlib.php");
2128 // Function to create better user passwords (much larger keyspace),
2129 // suitable for user passwords.
2130 // Sequence of random ASCII numbers, letters and some special chars.
2131 // Note: There exist other algorithms for easy-to-remember passwords.
2132 function random_good_password ($minlength = 5, $maxlength = 8) {
2134 // assume ASCII ordering (not valid on EBCDIC systems!)
2135 $valid_chars = "!#%&+-.0123456789=@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz";
2136 $start = ord($valid_chars);
2137 $end = ord(substr($valid_chars,-1));
2139 if (function_exists('mt_rand')) // mersenne twister
2140 $length = mt_rand($minlength, $maxlength);
2141 else // the usually bad glibc rand()
2142 $length = rand($minlength, $maxlength);
2143 while ($length > 0) {
2144 if (function_exists('mt_rand'))
2145 $newchar = mt_rand($start, $end);
2147 $newchar = rand($start, $end);
2148 if (! strrpos($valid_chars,$newchar) ) continue; // skip holes
2149 $newpass .= sprintf("%c", $newchar);
2156 function printArray($a) {
2157 echo "<hr />\n<pre>\n";
2159 echo "\n</pre>\n<hr />\n";
2162 // end of class definitions
2163 /////////////////////////////
2164 // begin auto generation code
2166 if (!function_exists('is_a')) {
2167 function is_a($object, $class) {
2168 $class = strtolower($class);
2169 return (get_class($object) == $class) or is_subclass_of($object, $class);
2174 if (!empty($HTTP_POST_VARS['action'])
2175 and $HTTP_POST_VARS['action'] == 'make_config') {
2177 $timestamp = date ('dS of F, Y H:i:s');
2180 ; This is a local configuration file for PhpWiki.
2181 ; It was automatically generated by the configurator script
2182 ; on the $timestamp.
2187 $posted = $GLOBALS['HTTP_POST_VARS'];
2189 if (defined('DEBUG'))
2190 printArray($GLOBALS['HTTP_POST_VARS']);
2192 foreach($properties as $option_name => $a) {
2193 $posted_value = $posted[$a->config_item_name];
2194 $config .= $properties[$option_name]->get_config($posted_value);
2199 // I think writing this config file is a big security hole.
2200 // If this is installed in such a way that it can write an index-user.php,
2201 // then anyone can create a working index-user.php with, e.g. any
2202 // admin user and pw of their choosing...
2204 // So I'm disabling it...
2206 if (defined('ENABLE_FILE_OUTPUT') and ENABLE_FILE_OUPUT) {
2207 // We first check if the config-file exists.
2208 if (file_exists($fs_config_file)) {
2209 // We make a backup copy of the file
2210 // $config_file = 'index-user.php';
2211 $new_filename = preg_replace('/\.ini$/', time() . '.ini', $fs_config_file);
2212 if (@copy($fs_config_file, $new_filename)) {
2213 $fp = @fopen($fs_config_file, 'w');
2216 $fp = @fopen($fs_config_file, 'w');
2224 fputs($fp, $config);
2226 echo "<p>The configuration was written to <code><b>$config_file</b></code>.</p>\n";
2227 if ($new_filename) {
2228 echo "<p>A backup was made to <code><b>$new_filename</b></code>.</p>\n";
2230 echo "<p><strong>You must rename or copy this</strong> <code><b>$config_file</b></code> <strong>file to</strong> <code><b>index.php</b></code>.</p>\n";
2232 echo "<p>A configuration file could <b>not</b> be written. You should copy the above configuration to a file, and manually save it as <code><b>config/config.ini</b></code>.</p>\n";
2235 echo "<hr />\n<p>Here's the configuration file based on your answers:</p>\n";
2236 echo "<form method=\"get\" action=\"configurator.php\">\n";
2237 echo "<textarea id='config-output' readonly='readonly' style='width:100%;' rows='30' cols='100'>\n";
2238 echo htmlentities($config);
2239 echo "</textarea></form>\n";
2242 echo "<p>To make any corrections, <a href=\"configurator.php\">edit the settings again</a>.</p>\n";
2244 } else { // first time or create password
2245 $posted = $GLOBALS['HTTP_POST_VARS'];
2246 // No action has been specified - we make a form.
2249 <form action="configurator.php" method="post">
2250 <input type="hidden" name="action" value="make_config" />
2251 <table cellpadding="4" cellspacing="0">
2254 while(list($property, $obj) = each($properties)) {
2255 echo $obj->get_instructions($property);
2256 if ($h = $obj->get_html()) {
2257 if (defined('DEBUG') and DEBUG) $h = get_class($obj) . "<br />\n" . $h;
2258 echo "<td>".$h."</td>\n";
2265 <p><input type="submit" value="Save ',$config_file,'" /> <input type="reset" value="Clear" /></p>