2 // $Id: configurator.php,v 1.25 2005-02-15 17:54: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.
21 global $HTTP_SERVER_VARS;
22 if (empty($configurator))
23 $configurator = "configurator.php";
24 if (!strstr($HTTP_SERVER_VARS["SCRIPT_NAME"], $configurator) and defined('DATA_PATH'))
25 $configurator = DATA_PATH . "/" . $configurator;
26 $scriptname = str_replace('configurator.php', 'index.php', $HTTP_SERVER_VARS["SCRIPT_NAME"]);
29 $config_file = (substr(PHP_OS,0,3) == 'WIN') ? 'config\\config.ini' : 'config/config.ini';
30 $fs_config_file = dirname(__FILE__) . (substr(PHP_OS,0,3) == 'WIN' ? '\\' : '/') . $config_file;
31 if (isset($HTTP_POST_VARS['create'])) header('Location: '.$configurator.'?create=1#create');
32 printf("<?xml version=\"1.0\" encoding=\"%s\"?>\n", 'iso-8859-1');
34 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
35 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
36 <html xmlns="http://www.w3.org/1999/xhtml">
38 <!-- $Id: configurator.php,v 1.25 2005-02-15 17:54:37 rurban Exp $ -->
39 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
40 <title>Configuration tool for PhpWiki <?php echo $config_file ?></title>
41 <style type="text/css" media="screen">
43 /* TABLE { border: thin solid black } */
44 body { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 80%; }
45 pre { font-size: 120%; }
46 td { border: thin solid black }
48 tr.hidden { border: none; display: none; }
49 td.part { background-color: #eeeeee; color: inherit; }
50 td.instructions { background-color: #ffffee; width: <?php echo $tdwidth ?>px; color: inherit; }
51 td.unchangeable-variable-top { border-bottom: none; background-color: #ffffee; color:inherit; }
52 td.unchangeable-variable-left { border-top: none; background-color: #ffffee; color:inherit; }
55 <script language="JavaScript" type="text/javascript">
57 function update(accepted, error, value, output) {
59 document.getElementById(output).innerHTML = "<font color=\"green\">Input accepted.</font>";
61 while ((index = error.indexOf("%s")) > -1) {
62 error = error.substring(0, index) + value + error.substring(index+2);
64 document.getElementById(output).innerHTML = "<font color=\"red\">" + error + "</font>";
68 function validate(error, value, output, field) {
69 update(field.value == value, error, field.value, output);
72 function validate_ereg(error, ereg, output, field) {
73 regex = new RegExp(ereg);
74 update(regex.test(field.value), error, field.value, output);
77 function validate_range(error, low, high, empty_ok, output, field) {
78 update((empty_ok == 1 && field.value == "") ||
79 (field.value >= low && field.value <= high),
80 error, field.value, output);
83 function toggle_group(id) {
84 var text = document.getElementById(id + "_text");
86 if (text.innerHTML == "Hide options.") {
88 text.innerHTML = "Show options.";
90 text.innerHTML = "Hide options.";
93 var rows = document.getElementsByTagName('tr');
95 for (i = 0; i < rows.length; i++) {
97 if (tr.className == 'header' && tr.id == id) {
102 for (; i < rows.length; i++) {
104 if (tr.className == 'header')
106 tr.className = do_hide ? 'hidden': 'nonhidden';
111 // Hide all groups. We do this via JavaScript to avoid
112 // hiding the groups if JavaScript is not supported...
113 var rows = document.getElementsByTagName('tr');
114 for (var i = 0; i < rows.length; i++) {
116 if (tr.className == 'header')
120 // Select text in textarea upon focus
121 var area = document.getElementById('config-output');
123 listener = { handleEvent: function (e) { area.select(); } };
124 area.addEventListener('focus', listener, false);
131 <body onload="do_init();">
133 <h1>Configuration for PhpWiki <?php echo $config_file ?></h1>
136 //define('DEBUG', 1);
138 * The Configurator is a php script to aid in the configuration of PhpWiki.
139 * Parts of this file are based on PHPWeather's configurator.php file.
140 * http://sourceforge.net/projects/phpweather/
142 * TO CHANGE THE CONFIGURATION OF YOUR PHPWIKI, DO *NOT* MODIFY THIS FILE!
143 * more instructions go here
146 * * start this automatically the first time
148 * * eval index.php to get the actual settings.
149 * * ask to store it in index.php or settings.php
152 //////////////////////////////
153 // begin configuration options
156 * Notes for the description parameter of $property:
158 * - Descriptive text will be changed into comments (preceeded by //)
159 * for the final output to index.php.
161 * - Only a limited set of html is allowed: pre, dl dt dd; it will be
162 * stripped from the final output.
164 * - Line breaks and spacing will be preserved for the final output.
166 * - Double line breaks are automatically converted to paragraphs
167 * for the html version of the descriptive text.
169 * - Double-quotes and dollar signs in the descriptive text must be
170 * escaped: \" and \$. Instead of escaping double-quotes you can use
171 * single (') quotes for the enclosing quotes.
173 * - Special characters like < and > must use html entities,
174 * they will be converted back to characters for the final output.
177 $SEPARATOR = ";=========================================================================";
180 ; This is the main configuration file for PhpWiki.
181 ; Note that certain characters are used as comment char and therefore
182 ; these entries must be in double-quotes. Such as \":\", \";\", \",\" and \"|\"
184 ; This file is divided into eight parts: Parts Zero, One, Two, Three,
185 ; Four, Five, Six and Seven. Each one has different configuration settings you can
186 ; change; in all cases the default should work on your system,
187 ; however, we recommend you tailor things to your particular setting.
190 $properties["Part Zero"] =
191 new part('_part0', $SEPARATOR."\n", "
192 Part Zero: (optional)
193 Latest Development and Tricky Options");
195 if (substr(PHP_OS,0,3) == 'WIN') {
196 $include_path = dirname(__FILE__) . ';' . ini_get('include_path');
197 if (strchr(ini_get('include_path'),'/'))
198 $include_path = strtr($include_path,'\\','/');
200 $include_path = dirname(__FILE__) . ':' . ini_get('include_path');
203 $properties["PHP include_path"] =
204 new _define_optional('INCLUDE_PATH', ini_get('include_path'), "
205 If PHP needs help in finding where you installed the rest of the PhpWiki
206 code, you can set the include_path here.
208 Override the PHP include path so that it can find some needed additional libraries.
209 You shouldn't need to do this unless your system include_path esp. your
210 system pear libs are broken or oudated. The PHPWIKI_DIR is automatically
211 put to the front and the local lib/pear path is automatically added to the end.
212 But if you define it, be sure to include either the system pear path or
213 the phpwiki/lib/pear path to override your Pear_DB.
214 Note that on Windows-based servers, you should use ; rather than :
215 as the path separator.");
217 $properties["DEBUG"] =
218 new _define_optional('DEBUG', '0', "
219 Set DEBUG to 1 to view the XHTML and CSS validator icons, page
220 processing timer, and possibly other debugging messages at the
221 bottom of each page. 65 for a more verbose level.
222 See lib/config.php for all supported values.");
224 $properties["ENABLE_USER_NEW"] =
225 new boolean_define_commented_optional
227 array('true' => "Enabled",
228 'false' => "Disabled."), "
229 Enable the new method of handling WikiUser Authetincation and Preferences.
230 It's best to leave it on, and only disable it if you have problems with it.
231 Servers with memory-limit problems might want to turn it off. It costs ~300KB
234 $properties["ENABLE_PAGEPERM"] =
235 new boolean_define_commented_optional
237 array('true' => "Enabled",
238 'false' => "Disabled."), "
239 I suspect ACL page permissions to degrade speed by 10%. Default: true");
241 $properties["ENABLE_EDIT_TOOLBAR"] =
242 new boolean_define_commented_optional
243 ('ENABLE_EDIT_TOOLBAR',
244 array('true' => "Enabled",
245 'false' => "Disabled."), "
246 Graphical buttons on edit. Default: true
247 Reportedly broken on MacOSX Safari");
249 $properties["JS_SEARCHREPLACE"] =
250 new boolean_define_commented_optional
252 array('true' => "Enabled",
253 'false' => "Disabled."), "
254 Adds two additional buttons in EDIT_TOOLBAR, Search&Replace and Undo.
255 Undo is experimental.");
257 $properties["ENABLE_DOUBLECLICKEDIT"] =
258 new boolean_define_commented_optional
259 ('ENABLE_DOUBLECLICKEDIT',
260 array('true' => "Enabled",
261 'false' => "Disabled."), "
264 $properties["ENABLE_XHTML_XML"] =
265 new boolean_define_commented_optional
267 array('true' => "Enabled",
268 'false' => "Disabled."), "
269 Needed for inlined SVG and MathM, but may conflict with document.write().
270 Experimental. Default: false");
272 $properties["USECACHE"] =
273 new boolean_define_commented_optional
275 array('true' => "Enabled",
276 'false' => "Disabled."), "
277 Store DB query results in memory to avoid duplicate queries.
278 Disable only for old php's with low memory or memory_limit=8MB.
281 $properties["ENABLE_SPAMASSASSIN"] =
282 new boolean_define_commented_optional
283 ('ENABLE_SPAMASSASSIN',
284 array('true' => "Enabled",
285 'false' => "Disabled."), "
286 Needs babycart installed. See http://phpwiki.org/SpamAssassinIntegration
287 Optionally define BABYCART_PATH. Default: /usr/local/bin/babycart");
289 $properties["GOOGLE_LINKS_NOFOLLOW"] =
290 new boolean_define_commented_optional
291 ('GOOGLE_LINKS_NOFOLLOW',
292 array('true' => "Enabled",
293 'false' => "Disabled."), "
294 If enabled ref=nofollow is added to all external links to discourage spam.
295 You might want to turn it off, if you want to improve pageranks on external links.");
297 $properties["ENABLE_LIVESEARCH"] =
298 new boolean_define_commented_optional
299 ('ENABLE_LIVESEARCH',
300 array('true' => "Enabled",
301 'false' => "Disabled."), "
302 LiveSearch enables immediate title search results via XMLHttpRequest.
303 Displays the results in a dropdown under the titlesearch inputbox
304 while typing. (experimental, only with certain themes)
305 You'll have to copy livesearch.js from http://blog.bitflux.ch/wiki/LiveSearch
306 to themes/default/ and define ENABLE_LIVESEARCH in config.ini to true.
307 See themes/blog/themeinfo.php.
308 Currently we use the bitflux.ch library, but we will change to
309 the russian acdropdown soon. http://momche.net/publish/article.php?page=acdropdown");
311 $properties["Part One"] =
312 new part('_partone', $SEPARATOR."\n", "
313 Part One: Authentication and security settings. See Part Three for more.");
315 $properties["Admin Username"] =
316 new _define_optional_notempty('ADMIN_USER', "", "
317 You must set this! Username and password of the administrator.",
318 "onchange=\"validate_ereg('Sorry, ADMIN_USER cannot be empty.', '^.+$', 'ADMIN_USER', this);\"");
320 $properties["Admin Password"] =
321 new _define_password_optional('ADMIN_PASSWD', "", "
322 For heaven's sake pick a good password.
323 If your version of PHP supports encrypted passwords, your password will be
324 automatically encrypted within the generated config file.
325 Use the \"Create Random Password\" button to create a good (random) password.",
326 "onchange=\"validate_ereg('Sorry, ADMIN_PASSWD must be at least 4 chars long.', '^....+$', 'ADMIN_PASSWD', this);\"");
329 $properties["Wiki Name"] =
330 new _define_optional('WIKI_NAME', 'PhpWiki', "
331 The name of your wiki.
333 This is used to generate a keywords meta tag in the HTML templates,
334 in bookmark titles for any bookmarks made to pages in your wiki,
335 and during RSS generation for the title of the RSS channel.
337 It is recommended this be a relatively short WikiWord like the
338 InterWiki monikers found in the InterWikiMap. (For examples, see
342 $properties["Reverse DNS"] =
343 new boolean_define_optional
344 ('ENABLE_REVERSE_DNS',
345 array('true' => "true. perform additional reverse dns lookups",
346 'false' => "false. just record the address as given by the httpd server"),
348 If set, we will perform reverse dns lookups to try to convert the
349 users IP number to a host name, even if the http server didn't do it for us.");
351 $properties["ZIPdump Authentication"] =
352 new boolean_define_optional('ZIPDUMP_AUTH',
353 array('false' => "false. Everyone may download zip dumps",
354 'true' => "true. Only admin may download zip dumps"), "
355 If true, only the admin user can make zip dumps, else zip dumps
356 require no authentication.");
358 $properties["Enable RawHtml Plugin"] =
359 new boolean_define_commented_optional
361 array('true' => "Enabled",
362 'false' => "Disabled."), "
363 The RawHtml plugin allows page authors to embed real, raw HTML into Wiki
364 pages. This is a possible security threat, as much HTML (or, rather,
365 JavaScript) can be very risky. If you are in a controlled environment,
366 however, it could be of use.");
368 $properties["Allow RawHtml Plugin only on locked pages"] =
369 new boolean_define_commented_optional
370 ('ENABLE_RAW_HTML_LOCKEDONLY',
371 array('true' => "Enabled",
372 'false' => "Disabled."), "
373 If this is set, only pages locked by the Administrator may contain the RawHtml plugin.");
375 $properties["Allow RawHtml Plugin if safe HTML code"] =
376 new boolean_define_commented_optional
377 ('ENABLE_RAW_HTML_SAFE',
378 array('true' => "Enabled",
379 'false' => "Disabled."), "
380 If this is set, all unsafe html code is stripped automatically (experimental!)
381 See <a href=\"http://chxo.com/scripts/safe_html-test.php\" target=\"_new\">chxo.com/scripts/safe_html-test.php</a>
384 $properties["Strict Mailable Pagedumps"] =
385 new boolean_define_optional
386 ('STRICT_MAILABLE_PAGEDUMPS',
387 array('false' => "binary",
388 'true' => "quoted-printable"),
390 If you define this to true, (MIME-type) page-dumps (either zip dumps,
391 or \"dumps to directory\" will be encoded using the quoted-printable
392 encoding. If you're actually thinking of mailing the raw page dumps,
393 then this might be useful, since (among other things,) it ensures
394 that all lines in the message body are under 80 characters in length.
396 Also, setting this will cause a few additional mail headers
397 to be generated, so that the resulting dumps are valid
398 RFC 2822 e-mail messages.
400 Probably, you can just leave this set to false, in which case you get
401 raw ('binary' content-encoding) page dumps.");
403 $properties["HTML Dump Filename Suffix"] =
404 new _variable('HTML_DUMP_SUFFIX', ".html", "
405 Here you can change the filename suffix used for XHTML page dumps.
406 If you don't want any suffix just comment this out.");
408 //FIXME: should be numeric_define_optional
409 $properties["Maximum Upload Size"] =
410 new numeric_define('MAX_UPLOAD_SIZE', "16 * 1024 * 1024", "
411 The maximum file upload size.");
413 //FIXME: should be numeric_define_optional
414 $properties["Minor Edit Timeout"] =
415 new numeric_define('MINOR_EDIT_TIMEOUT', "7 * 24 * 3600", "
416 If the last edit is older than MINOR_EDIT_TIMEOUT seconds, the
417 default state for the \"minor edit\" checkbox on the edit page form
420 $properties["Disabled Actions"] =
421 new array_variable('DisabledActions', array(), "
422 Actions listed in this array will not be allowed. Actions are:
423 browse, create, diff, dumphtml, dumpserial, edit, loadfile, lock, remove,
424 unlock, upload, viewsource, zip, ziphtml");
426 $properties["Access Log"] =
427 new _define_commented('ACCESS_LOG', "/var/logs/wiki_access.log", "
428 PhpWiki can generate an access_log (in \"NCSA combined log\" format)
429 for you. If you want one, define this to the name of the log file,
430 such as /tmp/wiki_access_log.");
432 $properties["Compress Output"] =
433 new boolean_define_commented_optional
435 array('' => 'Compress when PhpWiki thinks appropriate.',
436 'false' => 'Never compress output.',
437 'true' => 'Always try to compress output.'),
439 By default PhpWiki will try to have PHP compress it's output
440 before sending it to the browser (if you have a recent enough
441 version of PHP and the browser supports it.)
443 Define COMPRESS_OUTPUT to false to prevent output compression.
445 Define COMPRESS_OUTPUT to true to force output compression,
446 even if we think your version of PHP does this in a buggy
449 Leave it undefined to leave the choice up to PhpWiki.");
451 $properties["HTTP Cache Control"] =
452 new _define_selection_optional
454 array('LOOSE' => 'LOOSE',
455 'STRICT' => 'STRICT',
456 'NO_CACHE' => 'NO_CACHE',
457 'ALLOW_STALE' => 'ALLOW_STALE'),
461 This controls how PhpWiki sets the HTTP cache control
462 headers (Expires: and Cache-Control:)
468 <dd>This is roughly the old (pre 1.3.4) behaviour. PhpWiki will
469 instruct proxies and browsers never to cache PhpWiki output.</dd>
472 <dd>Cached pages will be invalidated whenever the database global
473 timestamp changes. This should behave just like NONE (modulo
474 bugs in PhpWiki and your proxies and browsers), except that
475 things will be slightly more efficient.</dd>
478 <dd>Cached pages will be invalidated whenever they are edited,
479 or, if the pages include plugins, when the plugin output could
480 concievably have changed.
482 <p>Behavior should be much like STRICT, except that sometimes
483 wikilinks will show up as undefined (with the question mark)
484 when in fact they refer to (recently) created pages.
485 (Hitting your browsers reload or perhaps shift-reload button
486 should fix the problem.)</p></dd>
489 <dd>Proxies and browsers will be allowed to used stale pages.
490 (The timeout for stale pages is controlled by CACHE_CONTROL_MAX_AGE.)
492 <p>This setting will result in quirky behavior. When you edit a
493 page your changes may not show up until you shift-reload the
496 <p>This setting is generally not advisable, however it may be useful
497 in certain cases (e.g. if your wiki gets lots of page views,
498 and few edits by knowledgable people who won't freak over the quirks.)</p>
501 The default is currently LOOSE.");
503 // FIXME: should be numeric_define_optional
504 $properties["HTTP Cache Control Max Age"] =
505 new numeric_define('CACHE_CONTROL_MAX_AGE', 600,
507 Maximum page staleness, in seconds.");
509 $properties["Markup Caching"] =
510 new boolean_define_commented_optional
511 ('WIKIDB_NOCACHE_MARKUP',
512 array('false' => 'Enable markup cache',
513 'true' => 'Disable markup cache'),
517 PhpWiki normally caches a preparsed version (i.e. mostly
518 converted to HTML) of the most recent version of each page.
519 (Parsing the wiki-markup takes a fair amount of CPU.)
521 Define WIKIDB_NOCACHE_MARKUP to true to disable the
522 caching of marked-up page content.
524 Note that you can also disable markup caching on a per-page
525 temporary basis by addinging a query arg of '?nocache=1'
526 to the URL to the page. (Use '?nocache=purge' to completely
527 discard the cached version of the page.)
529 You can also purge the cached markup globally by using the
530 \"Purge Markup Cache\" button on the PhpWikiAdministration page.");
532 $properties["Path for PHP Session Support"] =
533 new _define_optional('SESSION_SAVE_PATH', ini_get('session.save_path'), "
534 The login code now uses PHP session support. Usually, the default
535 configuration of PHP is to store the session state information in
536 /tmp. That probably will work fine, but fails e.g. on clustered
537 servers where each server has their own distinct /tmp (this is the
538 case on SourceForge's project web server.) You can specify an
539 alternate directory in which to store state information like so
540 (whatever user your httpd runs as must have read/write permission
542 on USE_DB_SESSION = true you can ignore this.
545 ///////// database selection
547 $properties["Part Two"] =
548 new part('_parttwo', $SEPARATOR."\n", "
551 Database Configuration
554 $properties["Database Type"] =
555 new _define_selection("DATABASE_TYPE",
556 array('dba' => "dba",
558 'ADODB' => "SQL ADODB",
559 'PDO' => "PDO (php5 only)",
560 'file' => "flatfile",
561 'cvs' => "CVS File handler"), "
562 Select the database backend type:
563 Choose dba (default) to use one of the standard UNIX dba libraries. This is the fastest.
564 Choose ADODB or SQL to use an SQL database with ADODB or PEAR.
565 Choose PDO on php5 to use an SQL database.
566 flatfile is simple and slow.
567 CVS is highly experimental and slow.
568 Recommended is dba or SQL: PEAR or ADODB.");
570 $properties["SQL DSN Setup"] =
571 new unchangeable_variable('_sqldsnstuff', "", "
572 For SQL based backends, specify the database as a DSN
573 The most general form of a DSN looks like:
575 phptype(dbsyntax)://username:password@protocol+hostspec/database?option=value
577 For a MySQL database, the following should work:
579 mysql://user:password@host/databasename
581 To connect over a unix socket, use something like
583 mysql://user:password@unix(/path/to/socket)/databasename
586 DATABASE_DSN = mysql://guest@:/var/lib/mysql/mysql.sock/phpwiki
587 DATABASE_DSN = mysql://guest@localhost/phpwiki
588 DATABASE_DSN = pgsql://localhost/user_phpwiki
591 // Choose ADODB or SQL to use an SQL database with ADODB or PEAR.
592 // Choose dba to use one of the standard UNIX dbm libraries.
594 $properties["SQL Type"] =
595 new _variable_selection('_dsn_sqltype',
596 array('mysql' => "MySQL",
597 'pgsql' => "PostgreSQL",
598 'mssql' => "Microsoft SQL Server",
599 'oci8' => "Oracle 8",
600 'mysqli' => "mysqli (only ADODB)",
601 'mysqlt' => "mysqlt (only ADODB)",
602 'ODBC' => "ODBC (only ADODB or PDO)",
603 'firebird' => "Firebird (only PDO)",
604 'oracle' => "Oracle (only PDO)",
606 SQL DB types. The DSN hosttype.");
608 $properties["SQL User"] =
609 new _variable('_dsn_sqluser', "wikiuser", "
612 $properties["SQL Password"] =
613 new _variable('_dsn_sqlpass', "", "
616 $properties["SQL Database Host"] =
617 new _variable('_dsn_sqlhostorsock', "localhost", "
618 SQL Database Hostname:
620 To connect over a local named socket, use something like
622 unix(/var/lib/mysql/mysql.sock)
625 mysql on Windows via named pipes might need 127.0.0.1");
627 $properties["SQL Database Name"] =
628 new _variable('_dsn_sqldbname', "phpwiki", "
629 SQL Database Name:");
631 $dsn_sqltype = $properties["SQL Type"]->value();
632 $dsn_sqluser = $properties["SQL User"]->value();
633 $dsn_sqlpass = $properties["SQL Password"]->value();
634 $dsn_sqlhostorsock = $properties["SQL Database Host"]->value();
635 $dsn_sqldbname = $properties["SQL Database Name"]->value();
636 $dsn_sqlstring = $dsn_sqltype."://{$dsn_sqluser}:{$dsn_sqlpass}@{$dsn_sqlhostorsock}/{$dsn_sqldbname}";
638 $properties["SQL dsn"] =
639 new unchangeable_define("DATABASE_DSN",
640 "DATABASE_DSN = \"$dsn_sqlstring\"", "
641 Calculated from the settings above:");
643 $properties["Filename / Table name Prefix"] =
644 new _define_commented("DATABASE_PREFIX", "", "
645 Used by all DB types:
647 Prefix for filenames or table names, e.g. \"phpwiki_\"
649 Currently <b>you MUST EDIT THE SQL file too!</b> (in the schemas/
650 directory because we aren't doing on the fly sql generation
651 during the installation.");
653 $properties["DB Session table"] =
654 new _define_optional("DATABASE_SESSION_TABLE", "session", "
655 Tablename to store session information. Only supported by SQL backends.
657 A word of warning - any prefix defined above will be prepended to whatever is given here.
661 $temp = !empty($_ENV['TEMP']) ? $_ENV['TEMP'] : "/tmp";
662 $properties["dba directory"] =
663 new _define("DATABASE_DIRECTORY", $temp, "
666 // TODO: list the available methods
667 $properties["dba handler"] =
668 new _define_selection('DATABASE_DBA_HANDLER',
669 array('gdbm' => "Gdbm - GNU database manager (recommended)",
670 'dbm' => "DBM - Redhat default. On sf.net there's dbm and gdbm",
671 'db2' => "DB2 - Sleepycat Software's DB2",
672 'db3' => "DB3 - Sleepycat Software's DB3. Default on Windows but not on every Linux",
673 'db4' => "DB4 - Sleepycat Software's DB4."), "
674 Use 'gdbm', 'dbm', 'db2', 'db3' or 'db4' depending on your DBA handler methods supported: <br > "
675 . (function_exists("dba_handlers") ? join(", ",dba_handlers()) : ""));
677 $properties["dba timeout"] =
678 new numeric_define("DATABASE_TIMEOUT", "12", "
679 Recommended values are 10-20.");
683 $properties["Page Revisions"] =
684 new unchangeable_variable('_parttworevisions', "", "
686 Section 2a: Archive Cleanup
687 The next section controls how many old revisions of each page are kept in the database.
689 There are two basic classes of revisions: major and minor. Which
690 class a revision belongs in is determined by whether the author
691 checked the \"this is a minor revision\" checkbox when they saved the
694 There is, additionally, a third class of revisions: author
695 revisions. The most recent non-mergable revision from each distinct
696 author is and author revision.
698 The expiry parameters for each of those three classes of revisions
699 can be adjusted seperately. For each class there are five
700 parameters (usually, only two or three of the five are actually
701 set) which control how long those revisions are kept in the
704 <dt>max_keep:</dt> <dd>If set, this specifies an absolute maximum for the
705 number of archived revisions of that class. This is
706 meant to be used as a safety cap when a non-zero
707 min_age is specified. It should be set relatively high,
708 and it's purpose is to prevent malicious or accidental
709 database overflow due to someone causing an
710 unreasonable number of edits in a short period of time.</dd>
712 <dt>min_age:</dt> <dd>Revisions younger than this (based upon the supplanted
713 date) will be kept unless max_keep is exceeded. The age
714 should be specified in days. It should be a
715 non-negative, real number,</dd>
717 <dt>min_keep:</dt> <dd>At least this many revisions will be kept.</dd>
719 <dt>keep:</dt> <dd>No more than this many revisions will be kept.</dd>
721 <dt>max_age:</dt> <dd>No revision older than this age will be kept.</dd>
723 Supplanted date: Revisions are timestamped at the instant that they
724 cease being the current revision. Revision age is computed using
725 this timestamp, not the edit time of the page.
727 Merging: When a minor revision is deleted, if the preceding
728 revision is by the same author, the minor revision is merged with
729 the preceding revision before it is deleted. Essentially: this
730 replaces the content (and supplanted timestamp) of the previous
731 revision with the content after the merged minor edit, the rest of
732 the page metadata for the preceding version (summary, mtime, ...)
736 // For now the expiration parameters are statically inserted as
737 // an unchangeable property. You'll have to edit the resulting
738 // config file if you really want to change these from the default.
740 $properties["Major Edits: keep minumum days"] =
741 new numeric_define("MAJOR_MIN_KEEP", "2147483647", "
742 Default: Keep at least for unlimited time.
743 Set to 0 to enable archive cleanup");
744 $properties["Minor Edits: keep minumum days"] =
745 new numeric_define("MINOR_MIN_KEEP", "2147483647", "
746 Default: Keep at least for unlimited time.
747 Set to 0 to enable archive cleanup");
749 $properties["Major Edits: how many"] =
750 new numeric_define("MAJOR_KEEP", "8", "
751 Keep up to 8 major edits");
752 $properties["Major Edits: how many days"] =
753 new numeric_define("MAJOR_MAX_AGE", "32", "
754 keep them no longer than a month");
756 $properties["Minor Edits: how many"] =
757 new numeric_define("MINOR_KEEP", "4", "
758 Keep up to 4 minor edits");
759 $properties["Minor Edits: how many days"] =
760 new numeric_define("MINOR_MAX_AGE", "7", "
761 keep them no longer than a week");
763 $properties["per Author: how many"] =
764 new numeric_define("AUTHOR_KEEP", "8", "
765 Keep the latest contributions of the last 8 authors,");
766 $properties["per Author: how many days"] =
767 new numeric_define("AUTHOR_MAX_AGE", "365", "
769 $properties["per Author: keep minumum days"] =
770 new numeric_define("AUTHOR_MIN_AGE", "7", "
771 Additionally, (in the case of a particularly active page) try to
772 keep the latest contributions of all authors in the last week (even if there are more than eight of them,)");
773 $properties["per Author: max revisions"] =
774 new numeric_define("AUTHOR_MAX_KEEP", "20", "
775 but in no case keep more than twenty unique author revisions.");
777 /////////////////////////////////////////////////////////////////////
779 $properties["Part Three"] =
780 new part('_partthree', $SEPARATOR."\n", "
782 Part Three: (optional)
783 Basic User Authentication Setup
786 $properties["Publicly viewable"] =
787 new boolean_define_optional('ALLOW_ANON_USER',
788 array('true' => "true. Permit anonymous view. (Default)",
789 'false' => "false. Force login even on view (strictly private)"), "
790 If ALLOW_ANON_USER is false, you have to login before viewing any page or doing any other action on a page.");
792 $properties["Allow anonymous edit"] =
793 new boolean_define_optional('ALLOW_ANON_EDIT',
794 array('true' => "true. Permit anonymous users to edit. (Default)",
795 'false' => "false. Force login on edit (moderately locked)"), "
796 If ALLOW_ANON_EDIT is false, you have to login before editing or changing any page. See below.");
798 $properties["Allow Bogo Login"] =
799 new boolean_define_optional('ALLOW_BOGO_LOGIN',
800 array('true' => "true. Users may Sign In with any WikiWord, without password. (Default)",
801 'false' => "false. Require stricter authentication."), "
802 If ALLOW_BOGO_LOGIN is false, you may not login with any wikiword username and empty password.
803 If true, users are allowed to create themselves with any WikiWord username. See below.");
805 $properties["Allow User Passwords"] =
806 new boolean_define_optional('ALLOW_USER_PASSWORDS',
807 array('true' => "True user authentication with password checking. (Default)",
808 'false' => "false. Ignore authentication settings below."), "
809 If ALLOW_USER_PASSWORDS is true, the authentication settings below define where and how to
810 check against given username/passwords. For completely security disable BOGO_LOGIN and ANON_EDIT above.");
812 $properties["Allow User Passwords"] =
813 new array_define('USER_AUTH_ORDER', array("PersonalPage", "Db"), "
814 Many different methods can be used to check user's passwords.
815 Try any of these in the given order:
818 <dd>WikiWord username, with no *actual* password checking,
819 although the user will still have to enter one.</dd>
820 <dt>PersonalPage</dt>
821 <dd>Store passwords in the users homepage metadata (simple)</dd>
823 <dd>Use DBAUTH_AUTH_* (see below) with PearDB or ADODB only.</dd>
825 <dd>Authenticate against LDAP_AUTH_HOST with LDAP_BASE_DN</dd>
827 <dd>Authenticate against IMAP_AUTH_HOST (email account)</dd>
829 <dd>Authenticate against POP3_AUTH_HOST (email account)</dd>
831 <dd>Get username and level from a PHP session variable. (e.g. for gforge)</dd>
833 <dd>Store username:crypted-passwords in .htaccess like files.
834 Use Apache's htpasswd to manage this file.</dd>
836 <dd>Use the protection by the webserver (.htaccess/.htpasswd) (experimental)
837 Enforcing HTTP Auth not yet. Note that the ADMIN_USER should exist also.
838 Using HttpAuth disables all other methods and no userauth sessions are used.</dd>
841 Several of these methods can be used together, in the manner specified by
842 USER_AUTH_POLICY, below. To specify multiple authentication methods,
843 separate the name of each one with colons.
845 USER_AUTH_ORDER = 'PersonalPage : Db'
846 USER_AUTH_ORDER = 'BogoLogin : PersonalPage'</pre>");
848 $properties["PASSWORD_LENGTH_MINIMUM"] =
849 new numeric_define("PASSWORD_LENGTH_MINIMUM", "6", "
850 For 'security' purposes, you can specify that a password be at least a
851 certain number of characters long. This applies even to the BogoLogin method.
852 Default: 0 (to allow immediate passwordless BogoLogin)");
854 $properties["USER_AUTH_POLICY"] =
855 new _define_selection('USER_AUTH_POLICY',
856 array('first-only' => "first-only - use only the first method in USER_AUTH_ORDER",
857 'old' => "old - ignore USER_AUTH_ORDER (legacy)",
858 'strict' => "strict - check all methods for userid + password (recommended)",
859 'stacked' => "stacked - check all methods for userid, and if found for password"), "
860 The following policies are available for user authentication:
863 <dd>use only the first method in USER_AUTH_ORDER</dd>
865 <dd>ignore USER_AUTH_ORDER and try to use all available
866 methods as in the previous PhpWiki releases (slow)</dd>
868 <dd>check if the user exists for all methods:
869 on the first existing user, try the password.
870 dont try the other methods on failure then</dd>
872 <dd>check the given user - password combination for all
873 methods and return true on the first success.</dd></dl>");
877 $properties["Part Three A"] =
878 new part('_partthree_a', $SEPARATOR."\n", "
880 Part Three A: (optional)
883 $properties["Group membership"] =
884 new _define_selection("GROUP_METHOD",
885 array('WIKIPAGE' => "WIKIPAGE - List at \"CategoryGroup\". (Slowest, but easiest to maintain)",
886 '"NONE"' => "NONE - Disable group membership (Fastest)",
887 'DB' => "DB - SQL Database, Optionally external. See USERS/GROUPS queries",
888 'FILE' => "Flatfile. See AUTH_GROUP_FILE below.",
889 'LDAP' => "LDAP - See \"LDAP authentication options\" above. (Experimental)"), "
890 Group membership. PhpWiki supports defining permissions for a group as
891 well as for individual users. This defines how group membership information
892 is obtained. Supported values are:
895 <dd>Disable group membership (Fastest). Note the required quoting.</dd>
897 <dd>Define groups as list at \"CategoryGroup\". (Slowest, but easiest to maintain)</dd>
899 <dd>Stored in an SQL database. Optionally external. See USERS/GROUPS queries</dd>
901 <dd>Flatfile. See AUTH_GROUP_FILE below.</dd>
903 <dd>LDAP groups. See \"LDAP authentication options\" above and
904 lib/WikiGroup.php. (experimental)</dd></dl>");
906 $properties["CATEGORY_GROUP_PAGE"] =
907 new _define_optional('CATEGORY_GROUP_PAGE', _("CategoryGroup"), "
908 If GROUP_METHOD = WIKIPAGE:
910 Page where all groups are listed.");
912 $properties["AUTH_GROUP_FILE"] =
913 new _define_optional('AUTH_GROUP_FILE', _("/etc/groups"), "
914 For GROUP_METHOD = FILE, the file given below is referenced to obtain
915 group membership information. It should be in the same format as the
916 standard unix /etc/groups(5) file.");
918 $properties["Part Three B"] =
919 new part('_partthree_b', $SEPARATOR."\n", "
921 Part Three B: (optional)
922 External database authentication and authorization.
924 If USER_AUTH_ORDER includes Db, or GROUP_METHOD = DB, the options listed
925 below define the SQL queries used to obtain the information out of the
926 database, and (optionally) store the information back to the DB.");
928 $properties["DBAUTH_AUTH_DSN"] =
929 new _define_optional('DBAUTH_AUTH_DSN', $dsn_sqlstring, "
930 A database DSN to connect to. Defaults to the DSN specified for the Wiki as a whole.");
932 $properties["User Exists Query"] =
933 new _define('DBAUTH_AUTH_USER_EXISTS', "\"SELECT userid FROM user WHERE userid='\$userid'\"", "
934 USER/PASSWORD queries:
936 For USER_AUTH_POLICY=strict and the Db method is required");
938 $properties["Check Query"] =
939 new _define_optional('DBAUTH_AUTH_CHECK', "\"SELECT IF(passwd='\$password',1,0) AS ok FROM user WHERE userid='\$userid'\"", "
941 Check to see if the supplied username/password pair is OK
943 Plaintext passwords: (DBAUTH_AUTH_CRYPT_METHOD = plain)<br>
944 ; DBAUTH_AUTH_CHECK = \"SELECT IF(passwd='\$password',1,0) AS ok FROM user WHERE userid='\$userid'\"
946 database-hashed passwords (more secure):<br>
947 ; DBAUTH_AUTH_CHECK = \"SELECT IF(passwd=PASSWORD('\$password'),1,0) AS ok FROM user WHERE userid='\$userid'\"");
949 $properties["Crypt Method"] =
950 new _define_selection_optional
951 ('DBAUTH_AUTH_CRYPT_METHOD',
952 array('plain' => 'plain',
953 'crypt' => 'crypt'), "
954 If you want to use Unix crypt()ed passwords, you can use DBAUTH_AUTH_CHECK
955 to get the password out of the database with a simple SELECT query, and
956 specify DBAUTH_AUTH_USER_EXISTS and DBAUTH_AUTH_CRYPT_METHOD:
958 ; DBAUTH_AUTH_CHECK = \"SELECT passwd FROM user where userid='\$userid'\" <br>
959 ; DBAUTH_AUTH_CRYPT_METHOD = crypt");
961 $properties["Update the user's authentication credential"] =
962 new _define('DBAUTH_AUTH_UPDATE', "\"UPDATE user SET passwd='\$password' WHERE userid='\$userid'\"", "
963 If this is not defined but DBAUTH_AUTH_CHECK is, then the user will be unable to update their
966 Plaintext passwords:<br>
967 DBAUTH_AUTH_UPDATE = \"UPDATE user SET passwd='\$password' WHERE userid='\$userid'\"<br>
968 Database-hashed passwords:<br>
969 DBAUTH_AUTH_UPDATE = \"UPDATE user SET passwd=PASSWORD('\$password') WHERE userid='\$userid'\"");
971 $properties["Allow the user to create their own account"] =
972 new _define_optional('DBAUTH_AUTH_CREATE', "\"INSERT INTO user SET passwd=PASSWORD('\$password'),userid='\$userid'\"", "
973 If this is empty, Db users cannot subscribe by their own.");
975 $properties["USER/PREFERENCE queries"] =
976 new _define_optional('DBAUTH_PREF_SELECT', "\"SELECT prefs FROM user WHERE userid='\$userid'\"", "
977 If you choose to store your preferences in an external database, enable
978 the following queries. Note that if you choose to store user preferences
979 in the 'user' table, only registered users get their prefs from the database,
980 self-created users do not. Better to use the special 'pref' table.
982 The prefs field stores the serialized form of the user's preferences array,
983 to ease the complication of storage.
985 DBAUTH_PREF_SELECT = \"SELECT prefs FROM user WHERE userid='\$userid'\"
986 DBAUTH_PREF_SELECT = \"SELECT prefs FROM pref WHERE userid='\$userid'\"
989 $properties["Update the user's preferences"] =
990 new _define_optional('DBAUTH_PREF_UPDATE', "\"UPDATE user SET prefs='\$pref_blob' WHERE userid='\$userid'\"", "
991 Note that REPLACE works only with mysql and destroy all other columns!
993 Mysql: DBAUTH_PREF_UPDATE = \"REPLACE INTO pref SET prefs='\$pref_blob',userid='\$userid'\"");
995 $properties["USERS/GROUPS queries"] =
996 new _define_optional('DBAUTH_IS_MEMBER', "\"SELECT user FROM user WHERE user='\$userid' AND group='\$groupname'\"", "
997 You can define 1:n or n:m user<=>group relations, as you wish.
999 Sample configurations:
1001 only one group per user (1:n):<br>
1002 DBAUTH_IS_MEMBER = \"SELECT user FROM user WHERE user='\$userid' AND group='\$groupname'\"<br>
1003 DBAUTH_GROUP_MEMBERS = \"SELECT user FROM user WHERE group='\$groupname'\"<br>
1004 DBAUTH_USER_GROUPS = \"SELECT group FROM user WHERE user='\$userid'\"<br>
1005 multiple groups per user (n:m):<br>
1006 DBAUTH_IS_MEMBER = \"SELECT userid FROM member WHERE userid='\$userid' AND groupname='\$groupname'\"<br>
1007 DBAUTH_GROUP_MEMBERS = \"SELECT DISTINCT userid FROM member WHERE groupname='\$groupname'\"<br>
1008 DBAUTH_USER_GROUPS = \"SELECT groupname FROM member WHERE userid='\$userid'\"<br>");
1009 $properties["DBAUTH_GROUP_MEMBERS"] =
1010 new _define_optional('DBAUTH_GROUP_MEMBERS', "\"SELECT user FROM user WHERE group='\$groupname'\"", "");
1011 $properties["DBAUTH_USER_GROUPS"] =
1012 new _define_optional('DBAUTH_USER_GROUPS', "\"SELECT group FROM user WHERE user='\$userid'\"", "");
1014 if (function_exists('ldap_connect')) {
1016 $properties["LDAP AUTH Host"] =
1017 new _define_optional('LDAP_AUTH_HOST', "ldap://localhost:389", "
1018 If USER_AUTH_ORDER contains Ldap:
1020 The LDAP server to connect to. Can either be a hostname, or a complete
1021 URL to the server (useful if you want to use ldaps or specify a different
1024 $properties["LDAP BASE DN"] =
1025 new _define_optional('LDAP_BASE_DN', "ou=mycompany.com,o=My Company", "
1026 The organizational or domain BASE DN: e.g. \"dc=mydomain,dc=com\".
1028 Note: ou=Users and ou=Groups are used for GroupLdap Membership
1029 Better use LDAP_OU_USERS and LDAP_OU_GROUP with GROUP_METHOD=LDAP.");
1031 $properties["LDAP SET OPTION"] =
1032 new _define_optional('LDAP_SET_OPTION', "LDAP_OPT_PROTOCOL_VERSION=3:LDAP_OPT_REFERRALS=0", "
1033 Some LDAP servers need some more options, such as the Windows Active
1034 Directory Server. Specify the options (as allowed by the PHP LDAP module)
1035 and their values as NAME=value pairs separated by colons.");
1037 $properties["LDAP AUTH USER"] =
1038 new _define_optional('LDAP_AUTH_USER', "CN=ldapuser,ou=Users,o=Development,dc=mycompany.com", "
1039 DN to initially bind to the LDAP server as. This is needed if the server doesn't
1040 allow anonymous queries. (Windows Active Directory Server)");
1042 $properties["LDAP AUTH PASSWORD"] =
1043 new _define_optional('LDAP_AUTH_PASSWORD', "secret", "
1044 Password to use to initially bind to the LDAP server, as the DN
1045 specified in the LDAP_AUTH_USER option (above).");
1047 $properties["LDAP SEARCH FIELD"] =
1048 new _define_optional('LDAP_SEARCH_FIELD', "uid", "
1049 If you want to match usernames against an attribute other than uid,
1050 specify it here. Default: uid
1052 e.g.: LDAP_SEARCH_FIELD = sAMAccountName");
1054 $properties["LDAP OU USERS"] =
1055 new _define_optional('LDAP_OU_USERS', "ou=Users", "
1056 If you have an organizational unit for all users, define it here.
1057 This narrows the search, and is needed for LDAP group membership (if GROUP_METHOD=LDAP)
1058 Default: ou=Users");
1060 $properties["LDAP OU GROUP"] =
1061 new _define_optional('LDAP_OU_GROUP', "ou=Groups", "
1062 If you have an organizational unit for all groups, define it here.
1063 This narrows the search, and is needed for LDAP group membership (if GROUP_METHOD=LDAP)
1064 The entries in this ou must have a gidNumber and cn attribute.
1065 Default: ou=Groups");
1069 $properties["LDAP Authentication"] =
1070 new unchangeable_define('LDAP Authentication', "
1071 If USER_AUTH_ORDER contains Ldap:
1073 The LDAP server to connect to. Can either be a hostname, or a complete
1074 URL to the server (useful if you want to use ldaps or specify a different
1076 ;LDAP_AUTH_HOST = \"ldap://localhost:389\"
1078 ; The organizational or domain BASE DN: e.g. \"dc=mydomain,dc=com\".
1080 ; Note: ou=Users and ou=Groups are used for GroupLdap Membership
1081 ; Better use LDAP_OU_USERS and LDAP_OU_GROUP with GROUP_METHOD=LDAP.
1082 ;LDAP_BASE_DN = \"ou=Users,o=Development,dc=mycompany.com\"
1084 ; Some LDAP servers need some more options, such as the Windows Active
1085 ; Directory Server. Specify the options (as allowed by the PHP LDAP module)
1086 ; and their values as NAME=value pairs separated by colons.
1087 ; LDAP_SET_OPTION = \"LDAP_OPT_PROTOCOL_VERSION=3:LDAP_OPT_REFERRALS=0\"
1089 ; DN to initially bind to the LDAP server as. This is needed if the server doesn't
1090 ; allow anonymous queries. (Windows Active Directory Server)
1091 ; LDAP_AUTH_USER = \"CN=ldapuser,ou=Users,o=Development,dc=mycompany.com\"
1093 ; Password to use to initially bind to the LDAP server, as the DN
1094 ; specified in the LDAP_AUTH_USER option (above).
1095 ; LDAP_AUTH_PASSWORD = secret
1097 ; If you want to match usernames against an attribute other than uid,
1098 ; specify it here. Default: uid
1099 ; LDAP_SEARCH_FIELD = sAMAccountName
1101 ; If you have an organizational unit for all users, define it here.
1102 ; This narrows the search, and is needed for LDAP group membership (if GROUP_METHOD=LDAP)
1104 ; LDAP_OU_USERS = ou=Users
1106 ; If you have an organizational unit for all groups, define it here.
1107 ; This narrows the search, and is needed for LDAP group membership (if GROUP_METHOD=LDAP)
1108 ; The entries in this ou must have a gidNumber and cn attribute.
1109 ; Default: ou=Groups
1110 ; LDAP_OU_GROUP = ou=Groups", "
1111 ; Ignored. No LDAP support in this php. configure --with-ldap");
1114 if (function_exists('imap_open')) {
1116 $properties["IMAP Auth Host"] =
1117 new _define_optional('IMAP_AUTH_HOST', 'localhost:143/imap/notls', "
1118 If USER_AUTH_ORDER contains IMAP:
1120 The IMAP server to check usernames from. Defaults to localhost.
1122 Some IMAP_AUTH_HOST samples:
1123 localhost, localhost:143/imap/notls,
1124 localhost:993/imap/ssl/novalidate-cert (SuSE refuses non-SSL conections)");
1128 $properties["IMAP Authentication"] =
1129 new unchangeable_define('IMAP_AUTH_HOST',"
1130 ; If USER_AUTH_ORDER contains IMAP:
1131 ; The IMAP server to check usernames from. Defaults to localhost.
1133 ; Some IMAP_AUTH_HOST samples:
1134 ; localhost, localhost:143/imap/notls,
1135 ; localhost:993/imap/ssl/novalidate-cert (SuSE refuses non-SSL conections)
1136 ;IMAP_AUTH_HOST = localhost:143/imap/notls", "
1137 Ignored. No IMAP support in this php. configure --with-imap");
1141 $properties["POP3 Authentication"] =
1142 new _define_optional('POP3_AUTH_HOST', 'localhost:110', "
1143 If USER_AUTH_ORDER contains POP3:
1145 The POP3 mail server to check usernames and passwords against.");
1146 $properties["File Authentication"] =
1147 new _define_optional('AUTH_USER_FILE', '/etc/shadow', "
1148 If USER_AUTH_ORDER contains File:
1150 File to read for authentication information.
1151 Popular choices are /etc/shadow and /etc/httpd/.htpasswd");
1153 $properties["File Storable?"] =
1154 new boolean_define_commented_optional
1155 ('AUTH_USER_FILE_STORABLE',
1156 array('false' => "Disabled",
1157 'true' => "Enabled"), "
1158 Defines whether the user is able to change their own password via PhpWiki.
1159 Note that this means that the webserver user must be able to write to the
1160 file specified in AUTH_USER_FILE.");
1162 $properties["Session Auth USER"] =
1163 new _define_optional('AUTH_SESS_USER', 'userid', "
1164 If USER_AUTH_ORDER contains Session:
1166 Name of the session variable which holds the already authenticated username.
1167 Sample: 'userid', 'user[username]', 'user->username'");
1169 $properties["Session Auth LEVEL"] =
1170 new numeric_define('AUTH_SESS_LEVEL', '2', "
1171 Which level will the user be? 1 = Bogo or 2 = Pass");
1173 /////////////////////////////////////////////////////////////////////
1175 $properties["Part Four"] =
1176 new part('_partfour', $SEPARATOR."\n", "
1179 Page appearance and layout");
1181 $properties["Theme"] =
1182 new _define_selection_optional('THEME',
1183 array('default' => "default",
1184 'MacOSX' => "MacOSX",
1185 'smaller' => 'smaller',
1186 'Wordpress'=> 'Wordpress',
1187 'Portland' => "Portland",
1188 'Hawaiian' => "Hawaiian",
1189 'Sidebar' => "Sidebar",
1191 'wikilens' => 'wikilens (Ratings)',
1192 'SpaceWiki' => "SpaceWiki",
1193 'shamino_com' => 'shamino_com',
1194 'MonoBook' => 'MonoBook [experimental]',
1195 'blog' => 'blog [experimental]',
1199 Most of the page appearance is controlled by files in the theme
1202 There are a number of pre-defined themes shipped with PhpWiki.
1203 Or you may create your own (e.g. by copying and then modifying one of
1208 THEME = MonoBook (WikiPedia) [experimental. MSIE problems]
1209 THEME = blog (Kubrick) [experimental. Several links missing]
1212 $properties["Character Set"] =
1213 new _define_optional('CHARSET', 'iso-8859-1', "
1214 Select a valid charset name to be inserted into the xml/html pages,
1215 and to reference links to the stylesheets (css). For more info see:
1216 http://www.iana.org/assignments/character-sets. Note that PhpWiki
1217 has been extensively tested only with the latin1 (iso-8859-1)
1220 If you change the default from iso-8859-1 PhpWiki may not work
1221 properly and it will require code modifications. However, character
1222 sets similar to iso-8859-1 may work with little or no modification
1223 depending on your setup. The database must also support the same
1224 charset, and of course the same is true for the web browser. (Some
1225 work is in progress hopefully to allow more flexibility in this
1226 area in the future).");
1228 $properties["Language"] =
1229 new _define_selection_optional('DEFAULT_LANGUAGE',
1230 array('en' => "English",
1231 '' => "<empty> (user-specific)",
1232 'fr' => "Français",
1234 'nl' => "Nederlands",
1239 'zh' => "Chinese"), "
1240 Select your language/locale - default language is \"en\" for English.
1241 Other languages available:<pre>
1242 English \"en\" (English - HomePage)
1243 German \"de\" (Deutsch - StartSeite)
1244 French \"fr\" (Français - Accueil)
1245 Dutch \"nl\" (Nederlands - ThuisPagina)
1246 Spanish \"es\" (Español - PáginaPrincipal)
1247 Swedish \"sv\" (Svenska - Framsida)
1248 Italian \"it\" (Italiano - PaginaPrincipale)
1249 Japanese \"ja\" (Japanese - ¥Û¡¼¥à ¥Ú¡¼¥¸)
1250 Chinese \"zh\" (Chinese)
1252 If you set DEFAULT_LANGUAGE to the empty string, your systems default language
1253 (as determined by the applicable environment variables) will be
1256 $properties["Wiki Page Source"] =
1257 new _define_optional('WIKI_PGSRC', 'pgsrc', "
1258 WIKI_PGSRC -- specifies the source for the initial page contents of
1259 the Wiki. The setting of WIKI_PGSRC only has effect when the wiki is
1260 accessed for the first time (or after clearing the database.)
1261 WIKI_PGSRC can either name a directory or a zip file. In either case
1262 WIKI_PGSRC is scanned for files -- one file per page.
1264 // Default (old) behavior:
1265 define('WIKI_PGSRC', 'pgsrc');
1267 define('WIKI_PGSRC', 'wiki.zip');
1268 define('WIKI_PGSRC',
1269 '../Logs/Hamwiki/hamwiki-20010830.zip');
1273 $properties["Default Wiki Page Source"] =
1274 new _define('DEFAULT_WIKI_PGSRC', 'pgsrc', "
1275 DEFAULT_WIKI_PGSRC is only used when the language is *not* the
1276 default (English) and when reading from a directory: in that case
1277 some English pages are inserted into the wiki as well.
1278 DEFAULT_WIKI_PGSRC defines where the English pages reside.
1280 FIXME: is this really needed?
1283 $properties["Generic Pages"] =
1284 new array_variable('GenericPages', array('ReleaseNotes', 'SteveWainstead', 'TestPage'), "
1285 These are the pages which will get loaded from DEFAULT_WIKI_PGSRC.
1287 FIXME: is this really needed? Cannot we just copy these pages into
1288 the localized pgsrc?
1294 $properties["Part Five"] =
1295 new part('_partfive', $SEPARATOR."\n", "
1300 $properties["Allowed Protocols"] =
1301 new list_define('ALLOWED_PROTOCOLS', 'http|https|mailto|ftp|news|nntp|ssh|gopher', "
1302 Allowed protocols for links - be careful not to allow \"javascript:\"
1303 URL of these types will be automatically linked.
1304 within a named link [name|uri] one more protocol is defined: phpwiki");
1306 $properties["Inline Images"] =
1307 new list_define('INLINE_IMAGES', 'png|jpg|gif', "
1308 URLs ending with the following extension should be inlined as images");
1310 $properties["WikiName Regexp"] =
1311 new _define('WIKI_NAME_REGEXP', "(?<![[:alnum:]])(?:[[:upper:]][[:lower:]]+){2,}(?![[:alnum:]])", "
1312 Perl regexp for WikiNames (\"bumpy words\")
1313 (?<!..) & (?!...) used instead of '\b' because \b matches '_' as well");
1315 $properties["Subpage Separator"] =
1316 new _define_optional('SUBPAGE_SEPARATOR', '/', "
1317 One character which seperates pages from subpages. Defaults to '/', but '.' or ':' were also used.",
1318 "onchange=\"validate_ereg('Sorry, \'%s\' must be a single character. Currently only :, / or .', '^[/:.]$', 'SUBPAGE_SEPARATOR', this);\""
1321 $properties["InterWiki Map File"] =
1322 new _define('INTERWIKI_MAP_FILE', 'lib/interwiki.map', "
1323 InterWiki linking -- wiki-style links to other wikis on the web
1325 The map will be taken from a page name InterWikiMap.
1326 If that page is not found (or is not locked), or map
1327 data can not be found in it, then the file specified
1328 by INTERWIKI_MAP_FILE (if any) will be used.");
1330 $properties["WARN_NONPUBLIC_INTERWIKIMAP"] =
1331 new boolean_define('WARN_NONPUBLIC_INTERWIKIMAP',
1332 array('true' => "true",
1333 'false' => "false"), "
1334 Display a warning if the internal lib/interwiki.map is used, and
1335 not the public InterWikiMap page. This map is not readable from outside.");
1338 $properties["Keyword Link Regexp"] =
1339 new _define_optional('KEYWORDS', '\"Category* OR Topic*\"', "
1340 Search term used for automatic page classification by keyword extraction.
1342 Any links on a page to pages whose names match this search
1343 will be used keywords in the keywords html meta tag. This is an aid to
1344 classification by search engines. The value of the match is
1345 used as the keyword.
1347 The default behavior is to match Category* or Topic* links.");
1349 $properties["Author and Copyright Site Navigation Links"] =
1350 new _define_commented_optional('COPYRIGHTPAGE_TITLE', "GNU General Public License", "
1352 These will be inserted as <link rel> tags in the html header of
1353 every page, for search engines and for browsers like Mozilla which
1354 take advantage of link rel site navigation.
1356 If you have your own copyright and contact information pages change
1357 these as appropriate.");
1359 $properties["COPYRIGHTPAGE URL"] =
1360 new _define_commented_optional('COPYRIGHTPAGE_URL', "http://www.gnu.org/copyleft/gpl.html#SEC1", "
1362 Other useful alternatives to consider:
1364 COPYRIGHTPAGE_TITLE = \"GNU Free Documentation License\"
1365 COPYRIGHTPAGE_URL = \"http://www.gnu.org/copyleft/fdl.html\"
1366 COPYRIGHTPAGE_TITLE = \"Creative Commons License 2.0\"
1367 COPYRIGHTPAGE_URL = \"http://creativecommons.org/licenses/by/2.0/\"</pre>
1368 See http://creativecommons.org/learn/licenses/ for variations");
1370 $properties["AUTHORPAGE_TITLE"] =
1371 new _define_commented_optional('AUTHORPAGE_TITLE', "The PhpWiki Programming Team", "
1372 Default Author Names");
1373 $properties["AUTHORPAGE_URL"] =
1374 new _define_commented_optional('AUTHORPAGE_URL', "http://phpwiki.org/ThePhpWikiProgrammingTeam", "
1375 Default Author URL");
1377 new boolean_define_optional
1379 array('true' => "Enabled",
1380 'false' => "Disabled."), "
1381 Allow full markup in headers to be parsed by the CreateToc plugin.
1383 If false you may not use WikiWords or [] links or any other markup in
1384 headers in pages with the CreateToc plugin. But if false the parsing is
1385 faster and more stable.");
1389 $properties["Part Six"] =
1390 new part('_partsix', $SEPARATOR."\n", "
1392 Part Six (optional):
1393 URL options -- you can probably skip this section.
1395 For a pretty wiki (no index.php in the url) set a seperate DATA_PATH.");
1397 global $HTTP_SERVER_VARS;
1398 $properties["Server Name"] =
1399 new _define_commented_optional('SERVER_NAME', $HTTP_SERVER_VARS['SERVER_NAME'], "
1400 Canonical name and httpd port of the server on which this PhpWiki
1404 $properties["Server Port"] =
1405 new numeric_define_commented('SERVER_PORT', $HTTP_SERVER_VARS['SERVER_PORT'], "",
1406 "onchange=\"validate_ereg('Sorry, \'%s\' is no valid port number.', '^[0-9]+$', 'SERVER_PORT', this);\"");
1408 $properties["Script Name"] =
1409 new _define_commented_optional('SCRIPT_NAME', $scriptname, "
1410 Relative URL (from the server root) of the PhpWiki script.");
1412 $properties["Data Path"] =
1413 new _define_commented_optional('DATA_PATH', dirname($scriptname), "
1414 URL of the PhpWiki install directory. (You only need to set this
1415 if you've moved index.php out of the install directory.) This can
1416 be either a relative URL (from the directory where the top-level
1417 PhpWiki script is) or an absolute one.");
1420 $properties["PhpWiki Install Directory"] =
1421 new _define_commented_optional('PHPWIKI_DIR', dirname(__FILE__), "
1422 Path to the PhpWiki install directory. This is the local
1423 filesystem counterpart to DATA_PATH. (If you have to set
1424 DATA_PATH, your probably have to set this as well.) This can be
1425 either an absolute path, or a relative path interpreted from the
1426 directory where the top-level PhpWiki script (normally index.php)
1429 $properties["Use PATH_INFO"] =
1430 new boolean_define_commented_optional('USE_PATH_INFO',
1431 array('true' => 'use PATH_INFO',
1432 'false' => 'do not use PATH_INFO'), "
1433 PhpWiki will try to use short urls to pages, eg
1434 http://www.example.com/index.php/HomePage
1435 If you want to use urls like
1436 http://www.example.com/index.php?pagename=HomePage
1437 then define 'USE_PATH_INFO' as false by uncommenting the line below.
1438 NB: If you are using Apache >= 2.0.30, then you may need to to use
1439 the directive \"AcceptPathInfo On\" in your Apache configuration file
1440 (or in an appropriate <.htaccess> file) for the short urls to work:
1441 See http://httpd.apache.org/docs-2.0/mod/core.html#acceptpathinfo
1443 See also http://phpwiki.sourceforge.net/phpwiki/PrettyWiki for more ideas
1444 on prettifying your urls.
1446 Default: PhpWiki will try to divine whether use of PATH_INFO
1447 is supported in by your webserver/PHP configuration, and will
1448 use PATH_INFO if it thinks that is possible.");
1451 $properties["Virtual Path"] =
1452 new _define_commented_optional('VIRTUAL_PATH', '/SomeWiki', "
1453 VIRTUAL_PATH is the canonical URL path under which your your wiki
1454 appears. Normally this is the same as dirname(SCRIPT_NAME), however
1455 using, e.g. seperate starter scripts, apaches mod_actions (or mod_rewrite), you can make it
1456 something different.
1458 If you do this, you should set VIRTUAL_PATH here or in the starter scripts.
1460 E.g. your phpwiki might be installed at at /scripts/phpwiki/index.php,
1461 but you've made it accessible through eg. /wiki/HomePage.
1463 One way to do this is to create a directory named 'wiki' in your
1464 server root. The directory contains only one file: an .htaccess
1465 file which reads something like:
1467 Action x-phpwiki-page /scripts/phpwiki/index.php
1468 SetHandler x-phpwiki-page
1469 DirectoryIndex /scripts/phpwiki/index.php
1471 In that case you should set VIRTUAL_PATH to '/wiki'.
1473 (VIRTUAL_PATH is only used if USE_PATH_INFO is true.)
1478 $properties["Part Seven"] =
1479 new part('_partseven', $SEPARATOR."\n", "
1483 Miscellaneous settings
1486 $properties["Pagename of Recent Changes"] =
1487 new _define_optional('RECENT_CHANGES', 'RecentChanges', "
1488 Page name of RecentChanges page. Used for RSS Auto-discovery.");
1490 $properties["Disable HTTP Redirects"] =
1491 new boolean_define_commented_optional
1492 ('DISABLE_HTTP_REDIRECT',
1493 array('false' => 'Enable HTTP Redirects',
1494 'true' => 'Disable HTTP Redirects'),
1496 (You probably don't need to touch this.)
1498 PhpWiki uses HTTP redirects for some of it's functionality.
1499 (e.g. after saving changes, PhpWiki redirects your browser to
1500 view the page you just saved.)
1502 Some web service providers (notably free European Lycos) don't seem to
1503 allow these redirects. (On Lycos the result in an \"Internal Server Error\"
1504 report.) In that case you can set DISABLE_HTTP_REDIRECT to true.
1505 (In which case, PhpWiki will revert to sneakier tricks to try to
1506 redirect the browser...)");
1508 $properties["EDITING_POLICY"] =
1509 new _define_optional('EDITING_POLICY', "EditingPolicy", "
1510 An interim page which gets displayed on every edit attempt, if it exists.");
1513 $end = "\n".$SEPARATOR."\n";
1515 // end of configuration options
1516 ///////////////////////////////
1517 // begin class definitions
1520 * A basic index.php configuration line in the form of a variable.
1522 * Produces a string in the form "$name = value;"
1524 * $WikiNameRegexp = "value";
1528 var $config_item_name;
1534 function _variable($config_item_name, $default_value, $description, $jscheck = '') {
1535 $this->config_item_name = $config_item_name;
1536 $this->description = $description;
1537 $this->default_value = $default_value;
1538 $this->jscheck = $jscheck;
1539 if (preg_match("/variable/i",get_class($this)))
1540 $this->prefix = "\$";
1541 elseif (preg_match("/ini_set/i",get_class($this)))
1542 $this->prefix = "ini_get: ";
1548 global $HTTP_POST_VARS;
1549 if (isset($HTTP_POST_VARS[$this->config_item_name]))
1550 return $HTTP_POST_VARS[$this->config_item_name];
1552 return $this->default_value;
1555 function _config_format($value) {
1556 $v = $this->get_config_item_name();
1557 // handle arrays: a|b --> a['b']
1558 if (strpos($v, '|')) {
1559 list($a, $b) = explode('|', $v);
1560 $v = sprintf("%s['%s']", $a, $b);
1562 if (preg_match("/[\"']/", $value))
1563 $value = '"' . $value . '"';
1564 return sprintf("%s = %s", $v, $value);
1567 function get_config_item_name() {
1568 return $this->config_item_name;
1571 function get_config_item_id() {
1572 return str_replace('|', '-', $this->config_item_name);
1575 function get_config_item_header() {
1576 if (strchr($this->config_item_name,'|')) {
1577 list($var,$param) = explode('|',$this->config_item_name);
1578 return "<b>" . $this->prefix . $var . "['" . $param . "']</b><br />";
1580 elseif ($this->config_item_name[0] != '_')
1581 return "<b>" . $this->prefix . $this->config_item_name . "</b><br />";
1586 function _get_description() {
1587 return $this->description;
1590 function _get_config_line($posted_value) {
1591 return "\n" . $this->_config_format($posted_value);
1594 function get_config($posted_value) {
1595 $d = stripHtml($this->_get_description());
1596 $d = str_replace("\n", "\n; ", $d) . $this->_get_config_line($posted_value) ."\n";
1600 function get_instructions($title) {
1602 $i = "<h3>" . $title . "</h3>\n " . nl2p($this->_get_description()) . "\n";
1603 return "<tr>\n<td width=\"$tdwidth\" class=\"instructions\">\n" . $i . "</td>\n";
1606 function get_html() {
1607 $size = strlen($this->default_value) > 45 ? 90 : 50;
1608 return $this->get_config_item_header() .
1609 "<input type=\"text\" size=\"$50\" name=\"" . $this->get_config_item_name() . "\" value=\"" . htmlspecialchars($this->default_value) . "\" " .
1610 $this->jscheck . " />" . "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: green\">Input accepted.</p>";
1614 class unchangeable_variable
1616 function _config_format($value) {
1619 // function get_html() { return false; }
1620 function get_html() {
1621 return $this->get_config_item_header() .
1622 "<em>Not editable.</em>" .
1623 "<pre>" . $this->default_value."</pre>";
1625 function _get_config_line($posted_value) {
1626 if ($this->description)
1628 return "${n}".$this->default_value;
1630 function get_instructions($title) {
1632 $i = "<h3>" . $title . "</h3>\n " . nl2p($this->_get_description()) . "\n";
1633 // $i .= "<em>Not editable.</em><br />\n<pre>" . $this->default_value."</pre>";
1634 return '<tr><td width="100%" class="unchangeable-variable-top" colspan="2">'."\n".$i."</td></tr>\n"
1635 . '<tr style="border-top: none;"><td class="unchangeable-variable-left" width="'.$tdwidth.'"> </td>';
1639 class unchangeable_define
1640 extends unchangeable_variable {
1641 function _config_format($value) {
1645 class unchangeable_ini_set
1646 extends unchangeable_variable {
1647 function _config_format($value) {
1652 class _variable_selection
1655 global $HTTP_POST_VARS;
1656 if (!empty($HTTP_POST_VARS[$this->config_item_name]))
1657 return $HTTP_POST_VARS[$this->config_item_name];
1659 list($option, $label) = each($this->default_value);
1663 function get_html() {
1664 $output = $this->get_config_item_header();
1665 $output .= '<select name="' . $this->get_config_item_name() . "\">\n";
1666 /* The first option is the default */
1667 while(list($option, $label) = each($this->default_value)) {
1668 $output .= " <option value=\"$option\">$label</option>\n";
1670 $output .= "</select>\n";
1678 function _config_format($value) {
1679 return sprintf("%s = %s", $this->get_config_item_name(), $value);
1681 function _get_config_line($posted_value) {
1682 if ($this->description)
1684 if ($posted_value == '')
1685 return "${n};" . $this->_config_format("");
1687 return "${n}" . $this->_config_format($posted_value);
1689 function get_html() {
1690 $size = strlen($this->default_value) > 45 ? 90 : 50;
1691 return $this->get_config_item_header()
1692 . "<input type=\"text\" size=\"$size\" name=\"" . htmlentities($this->get_config_item_name())
1693 . "\" value=\"" . htmlentities($this->default_value) . "\" {$this->jscheck} />"
1694 . "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: green\">Input accepted.</p>";
1698 class _define_commented
1700 function _get_config_line($posted_value) {
1701 if ($this->description)
1703 if ($posted_value == $this->default_value)
1704 return "${n};" . $this->_config_format($posted_value);
1705 elseif ($posted_value == '')
1706 return "${n};" . $this->_config_format("");
1708 return "${n}" . $this->_config_format($posted_value);
1712 class _define_commented_optional
1713 extends _define_commented {
1714 /*function _config_format($value) {
1715 $name = $this->get_config_item_name();
1716 return sprintf("if (!defined('%s')) define('%s', '%s');", $name, $name, $value);
1720 class _define_optional
1722 /*function _config_format($value) {
1723 $name = $this->get_config_item_name();
1724 return sprintf("if (!defined('%s')) define('%s', '%s');", $name, $name, $value);
1728 class _define_optional_notempty
1729 extends _define_optional {
1730 function get_html() {
1731 $s = $this->get_config_item_header()
1732 . "<input type=\"text\" size=\"50\" name=\"" . $this->get_config_item_name()
1733 . "\" value=\"" . $this->default_value . "\" {$this->jscheck} />";
1734 if (empty($this->default_value))
1735 return $s . "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: red\">Cannot be empty.</p>";
1737 return $s . "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: green\">Input accepted.</p>";
1741 class _variable_commented
1743 function _get_config_line($posted_value) {
1744 if ($this->description)
1746 if ($posted_value == $this->default_value)
1747 return "${n};" . $this->_config_format($posted_value);
1748 elseif ($posted_value == '')
1749 return "${n};" . $this->_config_format("");
1751 return "${n}" . $this->_config_format($posted_value);
1755 class numeric_define_commented
1757 function numeric_define_commented($config_item_name, $default_value, $description, $jscheck = '') {
1758 $this->_define($config_item_name, $default_value, $description, $jscheck);
1760 $this->jscheck = "onchange=\"validate_ereg('Sorry, \'%s\' is not an integer.', '^[-+]?[0-9]+$', '" . $this->get_config_item_name() . "', this);\"";
1762 function get_html() {
1763 return numeric_define::get_html();
1765 function _get_config_line($posted_value) {
1766 if ($this->description)
1768 if ($posted_value == $this->default_value)
1769 return "${n};" . $this->_config_format($posted_value);
1770 elseif ($posted_value == '')
1771 return "${n};" . $this->_config_format('0');
1773 return "${n}" . $this->_config_format($posted_value);
1777 class _define_selection
1778 extends _variable_selection {
1779 function _config_format($value) {
1780 return sprintf("%s = %s", $this->get_config_item_name(), $value);
1782 function _get_config_line($posted_value) {
1783 return _define::_get_config_line($posted_value);
1785 function get_html() {
1786 return _variable_selection::get_html();
1790 class _define_selection_optional
1791 extends _define_selection {
1792 /* function _config_format($value) {
1793 $name = $this->get_config_item_name();
1794 return sprintf("if (!defined('%s')) define('%s', '%s');", $name, $name, $value);
1798 class _variable_selection_optional
1799 extends _variable_selection {
1801 function _config_format($value) {
1802 $v = $this->get_config_item_name();
1803 // handle arrays: a|b --> a['b']
1804 if (strpos($v, '|')) {
1805 list($a, $b) = explode('|', $v);
1806 $v = sprintf("%s['%s']", $a, $b);
1808 return sprintf("if (!isset(\$%s)) { \$%s = \"%s\"; }", $v, $v, $value);
1812 class _define_password
1815 function _define_password($config_item_name, $default_value, $description, $jscheck = '') {
1816 $this->_define($config_item_name, $default_value, $description, $jscheck);
1818 $this->jscheck = "onchange=\"validate_ereg('Sorry, \'%s\' cannot be empty.', '^.+$', '" . $this->get_config_item_name() . "', this);\"";
1820 function _get_config_line($posted_value) {
1821 if ($this->description)
1823 if ($posted_value == '') {
1824 $p = "${n};" . $this->_config_format("");
1825 $p .= "\n; If you used the passencrypt.php utility to encode the password";
1826 $p .= "\n; then uncomment this line:";
1827 $p .= "\n;ENCRYPTED_PASSWD = true";
1830 if (function_exists('crypt')) {
1831 $salt_length = max(CRYPT_SALT_LENGTH,
1835 16 * CRYPT_BLOWFISH);
1836 // generate an encrypted password
1837 $crypt_pass = crypt($posted_value, rand_ascii($salt_length));
1838 $p = "${n}" . $this->_config_format($crypt_pass);
1839 return $p . "\nENCRYPTED_PASSWD = true";
1841 $p = "${n}" . $this->_config_format($posted_value);
1842 $p .= "\n; Encrypted passwords cannot be used:";
1843 $p .= "\n; 'function crypt()' not available in this version of php";
1844 $p .= "\nENCRYPTED_PASSWD = false";
1849 function get_html() {
1850 return _variable_password::get_html();
1854 class _define_password_optional
1855 extends _define_password {
1858 class _variable_password
1860 function _variable_password($config_item_name, $default_value, $description, $jscheck = '') {
1861 $this->_define($config_item_name, $default_value, $description, $jscheck);
1863 $this->jscheck = "onchange=\"validate_ereg('Sorry, \'%s\' cannot be empty.', '^.+$', '" . $this->get_config_item_name() . "', this);\"";
1865 function get_html() {
1866 global $HTTP_POST_VARS, $HTTP_GET_VARS;
1867 $s = $this->get_config_item_header();
1868 if (isset($HTTP_POST_VARS['create']) or isset($HTTP_GET_VARS['create'])) {
1869 $new_password = random_good_password();
1870 $this->default_value = $new_password;
1871 $s .= "Created password: <strong>$new_password</strong><br /> <br />";
1873 $s .= "<input type=\"password\" name=\"" . $this->get_config_item_name()
1874 . "\" value=\"" . $this->default_value
1875 . "\" {$this->jscheck} />"
1876 . " <input type=\"submit\" name=\"create\" value=\"Create Random Password\" />";
1877 if (empty($this->default_value))
1878 $s .= "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: red\">Cannot be empty.</p>";
1879 elseif (strlen($this->default_value) < 4)
1880 $s .= "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: red\">Must be longer than 4 chars.</p>";
1882 $s .= "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: green\">Input accepted.</p>";
1887 class numeric_define
1890 function numeric_define($config_item_name, $default_value, $description, $jscheck = '') {
1891 $this->_define($config_item_name, $default_value, $description, $jscheck);
1893 $this->jscheck = "onchange=\"validate_ereg('Sorry, \'%s\' is not an integer.', '^[-+]?[0-9]+$', '" . $this->get_config_item_name() . "', this);\"";
1895 function _config_format($value) {
1896 //return sprintf("define('%s', %s);", $this->get_config_item_name(), $value);
1897 return sprintf("%s = %s", $this->get_config_item_name(), $value);
1899 function _get_config_line($posted_value) {
1900 if ($this->description)
1902 if ($posted_value == '')
1903 return "${n};" . $this->_config_format('0');
1905 return "${n}" . $this->_config_format($posted_value);
1911 function _get_config_line($posted_value) {
1912 // split the phrase by any number of commas or space characters,
1913 // which include " ", \r, \t, \n and \f
1914 $list_values = preg_split("/[\s,]+/", $posted_value, -1, PREG_SPLIT_NO_EMPTY);
1915 $list_values = join("|", $list_values);
1916 return _variable::_get_config_line($list_values);
1918 function get_html() {
1919 $list_values = explode("|", $this->default_value);
1920 $rows = max(3, count($list_values) +1);
1921 $list_values = join("\n", $list_values);
1922 $ta = $this->get_config_item_header();
1923 $ta .= "<textarea cols=\"18\" rows=\"". $rows ."\" name=\"".$this->get_config_item_name()."\" {$this->jscheck}>";
1924 $ta .= $list_values . "</textarea>";
1925 $ta .= "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: green\">Input accepted.</p>";
1932 function _get_config_line($posted_value) {
1933 $list_values = preg_split("/[\s,]+/", $posted_value, -1, PREG_SPLIT_NO_EMPTY);
1934 $list_values = join("|", $list_values);
1935 return _variable::_get_config_line($list_values);
1937 function get_html() {
1938 $list_values = explode("|", $this->default_value);
1939 $rows = max(3, count($list_values) +1);
1940 $list_values = join("\n", $list_values);
1941 $ta = $this->get_config_item_header();
1942 $ta .= "<textarea cols=\"18\" rows=\"". $rows ."\" name=\"".$this->get_config_item_name()."\" {$this->jscheck}>";
1943 $ta .= $list_values . "</textarea>";
1944 $ta .= "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: green\">Input accepted.</p>";
1949 class array_variable
1951 function _config_format($value) {
1952 return sprintf("%s = \"%s\"", $this->get_config_item_name(),
1953 is_array($value) ? join(':', $value) : $value);
1955 function _get_config_line($posted_value) {
1956 // split the phrase by any number of commas or space characters,
1957 // which include " ", \r, \t, \n and \f
1958 $list_values = preg_split("/[\s,]+/", $posted_value, -1, PREG_SPLIT_NO_EMPTY);
1959 if (!empty($list_values)) {
1960 $list_values = "'".join("', '", $list_values)."'";
1961 return "\n" . $this->_config_format($list_values);
1963 return "\n;" . $this->_config_format('');
1965 function get_html() {
1966 $list_values = join("\n", $this->default_value);
1967 $rows = max(3, count($this->default_value) +1);
1968 $ta = $this->get_config_item_header();
1969 $ta .= "<textarea cols=\"18\" rows=\"". $rows ."\" name=\"".$this->get_config_item_name()."\" {$this->jscheck}>";
1970 $ta .= $list_values . "</textarea>";
1971 $ta .= "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: green\">Input accepted.</p>";
1978 function _config_format($value) {
1979 return sprintf("%s = \"%s\"", $this->get_config_item_name(),
1980 is_array($value) ? join(' : ', $value) : $value);
1982 function _get_config_line($posted_value) {
1983 // split the phrase by any number of commas or space characters,
1984 // which include " ", \r, \t, \n and \f
1985 $list_values = preg_split("/[\s,:]+/", $posted_value, -1, PREG_SPLIT_NO_EMPTY);
1986 if (!empty($list_values)) {
1987 $list_values = "'".join("' : '", $list_values)."'";
1988 return "\n" . $this->_config_format($list_values);
1990 return "\n;" . $this->_config_format('');
1992 function get_html() {
1993 $list_values = join("\n", $this->default_value);
1994 $rows = max(3, count($this->default_value) +1);
1995 $ta = $this->get_config_item_header();
1996 $ta .= "<textarea cols=\"18\" rows=\"". $rows ."\" name=\"".$this->get_config_item_name()."\" {$this->jscheck}>";
1997 $ta .= $list_values . "</textarea>";
1998 $ta .= "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: green\">Input accepted.</p>";
2007 global $HTTP_POST_VARS;
2008 if ($v = $HTTP_POST_VARS[$this->config_item_name])
2011 return ini_get($this->get_config_item_name);
2014 function _config_format($value) {
2015 return sprintf("ini_set('%s', '%s');", $this->get_config_item_name(), $value);
2017 function _get_config_line($posted_value) {
2018 if ($posted_value && ! $posted_value == $this->default_value)
2019 return "\n" . $this->_config_format($posted_value);
2021 return "\n;" . $this->_config_format($this->default_value);
2026 class boolean_define
2028 function _get_config_line($posted_value) {
2029 if ($this->description)
2031 return "${n}" . $this->_config_format($posted_value);
2033 function _config_format($value) {
2034 if (strtolower(trim($value)) == 'false')
2036 return sprintf("%s = %s", $this->get_config_item_name(),
2037 (bool)$value ? 'true' : 'false');
2039 function get_html() {
2040 $output = $this->get_config_item_header();
2041 $output .= '<select name="' . $this->get_config_item_name() . "\" {$this->jscheck}>\n";
2042 /* The first option is the default */
2043 list($option, $label) = each($this->default_value);
2044 $output .= " <option value=\"$option\" selected='selected'>$label</option>\n";
2045 /* There can usually, only be two options, there can be
2046 * three options in the case of a boolean_define_commented_optional */
2047 while (list($option, $label) = each($this->default_value))
2048 $output .= " <option value=\"$option\">$label</option>\n";
2049 $output .= "</select>\n";
2054 class boolean_define_optional
2055 extends boolean_define {}
2057 class boolean_define_commented
2058 extends boolean_define {
2059 function _get_config_line($posted_value) {
2060 if ($this->description)
2062 list($default_value, $label) = each($this->default_value);
2063 if ($posted_value == $default_value)
2064 return "${n};" . $this->_config_format($posted_value);
2065 elseif ($posted_value == '')
2066 return "${n};" . $this->_config_format('false');
2068 return "${n}" . $this->_config_format($posted_value);
2072 class boolean_define_commented_optional
2073 extends boolean_define_commented {}
2077 function value () { return; }
2078 function get_config($posted_value) {
2079 $d = stripHtml($this->_get_description());
2081 return "\n".$SEPARATOR . str_replace("\n", "\n; ", $d) ."\n".$this->default_value;
2083 function get_instructions($title) {
2084 $group_name = preg_replace("/\W/","",$title);
2085 $i = "<tr class='header' id='$group_name'>\n<td class=\"part\" width=\"100%\" colspan=\"2\" bgcolor=\"#eeeeee\">\n";
2086 $i .= "<h2>" . $title . "</h2>\n " . nl2p($this->_get_description()) ."\n";
2087 $i .= "<p><a href=\"javascript:toggle_group('$group_name')\" id=\"{$group_name}_text\">Hide options.</a></p>";
2088 return $i ."</td>\n";
2090 function get_html() {
2095 // html utility functions
2096 function nl2p($text) {
2097 preg_match_all("@\s*(<pre>.*?</pre>|<dl>.*?</dl>|.*?(?=\n\n|<pre>|<dl>|$))@s",
2098 $text, $m, PREG_PATTERN_ORDER);
2101 foreach ($m[1] as $par) {
2102 if (!($par = trim($par)))
2104 if (!preg_match('/^<(pre|dl)>/', $par))
2105 $par = "<p>$par</p>";
2111 function stripHtml($text) {
2112 $d = str_replace("<pre>", "", $text);
2113 $d = str_replace("</pre>", "", $d);
2114 $d = str_replace("<dl>", "", $d);
2115 $d = str_replace("</dl>", "", $d);
2116 $d = str_replace("<dt>", "", $d);
2117 $d = str_replace("</dt>", "", $d);
2118 $d = str_replace("<dd>", "", $d);
2119 $d = str_replace("</dd>", "", $d);
2120 $d = str_replace("<p>", "", $d);
2121 $d = str_replace("</p>", "", $d);
2122 //restore html entities into characters
2123 // http://www.php.net/manual/en/function.htmlentities.php
2124 $trans = get_html_translation_table (HTML_ENTITIES);
2125 $trans = array_flip ($trans);
2126 $d = strtr($d, $trans);
2130 include_once(dirname(__FILE__)."/lib/stdlib.php");
2133 // Function to create better user passwords (much larger keyspace),
2134 // suitable for user passwords.
2135 // Sequence of random ASCII numbers, letters and some special chars.
2136 // Note: There exist other algorithms for easy-to-remember passwords.
2137 function random_good_password ($minlength = 5, $maxlength = 8) {
2139 // assume ASCII ordering (not valid on EBCDIC systems!)
2140 $valid_chars = "!#%&+-.0123456789=@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz";
2141 $start = ord($valid_chars);
2142 $end = ord(substr($valid_chars,-1));
2144 if (function_exists('mt_rand')) // mersenne twister
2145 $length = mt_rand($minlength, $maxlength);
2146 else // the usually bad glibc rand()
2147 $length = rand($minlength, $maxlength);
2148 while ($length > 0) {
2149 if (function_exists('mt_rand'))
2150 $newchar = mt_rand($start, $end);
2152 $newchar = rand($start, $end);
2153 if (! strrpos($valid_chars,$newchar) ) continue; // skip holes
2154 $newpass .= sprintf("%c", $newchar);
2161 function printArray($a) {
2162 echo "<hr />\n<pre>\n";
2164 echo "\n</pre>\n<hr />\n";
2167 // end of class definitions
2168 /////////////////////////////
2169 // begin auto generation code
2171 if (!function_exists('is_a')) {
2172 function is_a($object, $class) {
2173 $class = strtolower($class);
2174 return (get_class($object) == $class) or is_subclass_of($object, $class);
2179 if (!empty($HTTP_POST_VARS['action'])
2180 and $HTTP_POST_VARS['action'] == 'make_config') {
2182 $timestamp = date ('dS of F, Y H:i:s');
2185 ; This is a local configuration file for PhpWiki.
2186 ; It was automatically generated by the configurator script
2187 ; on the $timestamp.
2192 $posted = $GLOBALS['HTTP_POST_VARS'];
2194 if (defined('DEBUG'))
2195 printArray($GLOBALS['HTTP_POST_VARS']);
2197 foreach($properties as $option_name => $a) {
2198 $posted_value = $posted[$a->config_item_name];
2199 $config .= $properties[$option_name]->get_config($posted_value);
2204 // I think writing this config file is a big security hole.
2205 // If this is installed in such a way that it can write an index-user.php,
2206 // then anyone can create a working index-user.php with, e.g. any
2207 // admin user and pw of their choosing...
2209 // So I'm disabling it...
2211 if (defined('ENABLE_FILE_OUTPUT') and ENABLE_FILE_OUPUT) {
2212 // We first check if the config-file exists.
2213 if (file_exists($fs_config_file)) {
2214 // We make a backup copy of the file
2215 // $config_file = 'index-user.php';
2216 $new_filename = preg_replace('/\.ini$/', time() . '.ini', $fs_config_file);
2217 if (@copy($fs_config_file, $new_filename)) {
2218 $fp = @fopen($fs_config_file, 'w');
2221 $fp = @fopen($fs_config_file, 'w');
2229 fputs($fp, $config);
2231 echo "<p>The configuration was written to <code><b>$config_file</b></code>.</p>\n";
2232 if ($new_filename) {
2233 echo "<p>A backup was made to <code><b>$new_filename</b></code>.</p>\n";
2235 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";
2237 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";
2240 echo "<hr />\n<p>Here's the configuration file based on your answers:</p>\n";
2241 echo "<form method=\"get\" action=\"", $configurator, "\">\n";
2242 echo "<textarea id='config-output' readonly='readonly' style='width:100%;' rows='30' cols='100'>\n";
2243 echo htmlentities($config);
2244 echo "</textarea></form>\n";
2247 echo "<p>To make any corrections, <a href=\"configurator.php\">edit the settings again</a>.</p>\n";
2249 } else { // first time or create password
2250 $posted = $GLOBALS['HTTP_POST_VARS'];
2251 // No action has been specified - we make a form.
2254 <form action="',$configurator,'" method="post">
2255 <input type="hidden" name="action" value="make_config" />
2256 <table cellpadding="4" cellspacing="0">
2259 while(list($property, $obj) = each($properties)) {
2260 echo $obj->get_instructions($property);
2261 if ($h = $obj->get_html()) {
2262 if (defined('DEBUG') and DEBUG) $h = get_class($obj) . "<br />\n" . $h;
2263 echo "<td>".$h."</td>\n";
2270 <p><input type="submit" value="Save ',$config_file,'" /> <input type="reset" value="Clear" /></p>