4 * * validate input (fix javascript, add POST checks)
5 * * start this automatically the first time
7 * * eval index-user.php or index.php to get the actual settings.
8 * * ask to store it in index.php or index-user.php
10 * The file index-user.php will be generated which you can use as your index.php.
14 $config_file = 'index-user.php';
15 $fs_config_file = dirname(__FILE__) . (substr(PHP_OS,0,3) == 'WIN' ? '\\' : "/") . $config_file;
16 if (isset($HTTP_POST_VARS['create'])) header('Location: configurator.php?create=1#create');
17 printf("<?xml version=\"1.0\" encoding=\"%s\"?>\n", 'iso-8859-1');
19 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
20 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
21 <html xmlns="http://www.w3.org/1999/xhtml">
23 <!-- $Id: configurator.php,v 1.15 2003-03-07 20:51:49 dairiki Exp $ -->
24 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
25 <title>Configuration tool for PhpWiki 1.3.x</title>
26 <style type="text/css" media="screen">
28 /* TABLE { border: thin solid black } */
29 body { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 80%; }
30 pre { font-size: 120%; }
31 td { border: thin solid black }
33 tr.hidden { border: none; display: none; }
34 td.part { background-color: #eeaaaa; color: inherit; }
35 td.instructions { background-color: #ffffee; width: <?php echo $tdwidth ?>px; color: inherit; }
36 td.unchangeable-variable-top { border-bottom: none; background-color: #eeeeee; color:inherit; }
37 td.unchangeable-variable-left { border-top: none; background-color: #eeeeee; color:inherit; }
40 <script language="JavaScript" type="text/javascript">
42 function update(accepted, error, value, output) {
44 document.getElementById(output).innerHTML = "<font color=\"green\">Input accepted.</font>";
46 while ((index = error.indexOf("%s")) > -1) {
47 error = error.substring(0, index) + value + error.substring(index+2);
49 document.getElementById(output).innerHTML = "<font color=\"red\">" + error + "</font>";
53 function validate(error, value, output, field) {
54 update(field.value == value, error, field.value, output);
57 function validate_ereg(error, ereg, output, field) {
58 regex = new RegExp(ereg);
59 update(regex.test(field.value), error, field.value, output);
62 function validate_range(error, low, high, empty_ok, output, field) {
63 update((empty_ok == 1 && field.value == "") ||
64 (field.value >= low && field.value <= high),
65 error, field.value, output);
68 function toggle_group(id) {
69 var text = document.getElementById(id + "_text");
71 if (text.innerHTML == "Hide options.") {
73 text.innerHTML = "Show options.";
75 text.innerHTML = "Hide options.";
78 var rows = document.getElementsByTagName('tr');
80 for (i = 0; i < rows.length; i++) {
82 if (tr.className == 'header' && tr.id == id) {
87 for (; i < rows.length; i++) {
89 if (tr.className == 'header')
91 tr.className = do_hide ? 'hidden': 'nonhidden';
96 // Hide all groups. We do this via JavaScript to avoid
97 // hiding the groups if JavaScript is not supported...
98 var rows = document.getElementsByTagName('tr');
99 for (var i = 0; i < rows.length; i++) {
101 if (tr.className == 'header')
105 // Select text in textarea upon focus
106 var area = document.getElementById('config-output');
108 listener = { handleEvent: function (e) { area.select(); } };
109 area.addEventListener('focus', listener, false);
116 <body onload="do_init();">
118 <h1>Configuration tool for PhpWiki 1.3.x</h1>
121 //define('DEBUG', 1);
123 * The Configurator is a php script to aid in the configuration of PhpWiki.
124 * Parts of this file are based on PHPWeather's configurator.php file.
125 * http://sourceforge.net/projects/phpweather/
128 * TO CHANGE THE CONFIGURATION OF YOUR PHPWIKI, DO *NOT* MODIFY THIS FILE!
129 * more instructions go here
132 * * start this automatically the first time
134 * * eval index.php to get the actual settings.
135 * * ask to store it in index.php or settings.php
137 * The file settings.php will be generated which you can use as your index.php.
141 //////////////////////////////
142 // begin configuration options
146 * Notes for the description parameter of $property:
148 * - Descriptive text will be changed into comments (preceeded by //)
149 * for the final output to index.php.
151 * - Only a limited set of html is allowed: pre, dl dt dd; it will be
152 * stripped from the final output.
154 * - Line breaks and spacing will be preserved for the final output.
156 * - Double line breaks are automatically converted to paragraphs
157 * for the html version of the descriptive text.
159 * - Double-quotes and dollar signs in the descriptive text must be
160 * escaped: \" and \$. Instead of escaping double-quotes you can use
161 * single (') quotes for the enclosing quotes.
163 * - Special characters like < and > must use html entities,
164 * they will be converted back to characters for the final output.
167 $SEPARATOR = "///////////////////////////////////////////////////////////////////";
170 Copyright 1999, 2000, 2001, 2002 $ThePhpWikiProgrammingTeam = array(
171 "Steve Wainstead", "Clifford A. Adams", "Lawrence Akka",
172 "Scott R. Anderson", "Jon Åslund", "Neil Brown", "Jeff Dairiki",
173 "Stéphane Gourichon", "Jan Hidders", "Arno Hollosi", "John Jorgensen",
174 "Antti Kaihola", "Jeremie Kass", "Carsten Klapp", "Marco Milanesi",
175 "Grant Morgan", "Jan Nieuwenhuizen", "Aredridel Niothke",
176 "Pablo Roca Rozas", "Sandino Araico Sánchez", "Joel Uckelman",
177 "Reini Urban", "Tim Voght", "Jochen Kalmbach");
179 This file is part of PhpWiki.
181 PhpWiki is free software; you can redistribute it and/or modify
182 it under the terms of the GNU General Public License as published by
183 the Free Software Foundation; either version 2 of the License, or
184 (at your option) any later version.
186 PhpWiki is distributed in the hope that it will be useful,
187 but WITHOUT ANY WARRANTY; without even the implied warranty of
188 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
189 GNU General Public License for more details.
191 You should have received a copy of the GNU General Public License
192 along with PhpWiki; if not, write to the Free Software
193 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
199 This is the starting file for PhpWiki. All this file does is set
200 configuration options, and at the end of the file it includes() the
201 file lib/main.php, where the real action begins.
203 If you include this file to override the default settings here,
204 you must also include lib/main.php.
206 This file is divided into seven parts: Parts Zero, One, Two, Three,
207 Four, Five and Six. Each one has different configuration settings you can
208 change; in all cases the default should work on your system,
209 however, we recommend you tailor things to your particular setting.
214 $properties["Part Zero"] =
215 new part('_part0', false, "
216 Part Zero: If PHP needs help in finding where you installed the
217 rest of the PhpWiki code, you can set the include_path here.");
219 if (substr(PHP_OS,0,3) == 'WIN') {
220 $include_path = ini_get('include_path') . ';' . dirname(__FILE__);
221 if (strchr(ini_get('include_path'),'/'))
222 $include_path = strtr($include_path,'\\','/');
224 $include_path = ini_get('include_path') . ':' . dirname(__FILE__);
227 $properties["PHP include_path"] =
228 new _ini_set('include_path', $include_path, "
229 NOTE: phpwiki uses the PEAR library of php code for SQL database
230 access. Your PHP is probably already configured to set
231 include_path so that PHP can find the pear code. If not (or if you
232 change include_path here) make sure you include the path to the
233 PEAR code in include_path. (To find the PEAR code on your system,
234 search for a file named 'PEAR.php'. Some common locations are:
242 The above examples are already included by PhpWiki. You shouldn't
243 have to change this unless you see a WikiFatalError:
245 lib/FileFinder.php:82: Fatal[256]:
246 DB.php: file not found
248 Define the include path for this wiki: pear plus the phpwiki path
250 \$include_path = '.:/Apache/php/pear:/prog/php/phpwiki';
252 Windows needs ';' as path delimiter. cygwin, mac and unix ':'
254 if (substr(PHP_OS,0,3) == 'WIN') {
255 \$include_path = implode(';',explode(':',\$include_path));
256 } elseif (substr(PHP_OS,0,6) == 'CYGWIN') {
257 \$include_path = '.:/usr/local/lib/php/pear'.
258 ':/usr/src/php/phpwiki';
263 $properties["Part Null"] =
264 new part('_partnullheader', "", "
265 Part Null: Don't touch this!");
269 $properties["Part Null Settings"] =
270 new unchangeable_variable('_partnullsettings', "
271 define ('PHPWIKI_VERSION', '1.3.5pre');
272 require \"lib/prepend.php\";
273 rcs_id('\$Id: configurator.php,v 1.15 2003-03-07 20:51:49 dairiki Exp $');", "");
276 $properties["Part One"] =
277 new part('_partone', $SEPARATOR."\n", "
280 Authentication and security settings. See Part Three for more.
285 $properties["Wiki Name"] =
286 new _define_optional('WIKI_NAME', 'PhpWiki', "
287 The name of your wiki.
288 This is used to generate a keywords meta tag in the HTML templates,
289 in bookmark titles for any bookmarks made to pages in your wiki,
290 and during RSS generation for the title of the RSS channel.");
293 $properties["Reverse DNS"] =
294 new boolean_define('ENABLE_REVERSE_DNS',
295 array('true' => "true. perform additional reverse dns lookups",
296 'false' => "false. just record the address as given by the httpd server"), "
297 If set, we will perform reverse dns lookups to try to convert the
298 users IP number to a host name, even if the http server didn't do it for us.");
300 $properties["Admin Username"] =
301 new _define_optional_notempty('ADMIN_USER', "", "
302 <a name=\"create\">You must set this! Username and password of the administrator.</a>",
303 "onchange=\"validate_ereg('Sorry, ADMIN_USER cannot be empty.', '^.+$', 'ADMIN_USER', this);\"");
305 $properties["Admin Password"] =
306 new _define_password_optional('ADMIN_PASSWD', "", "
307 For heaven's sake pick a good password.
308 You can also use our <a target=\"_new\" href=\"passencrypt.php\">passwordencrypter</a> to encrypt an existing password or
309 the \"Create Password\" button to create a good password.",
310 "onchange=\"validate_ereg('Sorry, ADMIN_PASSWD must be at least 4 chars long.', '^....+$', 'ADMIN_PASSWD', this);\"");
312 $properties["Encrypted Password"] =
313 new boolean_define_optional('ENCRYPTED_PASSWD',
314 array('true' => "true. ADMIN_PASSWD is encrypted",
315 'false' => "false. ADMIN_PASSWD is plaintext. Not recommended!"), "
316 If you used the passencrypt.php utility to encode the password or use an existing unix-crypt password,
317 then set this to true. Recommended!");
319 $properties["ZIPdump Authentication"] =
320 new boolean_define_optional('ZIPDUMP_AUTH',
321 array('false' => "false. Everyone may download zip dumps",
322 'true' => "true. Only admin may download zip dumps"), "
323 If true, only the admin user can make zip dumps, else zip dumps
324 require no authentication.");
326 $properties["Enable Plugin RawHtml"] =
327 new boolean_define_optional('ENABLE_RAW_HTML',
328 array('false' => "Disabled. Recommended on public sites.",
329 'true' => "Enabled"), "
330 Allow < ?plugin RawHtml ...>. Don't do this on a publicly accessable wiki for now.");
332 $properties["Strict Mailable Pagedumps"] =
333 new boolean_define('STRICT_MAILABLE_PAGEDUMPS',
334 array('false' => "binary",
335 'true' => "quoted-printable"), "
336 If you define this to true, (MIME-type) page-dumps (either zip dumps,
337 or \"dumps to directory\" will be encoded using the quoted-printable
338 encoding. If you're actually thinking of mailing the raw page dumps,
339 then this might be useful, since (among other things,) it ensures
340 that all lines in the message body are under 80 characters in length.
342 Also, setting this will cause a few additional mail headers
343 to be generated, so that the resulting dumps are valid
344 RFC 2822 e-mail messages.
346 Probably, you can just leave this set to false, in which case you get
347 raw ('binary' content-encoding) page dumps.");
351 $properties["HTML Dump Filename Suffix"] =
352 new _variable('HTML_DUMP_SUFFIX', ".html", "
353 Here you can change the filename suffix used for XHTML page dumps.
354 If you don't want any suffix just comment this out.");
358 $properties["Maximum Upload Size"] =
359 new numeric_define('MAX_UPLOAD_SIZE', "16 * 1024 * 1024", "
360 The maximum file upload size.");
364 $properties["Minor Edit Timeout"] =
365 new numeric_define('MINOR_EDIT_TIMEOUT', "7 * 24 * 3600", "
366 If the last edit is older than MINOR_EDIT_TIMEOUT seconds, the
367 default state for the \"minor edit\" checkbox on the edit page form
372 $properties["Disabled Actions"] =
373 new array_variable('DisabledActions', array(), "
374 Actions listed in this array will not be allowed. Actions are:
375 browse, create, diff, dumphtml, dumpserial, edit, loadfile, lock, remove,
376 unlock, upload, viewsource, zip, ziphtml");
378 $properties["Access Log"] =
379 new _define_commented('ACCESS_LOG', "/var/logs/wiki_access.log", "
380 PhpWiki can generate an access_log (in \"NCSA combined log\" format)
381 for you. If you want one, define this to the name of the log file,
382 such as /tmp/wiki_access_log.");
384 $properties["Compress Output"] =
385 new boolean_define_commented_optional
387 array('' => 'Compress when PhpWiki thinks approriate.',
388 'false' => 'Never compress output.',
389 'true' => 'Always try to compress output.'),
391 By default PhpWiki will try to have PHP compress it's output
392 before sending it to the browser (if you have a recent enough
393 version of PHP and the browser supports it.
395 Define COMPRESS_OUTPUT to false to prevent output compression.
397 Define COMPRESS_OUTPUT to true to force output compression,
398 even if we think your version of PHP does this in a buggy
401 Leave it undefined to leave the choice up to PhpWiki.");
403 $properties["HTTP Cache Control"] =
404 new _define_selection_optional
406 array('LOOSE' => 'LOOSE',
407 'STRICT' => 'STRICT',
409 'ALLOW_STALE' => 'ALLOW_STALE'),
413 This controls how PhpWiki sets the HTTP cache control
414 headers (Expires: and Cache-Control:)
420 <dd>This is roughly the old (pre 1.3.4) behavior. PhpWiki will
421 instruct proxies and browsers never to cache PhpWiki output.</dd>
424 <dd>Cached pages will be invalidated whenever the database global
425 timestamp changes. This should behave just like NONE (modulo
426 bugs in PhpWiki and your proxies and browsers), except that
427 things will be slightly more efficient.</dd>
430 <dd>Cached pages will be invalidated whenever they are edited,
431 or, if the pages include plugins, when the plugin output could
432 concievably have changed.
434 <p>Behavior should be much like STRICT, except that sometimes
435 wikilinks will show up as undefined (with the question mark)
436 when in fact they refer to (recently) created pages.
437 (Hitting your browsers reload or perhaps shift-reload button
438 should fix the problem.)</p></dd>
441 <dd>Proxies and browsers will be allowed to used stale pages.
442 (The timeout for stale pages is controlled by CACHE_CONTROL_MAX_AGE.)
444 <p>This setting will result in quirky behavior. When you edit a
445 page your changes may not show up until you shift-reload the
448 <p>This setting is generally not advisable, however it may be useful
449 in certain cases (e.g. if your wiki gets lots of page views,
450 and few edits by knowledgable people who won't freak over the quirks.)</p>
453 The default is currently LOOSE.");
455 $properties["HTTP Cache Control Max Age"] =
456 new numeric_define('CACHE_CONTROL_MAX_AGE', 600,
458 Maximum page staleness, in seconds.");
460 $properties["Markup Caching"] =
461 new boolean_define_commented_optional
462 ('WIKIDB_NOCACHE_MARKUP',
463 array('false' => 'Enable markup cache',
464 'true' => 'Disable markup cache'),
468 PhpWiki normally caches a preparsed version (i.e. mostly
469 converted to HTML) of the most recent version of each page.
470 (Parsing the wiki-markup takes a fair amount of CPU.)
472 Define WIKIDB_NOCACHE_MARKUP to true to disable the
473 caching of marked-up page content.
475 Note that you can also disable markup caching on a per-page
476 temporary basis by addinging a query arg of '?nocache=1'
477 to the URL to the page. (Use '?nocache=purge' to completely
478 discard the cached version of the page.)
480 You can also purge the cached markup globally by using the
481 \"Purge Markup Cache\" button on the PhpWikiAdministration page.");
484 $properties["Path for PHP Session Support"] =
485 new _ini_set('session.save_path', '/tmp', "
486 The login code now uses PHP's session support. Usually, the default
487 configuration of PHP is to store the session state information in
488 /tmp. That probably will work fine, but fails e.g. on clustered
489 servers where each server has their own distinct /tmp (this is the
490 case on SourceForge's project web server.) You can specify an
491 alternate directory in which to store state information like so
492 (whatever user your httpd runs as must have read/write permission
493 in this directory):");
497 $properties["Disable PHP Transparent Session ID"] =
498 new unchangeable_ini_set('session.use_trans_sid', "@ini_set('session.use_trans_sid', 0);", "
499 If your php was compiled with --enable-trans-sid it tries to
500 add a PHPSESSID query argument to all URL strings when cookie
501 support isn't detected in the client browser. For reasons
502 which aren't entirely clear (PHP bug) this screws up the URLs
503 generated by PhpWiki. Therefore, transparent session ids
504 should be disabled. This next line does that.
506 (At the present time, you will not be able to log-in to PhpWiki,
507 or set any user preferences, unless your browser supports cookies.)");
511 ///////// database selection
514 $properties["Part Two"] =
515 new part('_parttwo', $SEPARATOR."\n", "
522 $properties["Database Type"] =
523 new _variable_selection("DBParams|dbtype",
524 array('dba' => "dba DBM",
526 'ADODB' => "SQL ADODB",
527 'cvs' => "CVS File handler"), "
528 Select the database backend type:
529 Choose ADODB or SQL to use an SQL database with ADODB or PEAR.
530 Choose dba to use one of the standard UNIX dbm libraries.
531 CVS is not yet tested nor supported.
532 Recommended is SQL PEAR.");
534 $properties["Filename / Table name Prefix"] =
535 new _variable_commented("DBParams|prefix", "phpwiki_", "
536 Used by all DB types:
538 Prefix for filenames or table names
540 Currently you MUST EDIT THE SQL file too (in the schemas/
541 directory because we aren't doing on the fly sql generation
542 during the installation.");
545 $properties["SQL dsn Setup"] =
546 new unchangeable_variable('_sqldsnstuff', "", "
547 For SQL based backends, specify the database as a DSN
548 The most general form of a DSN looks like:
550 phptype(dbsyntax)://username:password@protocol+hostspec/database
552 For a MySQL database, the following should work:
554 mysql://user:password@host/databasename
556 To connect over a unix socket, use something like
558 mysql://user:password@unix(/path/to/socket)/databasename
560 <pre>'dsn' => 'mysql://guest@:/var/lib/mysql/mysql.sock/test',
561 'dsn' => 'mysql://guest@localhost/test',
562 'dsn' => 'pgsql://localhost/test',</pre>");
564 // Choose ADODB or SQL to use an SQL database with ADODB or PEAR.
565 // Choose dba to use one of the standard UNIX dbm libraries.
567 $properties["SQL Type"] =
568 new _variable_selection('_dsn_sqltype',
569 array('mysql' => "MySQL",
570 'pgsql' => "PostgreSQL"), "
575 $properties["SQL User"] =
576 new _variable('_dsn_sqluser', "wikiuser", "
581 $properties["SQL Password"] =
582 new _variable('_dsn_sqlpass', "", "
587 $properties["SQL Database Host"] =
588 new _variable('_dsn_sqlhostorsock', "localhost", "
589 SQL Database Hostname:
591 To connect over a local named socket, use something like
593 unix(/var/lib/mysql/mysql.sock)
599 $properties["SQL Database Name"] =
600 new _variable('_dsn_sqldbname', "phpwiki", "
601 SQL Database Name:");
603 list($dsn_sqltype,) = $properties["SQL Type"]->value();
604 $dsn_sqluser = $properties["SQL User"]->value();
605 $dsn_sqlpass = $properties["SQL Password"]->value();
606 $dsn_sqlhostorsock = $properties["SQL Database Host"]->value();
607 $dsn_sqldbname = $properties["SQL Database Name"]->value();
609 $properties["SQL dsn"] =
610 new unchangeable_variable("DBParams['dsn']",
611 "\$DBParams['dsn'] = \"\$_dsn_sqltype://{$dsn_sqluser}:{$dsn_sqlpass}@{$dsn_sqlhostorsock}/{$dsn_sqldbname}\";", "");
613 $properties["dba directory"] =
614 new _variable("DBParams|directory", "/tmp", "
618 $properties["dba handler"] =
619 new _variable_selection('DBParams|dba_handler',
620 array('gdbm' => "Gdbm - GNU database manager",
621 'dbm' => "DBM - Redhat default. On sf.net there's dbm and gdbm",
622 'db2' => "DB2 - Sleepycat Software's DB2",
623 'db3' => "DB3 - Sleepycat Software's DB3. Fine on Windows but not on every Linux"), "
624 Use 'gdbm', 'dbm', 'db2' or 'db3' depending on your DBA handler methods supported:");
626 $properties["dba timeout"] =
627 new _variable("DBParams|timeout", "20", "
628 Recommended values are 20 or 5.");
636 $properties["Page Revisions"] =
637 new unchangeable_variable('_parttworevisions', "", "
639 The next section controls how many old revisions of each page are
640 kept in the database.
642 There are two basic classes of revisions: major and minor. Which
643 class a revision belongs in is determined by whether the author
644 checked the \"this is a minor revision\" checkbox when they saved the
647 There is, additionally, a third class of revisions: author
648 revisions. The most recent non-mergable revision from each distinct
649 author is and author revision.
651 The expiry parameters for each of those three classes of revisions
652 can be adjusted seperately. For each class there are five
653 parameters (usually, only two or three of the five are actually
654 set) which control how long those revisions are kept in the
657 <dt>max_keep:</dt> <dd>If set, this specifies an absolute maximum for the
658 number of archived revisions of that class. This is
659 meant to be used as a safety cap when a non-zero
660 min_age is specified. It should be set relatively high,
661 and it's purpose is to prevent malicious or accidental
662 database overflow due to someone causing an
663 unreasonable number of edits in a short period of time.</dd>
665 <dt>min_age:</dt> <dd>Revisions younger than this (based upon the supplanted
666 date) will be kept unless max_keep is exceeded. The age
667 should be specified in days. It should be a
668 non-negative, real number,</dd>
670 <dt>min_keep:</dt> <dd>At least this many revisions will be kept.</dd>
672 <dt>keep:</dt> <dd>No more than this many revisions will be kept.</dd>
674 <dt>max_age:</dt> <dd>No revision older than this age will be kept.</dd>
676 Supplanted date: Revisions are timestamped at the instant that they
677 cease being the current revision. Revision age is computed using
678 this timestamp, not the edit time of the page.
680 Merging: When a minor revision is deleted, if the preceding
681 revision is by the same author, the minor revision is merged with
682 the preceding revision before it is deleted. Essentially: this
683 replaces the content (and supplanted timestamp) of the previous
684 revision with the content after the merged minor edit, the rest of
685 the page metadata for the preceding version (summary, mtime, ...)
690 // For now the expiration parameters are statically inserted as
691 // an unchangeable property. You'll have to edit the resulting
692 // config file if you really want to change these from the default.
694 $properties["Expiration Parameters for Major Edits"] =
695 new unchangeable_variable('ExpireParams|major',
696 "\$ExpireParams['major'] = array('max_age' => 32,
698 Keep up to 8 major edits, but keep them no longer than a month.");
700 $properties["Expiration Parameters for Minor Edits"] =
701 new unchangeable_variable('ExpireParams|minor',
702 "\$ExpireParams['minor'] = array('max_age' => 7,
704 Keep up to 4 minor edits, but keep them no longer than a week.");
708 $properties["Expiration Parameters by Author"] =
709 new unchangeable_variable('ExpireParams|author',
710 "\$ExpireParams['author'] = array('max_age' => 365,
713 'max_keep' => 20);", "
714 Keep the latest contributions of the last 8 authors up to a year.
715 Additionally, (in the case of a particularly active page) try to
716 keep the latest contributions of all authors in the last week (even
717 if there are more than eight of them,) but in no case keep more
718 than twenty unique author revisions.");
720 /////////////////////////////////////////////////////////////////////
722 $properties["Part Three"] =
723 new part('_partthree', $SEPARATOR."\n", "
725 Part Three: (optional)
729 $properties["User Authentication"] =
730 new boolean_define_optional('ALLOW_USER_LOGIN',
731 array('true' => "true. Check any defined passwords. (Default)",
732 'false' => "false. Don't check passwords. Legacy < 1.3.4"), "
733 If ALLOW_USER_LOGIN is true, any defined internal and external
734 authentication method is tried.
735 If not, we don't care about passwords, but check the next two constants.");
737 $properties["HTTP Authentication"] =
738 new boolean_define_optional('ALLOW_HTTP_AUTH_LOGIN',
739 array('false' => "false. Ignore HTTP Authentication. (Default)",
740 'true' => "true. Allow .htpasswd users login automatically."), "
741 The wiki can be optionally be protected by HTTP Auth. Use the username and password
742 from there, and if this fails, try the other methods also.");
744 $properties["Strict Login"] =
745 new boolean_define_optional('ALLOW_BOGO_LOGIN',
746 array('true' => "Users may Sign In with any WikiWord",
747 'false' => "Only admin may Sign In"), "
748 If ALLOW_BOGO_LOGIN is true, users are allowed to login (with
749 any/no password) using any userid which: 1) is not the ADMIN_USER,
750 2) is a valid WikiWord (matches \$WikiNameRegexp.)
751 If true, users may be created by themselves. Otherwise we need seperate auth.
752 This might be renamed to ALLOW_SELF_REGISTRATION");
754 $properties["Require Sign In Before Editing"] =
755 new boolean_define_optional('REQUIRE_SIGNIN_BEFORE_EDIT',
756 array('false' => "Do not require Sign In",
757 'true' => "Require Sign In"), "
758 If set, then if an anonymous user attempts to edit a page he will
759 be required to sign in. (If ALLOW_BOGO_LOGIN is true, of course,
760 no password is required, but the user must still sign in under
761 some sort of BogoUserId.)");
763 if (function_exists('ldap_connect')) {
764 $properties["LDAP Authentication"] =
765 new boolean_define_optional('ALLOW_LDAP_LOGIN',
766 array('true' => "Allow LDAP Authentication",
767 'false' => "Ignore LDAP"), "
770 $properties["LDAP Host"] =
771 new _define_optional('LDAP_AUTH_HOST', "localhost", "");
772 $properties["LDAP Root Search"] =
773 new _define_optional('LDAP_AUTH_SEARCH', "ou=mycompany.com,o=My Company", "
774 Give the right LDAP root search information in the next statement.");
778 $properties["LDAP Authentication"] =
779 new unchangeable_define('ALLOW_LDAP_LOGIN', "
780 if (!defined('ALLOW_LDAP_LOGIN')) define('ALLOW_LDAP_LOGIN', true and function_exists('ldap_connect'));
781 if (!defined('LDAP_AUTH_HOST')) define('LDAP_AUTH_HOST', 'localhost');
782 // Give the right LDAP root search information in the next statement.
783 if (!defined('LDAP_AUTH_SEARCH')) define('LDAP_AUTH_SEARCH', 'ou=mycompany.com,o=My Company');
785 Ignored. No LDAP support in this php. configure --with-ldap");
788 if (function_exists('imap_open')) {
789 $properties["IMAP Authentication"] =
790 new boolean_define_optional('ALLOW_IMAP_LOGIN',
791 array('true' => "Allow IMAP Authentication",
792 'false' => "Ignore IMAP"), "
795 $properties["IMAP Host"] =
796 new _define_optional('IMAP_AUTH_HOST', 'localhost', '');
798 $properties["IMAP Authentication"] =
799 new unchangeable_define('ALLOW_IMAP_LOGIN',"
800 // IMAP auth: check userid/passwords from a imap server, defaults to localhost
801 if (!defined('ALLOW_IMAP_LOGIN')) define('ALLOW_IMAP_LOGIN', true and function_exists('imap_open'));
802 if (!defined('IMAP_AUTH_HOST')) define('IMAP_AUTH_HOST', 'localhost');
803 ", "Ignored. No IMAP support in this php. configure --with-imap");
807 /////////////////////////////////////////////////////////////////////
809 $properties["Part Four"] =
810 new part('_partfour', $SEPARATOR."\n", "
813 Page appearance and layout
818 $properties["Theme"] =
819 new _define_selection_optional('THEME',
820 array('default' => "default",
821 'Hawaiian' => "Hawaiian",
822 'MacOSX' => "MacOSX",
823 'Portland' => "Portland",
824 'Sidebar' => "Sidebar",
825 'SpaceWiki' => "SpaceWiki"), "
828 Most of the page appearance is controlled by files in the theme
831 There are a number of pre-defined themes shipped with PhpWiki.
832 Or you may create your own (e.g. by copying and then modifying one of
837 define('THEME', 'default');
838 define('THEME', 'Hawaiian');
839 define('THEME', 'MacOSX');
840 define('THEME', 'Portland');
841 define('THEME', 'Sidebar');
842 define('THEME', 'SpaceWiki');</pre>");
846 $properties["Character Set"] =
847 new _define_optional('CHARSET', 'iso-8859-1', "
848 Select a valid charset name to be inserted into the xml/html pages,
849 and to reference links to the stylesheets (css). For more info see:
850 http://www.iana.org/assignments/character-sets. Note that PhpWiki
851 has been extensively tested only with the latin1 (iso-8859-1)
854 If you change the default from iso-8859-1 PhpWiki may not work
855 properly and it will require code modifications. However, character
856 sets similar to iso-8859-1 may work with little or no modification
857 depending on your setup. The database must also support the same
858 charset, and of course the same is true for the web browser. (Some
859 work is in progress hopefully to allow more flexibility in this
860 area in the future).");
864 $properties["Language"] =
865 new _variable_selection_optional('LANG',
866 array('en' => "English",
867 'nl' => "Nederlands",
874 Select your language/locale - default language is \"en\" for English.
875 Other languages available:<pre>
876 English \"en\" (English - HomePage)
877 Dutch \"nl\" (Nederlands - ThuisPagina)
878 Spanish \"es\" (Español - PáginaPrincipal)
879 French \"fr\" (Français - Accueil)
880 German \"de\" (Deutsch - StartSeite)
881 Swedish \"sv\" (Svenska - Framsida)
882 Italian \"it\" (Italiano - PaginaPrincipale)
884 If you set \$LANG to the empty string, your systems default language
885 (as determined by the applicable environment variables) will be
888 $properties["Language Locales"] =
889 new unchangeable_variable('language_locales',
890 "\$language_locales = array('en' => 'C',
898 if (empty(\$LC_ALL)) {
899 if (empty(\$language_locales[\$LANG]))
902 \$LC_ALL = \$language_locales[\$LANG];
904 putenv(\"LC_TIME=\$LC_ALL\");
906 Setting the LANG environment variable (accomplished above) may or
907 may not be sufficient to cause PhpWiki to produce dates in your
908 native language. (It depends on the configuration of the operating
909 system on your http server.) The problem is that, e.g. 'de' is
910 often not a valid locale.
912 A standard locale name is typically of the form
913 language[_territory][.codeset][@modifier], where language is
914 an ISO 639 language code, territory is an ISO 3166 country code,
915 and codeset is a character set or encoding identifier like
918 You can tailor the locale used for time and date formatting by
919 setting the LC_TIME environment variable. You'll have to experiment
920 to find the correct setting.
921 gettext() fix: With setlocale() we must use the long form,
922 like 'de_DE','nl_NL', 'es_MX', 'es_AR', 'fr_FR'.
923 For Windows maybe even 'german'. You might fix this accordingly.");
925 $properties["Wiki Page Source"] =
926 new _define_optional('WIKI_PGSRC', 'pgsrc', "
927 WIKI_PGSRC -- specifies the source for the initial page contents of
928 the Wiki. The setting of WIKI_PGSRC only has effect when the wiki is
929 accessed for the first time (or after clearing the database.)
930 WIKI_PGSRC can either name a directory or a zip file. In either case
931 WIKI_PGSRC is scanned for files -- one file per page.
933 // Default (old) behavior:
934 define('WIKI_PGSRC', 'pgsrc');
936 define('WIKI_PGSRC', 'wiki.zip');
938 '../Logs/Hamwiki/hamwiki-20010830.zip');
943 $properties["Default Wiki Page Source"] =
944 new _define('DEFAULT_WIKI_PGSRC', 'pgsrc', "
945 DEFAULT_WIKI_PGSRC is only used when the language is *not* the
946 default (English) and when reading from a directory: in that case
947 some English pages are inserted into the wiki as well.
948 DEFAULT_WIKI_PGSRC defines where the English pages reside.
950 FIXME: is this really needed?
955 $properties["Generic Pages"] =
956 new array_variable('GenericPages', array('ReleaseNotes', 'SteveWainstead', 'TestPage'), "
957 These are the pages which will get loaded from DEFAULT_WIKI_PGSRC.
959 FIXME: is this really needed? Can't we just copy these pages into
966 $properties["Part Five"] =
967 new part('_partfive', $SEPARATOR."\n", "
975 $properties["Allowed Protocols"] =
976 new list_variable('AllowedProtocols', 'http|https|mailto|ftp|news|nntp|ssh|gopher', "
977 allowed protocols for links - be careful not to allow \"javascript:\"
978 URL of these types will be automatically linked.
979 within a named link [name|uri] one more protocol is defined: phpwiki");
983 $properties["Inline Images"] =
984 new list_variable('InlineImages', 'png|jpg|gif', "
985 URLs ending with the following extension should be inlined as images");
989 $properties["WikiName Regexp"] =
990 new _variable('WikiNameRegexp', "(?<![[:alnum:]])(?:[[:upper:]][[:lower:]]+){2,}(?![[:alnum:]])", "
991 Perl regexp for WikiNames (\"bumpy words\")
992 (?<!..) & (?!...) used instead of '\b' because \b matches '_' as well");
994 $properties["Subpage Separator"] =
995 new _define_optional('SUBPAGE_SEPARATOR', '/', "
996 One character which seperates pages from subpages. Defaults to '/', but '.' or ':' were also used.",
997 "onchange=\"validate_ereg('Sorry, \'%s\' must be a single character. Currently only :, / or .', '^[/:.]$', 'SUBPAGE_SEPARATOR', this);\""
1000 $properties["InterWiki Map File"] =
1001 new _define('INTERWIKI_MAP_FILE', 'lib/interwiki.map', "
1002 InterWiki linking -- wiki-style links to other wikis on the web
1004 The map will be taken from a page name InterWikiMap.
1005 If that page is not found (or is not locked), or map
1006 data can not be found in it, then the file specified
1007 by INTERWIKI_MAP_FILE (if any) will be used.");
1009 $properties["WARN_NONPUBLIC_INTERWIKIMAP"] =
1010 new boolean_define('WARN_NONPUBLIC_INTERWIKIMAP',
1011 array('true' => "true",
1012 'false' => "false"), "
1013 Display a warning if the internal lib/interwiki.map is used, and
1014 not the public InterWikiMap page. This map is not readable from outside.");
1016 $properties["Keyword Link Regexp"] =
1017 new _variable('KeywordLinkRegexp',
1018 '(?<=^Category|^Topic)[[:upper:]].*$',
1020 Regexp used for automatic keyword extraction.
1022 Any links on a page to pages whose names match this regexp will
1023 be used keywords in the keywords meta tag. (This is an aid to
1024 classification by search engines.) The value of the match is
1025 used as the keyword.
1027 The default behavior is to match Category* and Topic* links.");
1029 $properties["Part Six"] =
1030 new part('_partsix', $SEPARATOR."\n", "
1032 Part Six (optional):
1033 URL options -- you can probably skip this section.
1036 $properties["Server Name"] =
1037 new _define_commented_optional('SERVER_NAME', $HTTP_SERVER_VARS['SERVER_NAME'], "
1038 Canonical name and httpd port of the server on which this PhpWiki
1043 $properties["Server Port"] =
1044 new numeric_define_commented('SERVER_PORT', $HTTP_SERVER_VARS['SERVER_PORT'], "",
1045 "onchange=\"validate_ereg('Sorry, \'%s\' is no valid port number.', '^[0-9]+$', 'SERVER_PORT', this);\"");
1047 $scriptname = preg_replace('/configurator.php/','index.php',$HTTP_SERVER_VARS["SCRIPT_NAME"]);
1049 $properties["Script Name"] =
1050 new _define_commented_optional('SCRIPT_NAME', $scriptname, "
1051 Relative URL (from the server root) of the PhpWiki script.");
1053 $properties["Data Path"] =
1054 new _define_commented_optional('DATA_PATH', dirname($scriptname), "
1055 URL of the PhpWiki install directory. (You only need to set this
1056 if you've moved index.php out of the install directory.) This can
1057 be either a relative URL (from the directory where the top-level
1058 PhpWiki script is) or an absolute one.");
1062 $properties["PhpWiki Install Directory"] =
1063 new _define_commented_optional('PHPWIKI_DIR', dirname(__FILE__), "
1064 Path to the PhpWiki install directory. This is the local
1065 filesystem counterpart to DATA_PATH. (If you have to set
1066 DATA_PATH, your probably have to set this as well.) This can be
1067 either an absolute path, or a relative path interpreted from the
1068 directory where the top-level PhpWiki script (normally index.php)
1073 $properties["Use PATH_INFO"] =
1074 new boolean_define_commented_optional('USE_PATH_INFO',
1075 array('true' => 'use PATH_INFO',
1076 'false' => 'do not use PATH_INFO'), "
1077 Define to 'true' to use PATH_INFO to pass the pagenames.
1078 e.g. http://www.some.where/index.php/HomePage instead
1079 of http://www.some.where/index.php?pagename=HomePage
1080 FIXME: more docs (maybe in README). Default: true");
1084 $properties["Virtual Path"] =
1085 new _define_commented_optional('VIRTUAL_PATH', '/SomeWiki', "
1086 VIRTUAL_PATH is the canonical URL path under which your your wiki
1087 appears. Normally this is the same as dirname(SCRIPT_NAME), however
1088 using, e.g. apaches mod_actions (or mod_rewrite), you can make it
1089 something different.
1091 If you do this, you should set VIRTUAL_PATH here.
1093 E.g. your phpwiki might be installed at at /scripts/phpwiki/index.php,
1094 but you've made it accessible through eg. /wiki/HomePage.
1096 One way to do this is to create a directory named 'wiki' in your
1097 server root. The directory contains only one file: an .htaccess
1098 file which reads something like:
1100 Action x-phpwiki-page /scripts/phpwiki/index.php
1101 SetHandler x-phpwiki-page
1102 DirectoryIndex /scripts/phpwiki/index.php
1104 In that case you should set VIRTUAL_PATH to '/wiki'.
1106 (VIRTUAL_PATH is only used if USE_PATH_INFO is true.)
1110 $properties["Part Seven"] =
1111 new part('_partseven', $SEPARATOR."\n", "
1115 Miscellaneous settings
1118 $properties["Pagename of Recent Changes"] =
1119 new _define_optional('RECENT_CHANGES', 'RecentChanges', "
1120 Page name of RecentChanges page. Used for RSS Auto-discovery.");
1122 $properties["Disable HTTP Redirects"] =
1123 new boolean_define_commented_optional
1124 ('DISABLE_HTTP_REDIRECT',
1125 array('false' => 'Enable HTTP Redirects',
1126 'true' => 'Disable HTTP Redirects'),
1128 (You probably don't need to touch this.)
1130 PhpWiki uses HTTP redirects for some of it's functionality.
1131 (e.g. after saving changes, PhpWiki redirects your browser to
1132 view the page you just saved.)
1134 Some web service providers (notably free European Lycos) don't seem to
1135 allow these redirects. (On Lycos the result in an \"Internal Server Error\"
1136 report.) In that case you can set DISABLE_HTTP_REDIRECT to true.
1137 (In which case, PhpWiki will revert to sneakier tricks to try to
1138 redirect the browser...)");
1143 // Check if we were included by some other wiki version (getimg, en, ...)
1145 // If the server requested this index.php fire up the code by loading lib/main.php.
1146 // Parallel wiki scripts can now simply include /index.php for the
1147 // main configuration, extend or redefine some settings and
1148 // load lib/main.php by themselves.
1149 // This overcomes the index as config problem.
1152 // This doesn't work with php as CGI yet!
1153 if (defined('VIRTUAL_PATH') and defined('USE_PATH_INFO')) {
1154 if (\$HTTP_SERVER_VARS['SCRIPT_NAME'] == VIRTUAL_PATH) {
1155 include \"lib/main.php\";
1158 if (defined('SCRIPT_NAME') and
1159 (\$HTTP_SERVER_VARS['SCRIPT_NAME'] == SCRIPT_NAME)) {
1160 include \"lib/main.php\";
1161 } elseif (strstr(\$HTTP_SERVER_VARS['PHP_SELF'],'index.php')) {
1162 include \"lib/main.php\";
1166 // (c-file-style: \"gnu\")
1170 // c-basic-offset: 4
1171 // c-hanging-comment-ender-p: nil
1172 // indent-tabs-mode: nil
1179 // end of configuration options
1180 ///////////////////////////////
1181 // begin class definitions
1184 * A basic index.php configuration line in the form of a variable.
1186 * Produces a string in the form "$name = value;"
1188 * $WikiNameRegexp = "value";
1192 var $config_item_name;
1198 function _variable($config_item_name, $default_value, $description, $jscheck = '') {
1199 $this->config_item_name = $config_item_name;
1200 $this->description = $description;
1201 $this->default_value = $default_value;
1202 $this->jscheck = $jscheck;
1203 if (preg_match("/variable/i",get_class($this)))
1204 $this->prefix = "\$";
1205 elseif (preg_match("/ini_set/i",get_class($this)))
1206 $this->prefix = "ini_get: ";
1212 global $HTTP_POST_VARS;
1213 if (isset($HTTP_POST_VARS[$this->config_item_name]))
1214 return $HTTP_POST_VARS[$this->config_item_name];
1216 return $this->default_value;
1219 function _config_format($value) {
1220 $v = $this->get_config_item_name();
1221 // handle arrays: a|b --> a['b']
1222 if (strpos($v, '|')) {
1223 list($a, $b) = explode('|', $v);
1224 $v = sprintf("%s['%s']", $a, $b);
1226 return sprintf("\$%s = \"%s\";", $v, $value);
1229 function get_config_item_name() {
1230 return $this->config_item_name;
1233 function get_config_item_id() {
1234 return str_replace('|', '-', $this->config_item_name);
1237 function get_config_item_header() {
1238 if (strchr($this->config_item_name,'|')) {
1239 list($var,$param) = explode('|',$this->config_item_name);
1240 return "<b>" . $this->prefix . $var . "['" . $param . "']</b><br />";
1242 elseif ($this->config_item_name[0] != '_')
1243 return "<b>" . $this->prefix . $this->config_item_name . "</b><br />";
1248 function _get_description() {
1249 return $this->description;
1252 function _get_config_line($posted_value) {
1253 return "\n" . $this->_config_format($posted_value);
1256 function get_config($posted_value) {
1257 $d = stripHtml($this->_get_description());
1258 $d = str_replace("\n", "\n// ", $d) . $this->_get_config_line($posted_value) ."\n";
1262 function get_instructions($title) {
1264 $i = "<h3>" . $title . "</h3>\n " . nl2p($this->_get_description()) . "\n";
1265 return "<tr>\n<td width=\"$tdwidth\" class=\"instructions\">\n" . $i . "</td>\n";
1268 function get_html() {
1269 return $this->get_config_item_header() .
1270 "<input type=\"text\" size=\"50\" name=\"" . $this->get_config_item_name() . "\" value=\"" . htmlspecialchars($this->default_value) . "\" " .
1271 $this->jscheck . " />" . "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: green\">Input accepted.</p>";
1275 class unchangeable_variable
1277 function _config_format($value) {
1280 // function get_html() { return false; }
1281 function get_html() {
1282 return $this->get_config_item_header() .
1283 "<em>Not editable.</em>" .
1284 "<pre>" . $this->default_value."</pre>";
1286 function _get_config_line($posted_value) {
1287 if ($this->description)
1289 return "${n}".$this->default_value;
1291 function get_instructions($title) {
1293 $i = "<h3>" . $title . "</h3>\n " . nl2p($this->_get_description()) . "\n";
1294 // $i = $i ."<em>Not editable.</em><br />\n<pre>" . $this->default_value."</pre>";
1295 return "<tr><td width=\"100%\" class=\"unchangeable-variable-top\" colspan=\"2\">\n".$i ."</td></tr>\n".
1296 "<tr style=\"border-top: none;\"><td class=\"unchangeable-variable-left\" width=\"$tdwidth\" bgcolor=\"#eeeeee\"> </td>";
1300 class unchangeable_define
1301 extends unchangeable_variable {
1302 function _config_format($value) {
1306 class unchangeable_ini_set
1307 extends unchangeable_variable {
1308 function _config_format($value) {
1314 class _variable_selection
1317 global $HTTP_POST_VARS;
1318 if (!empty($HTTP_POST_VARS[$this->config_item_name]))
1319 return $HTTP_POST_VARS[$this->config_item_name];
1321 list($option, $label) = current($this->default_value);
1322 return $this->$option;
1325 function get_html() {
1326 $output = $this->get_config_item_header();
1327 $output .= '<select name="' . $this->get_config_item_name() . "\">\n";
1328 /* The first option is the default */
1329 while(list($option, $label) = each($this->default_value)) {
1330 $output .= " <option value=\"$option\">$label</option>\n";
1332 $output .= "</select>\n";
1340 function _config_format($value) {
1341 return sprintf("define('%s', '%s');", $this->get_config_item_name(), $value);
1343 function _get_config_line($posted_value) {
1344 if ($this->description)
1346 if ($posted_value == '')
1347 return "${n}//" . $this->_config_format("");
1349 return "${n}" . $this->_config_format($posted_value);
1351 function get_html() {
1352 return $this->get_config_item_header() .
1353 "<input type=\"text\" size=\"50\" name=\"" . $this->get_config_item_name() . "\" value=\"" . $this->default_value . "\" {$this->jscheck} />" .
1354 "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: green\">Input accepted.</p>";
1358 class _define_commented
1360 function _get_config_line($posted_value) {
1361 if ($this->description)
1363 if ($posted_value == $this->default_value)
1364 return "${n}//" . $this->_config_format($posted_value);
1365 else if ($posted_value == '')
1366 return "${n}//" . $this->_config_format("");
1368 return "${n}" . $this->_config_format($posted_value);
1372 class _define_commented_optional
1373 extends _define_commented {
1374 function _config_format($value) {
1375 $name = $this->get_config_item_name();
1376 return sprintf("if (!defined('%s')) define('%s', '%s');", $name, $name, $value);
1380 class _define_optional
1382 function _config_format($value) {
1383 $name = $this->get_config_item_name();
1384 return sprintf("if (!defined('%s')) define('%s', '%s');", $name, $name, $value);
1388 class _define_optional_notempty
1389 extends _define_optional {
1390 function get_html() {
1391 $s = $this->get_config_item_header() .
1392 "<input type=\"text\" size=\"50\" name=\"" . $this->get_config_item_name() . "\" value=\"" . $this->default_value . "\" {$this->jscheck} />";
1393 if (empty($this->default_value))
1394 return $s . "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: red\">Cannot be empty.</p>";
1396 return $s . "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: green\">Input accepted.</p>";
1400 class _variable_commented
1402 function _get_config_line($posted_value) {
1403 if ($this->description)
1405 if ($posted_value == $this->default_value)
1406 return "${n}//" . $this->_config_format($posted_value);
1407 else if ($posted_value == '')
1408 return "${n}//" . $this->_config_format("");
1410 return "${n}" . $this->_config_format($posted_value);
1414 class numeric_define_commented
1416 // var $jscheck = "onchange=\"validate_ereg('Sorry, \'%s\' is not an integer.', '^[-+]?[0-9]+$', '" . $this->get_config_item_name() . "', this);\"";
1418 function get_html() {
1419 return numeric_define::get_html();
1421 function _get_config_line($posted_value) {
1422 if ($this->description)
1424 if ($posted_value == $this->default_value)
1425 return "${n}//" . $this->_config_format($posted_value);
1426 else if ($posted_value == '')
1427 return "${n}//" . $this->_config_format('0');
1429 return "${n}" . $this->_config_format($posted_value);
1433 class _define_selection
1434 extends _variable_selection {
1435 function _config_format($value) {
1436 return sprintf("define('%s', '%s');", $this->get_config_item_name(), $value);
1438 function _get_config_line($posted_value) {
1439 return _define::_get_config_line($posted_value);
1441 function get_html() {
1442 return _variable_selection::get_html();
1446 class _define_selection_optional
1447 extends _define_selection {
1448 function _config_format($value) {
1449 $name = $this->get_config_item_name();
1450 return sprintf("if (!defined('%s')) define('%s', '%s');", $name, $name, $value);
1454 class _variable_selection_optional
1455 extends _variable_selection {
1456 function _config_format($value) {
1457 $v = $this->get_config_item_name();
1458 // handle arrays: a|b --> a['b']
1459 if (strpos($v, '|')) {
1460 list($a, $b) = explode('|', $v);
1461 $v = sprintf("%s['%s']", $a, $b);
1463 return sprintf("if (!isset(\$%s)) { \$%s = \"%s\"; }", $v, $v, $value);
1467 class _define_password
1469 // var $jscheck = "onchange=\"validate_ereg('Sorry, \'%s\' cannot be empty.', '^.+$', '" . $this->get_config_item_name() . "', this);\"";
1471 function _get_config_line($posted_value) {
1472 if ($this->description)
1474 if ($posted_value == '') {
1475 $p = "${n}//" . $this->_config_format("");
1476 $p = $p . "\n// If you used the passencrypt.php utility to encode the password";
1477 $p = $p . "\n// then uncomment this line:";
1478 $p = $p . "\n//if (!defined('ENCRYPTED_PASSWD')) define('ENCRYPTED_PASSWD', true);";
1481 if (function_exists('crypt')) {
1482 $salt_length = max(CRYPT_SALT_LENGTH,
1486 16 * CRYPT_BLOWFISH);
1487 // generate an encrypted password
1488 $crypt_pass = crypt($posted_value, rand_ascii($salt_length));
1489 $p = "${n}" . $this->_config_format($crypt_pass);
1490 return $p . "\ndefine('ENCRYPTED_PASSWD', true);";
1492 $p = "${n}" . $this->_config_format($posted_value);
1493 $p = $p . "\n// If you used the passencrypt.php utility to encode the password";
1494 $p = $p . "\n// then uncomment this line:";
1495 $p = $p . "\n//define('ENCRYPTED_PASSWD', false);";
1496 $p = $p . "\n// Encrypted passwords cannot be used:";
1497 $p = $p . "\n// 'function crypt()' not available in this version of php";
1502 function get_html() {
1503 return _variable_password::get_html();
1507 class _define_password_optional
1508 extends _define_password {
1509 function _config_format($value) {
1510 $name = $this->get_config_item_name();
1511 return sprintf("if (!defined('%s')) define('%s', '%s');", $name, $name, $value);
1516 class _variable_password
1518 // var $jscheck = "onchange=\"validate_ereg('Sorry, \'%s\' cannot be empty.', '^.+$', '" . $this->get_config_item_name() . "', this);\"";
1520 function get_html() {
1521 global $HTTP_POST_VARS, $HTTP_GET_VARS;
1522 $s = $this->get_config_item_header();
1523 $s .= "<input type=\"password\" name=\"" . $this->get_config_item_name() . "\" value=\"" . $this->default_value . "\" {$this->jscheck} />" .
1524 " <input type=\"submit\" name=\"create\" value=\"Create Password\" />";
1525 if (isset($HTTP_POST_VARS['create']) or isset($HTTP_GET_VARS['create'])) {
1526 $new_password = random_good_password();
1527 $this->default_value = $new_password;
1528 $s .= "<br /> <br />Created password: <strong>$new_password</strong>";
1530 if (empty($this->default_value))
1531 $s .= "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: red\">Cannot be empty.</p>";
1532 elseif (strlen($this->default_value) < 4)
1533 $s .= "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: red\">Must be longer than 4 chars.</p>";
1535 $s .= "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: green\">Input accepted.</p>";
1540 class numeric_define
1542 // var $jscheck = "onchange=\"validate_ereg('Sorry, \'%s\' is not an integer.', '^[-+]?[0-9]+$', '" . $this->get_config_item_name() . "', this);\"";
1544 function _config_format($value) {
1545 return sprintf("define('%s', %s);", $this->get_config_item_name(), $value);
1547 function _get_config_line($posted_value) {
1548 if ($this->description)
1550 if ($posted_value == '')
1551 return "${n}//" . $this->_config_format('0');
1553 return "${n}" . $this->_config_format($posted_value);
1559 function _get_config_line($posted_value) {
1560 // split the phrase by any number of commas or space characters,
1561 // which include " ", \r, \t, \n and \f
1562 $list_values = preg_split("/[\s,]+/", $posted_value, -1, PREG_SPLIT_NO_EMPTY);
1563 $list_values = join("|", $list_values);
1564 return _variable::_get_config_line($list_values);
1566 function get_html() {
1567 $list_values = explode("|", $this->default_value);
1568 $rows = max(3, count($list_values) +1);
1569 $list_values = join("\n", $list_values);
1570 $ta = $this->get_config_item_header();
1571 $ta .= "<textarea cols=\"18\" rows=\"". $rows ."\" name=\"".$this->get_config_item_name()."\" {$this->jscheck}>";
1572 $ta .= $list_values . "</textarea>";
1573 $ta .= "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: green\">Input accepted.</p>";
1578 class array_variable
1580 function _config_format($value) {
1581 return sprintf("\$%s = array(%s);", $this->get_config_item_name(), $value);
1583 function _get_config_line($posted_value) {
1584 // split the phrase by any number of commas or space characters,
1585 // which include " ", \r, \t, \n and \f
1586 $list_values = preg_split("/[\s,]+/", $posted_value, -1, PREG_SPLIT_NO_EMPTY);
1587 if (!empty($list_values)) {
1588 $list_values = "'".join("', '", $list_values)."'";
1589 return "\n" . $this->_config_format($list_values);
1591 return "\n//" . $this->_config_format('');
1593 function get_html() {
1594 $list_values = join("\n", $this->default_value);
1595 $rows = max(3, count($this->default_value) +1);
1596 $ta = $this->get_config_item_header();
1597 $ta .= "<textarea cols=\"18\" rows=\"". $rows ."\" name=\"".$this->get_config_item_name()."\" {$this->jscheck}>";
1598 $ta .= $list_values . "</textarea>";
1599 $ta .= "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: green\">Input accepted.</p>";
1608 global $HTTP_POST_VARS;
1609 if ($v = $HTTP_POST_VARS[$this->config_item_name])
1612 return ini_get($this->get_config_item_name);
1615 function _config_format($value) {
1616 return sprintf("ini_set('%s', '%s');", $this->get_config_item_name(), $value);
1618 function _get_config_line($posted_value) {
1619 if ($posted_value && ! $posted_value == $this->default_value)
1620 return "\n" . $this->_config_format($posted_value);
1622 return "\n//" . $this->_config_format($this->default_value);
1626 class boolean_define
1628 function _get_config_line($posted_value) {
1629 if ($this->description)
1631 return "${n}" . $this->_config_format($posted_value);
1633 function _config_format($value) {
1634 if (strtolower(trim($value)) == 'false')
1636 return sprintf("define('%s', %s);", $this->get_config_item_name(),
1637 (bool)$value ? 'true' : 'false');
1639 function get_html() {
1640 $output = $this->get_config_item_header();
1641 $output .= '<select name="' . $this->get_config_item_name() . "\" {$this->jscheck}>\n";
1642 /* The first option is the default */
1643 list($option, $label) = each($this->default_value);
1644 $output .= " <option value=\"$option\" selected='selected'>$label</option>\n";
1645 /* There can usually, only be two options, there can be
1646 * three options in the case of a boolean_define_commented_optional */
1647 while (list($option, $label) = each($this->default_value))
1648 $output .= " <option value=\"$option\">$label</option>\n";
1649 $output .= "</select>\n";
1654 class boolean_define_optional
1655 extends boolean_define {
1656 function _config_format($value) {
1657 $name = $this->get_config_item_name();
1658 return "if (!defined('$name')) " . boolean_define::_config_format($value);
1662 class boolean_define_commented
1663 extends boolean_define {
1664 function _get_config_line($posted_value) {
1665 if ($this->description)
1667 list($default_value, $label) = each($this->default_value);
1668 if ($posted_value == $default_value)
1669 return "${n}//" . $this->_config_format($posted_value);
1670 else if ($posted_value == '')
1671 return "${n}//" . $this->_config_format('false');
1673 return "${n}" . $this->_config_format($posted_value);
1677 class boolean_define_commented_optional
1678 extends boolean_define_commented {
1679 function _config_format($value) {
1680 $name = $this->get_config_item_name();
1681 return "if (!defined('$name')) " . boolean_define_commented::_config_format($value);
1687 function value () { return; }
1688 function get_config($posted_value) {
1689 $d = stripHtml($this->_get_description());
1691 return "\n".$SEPARATOR . str_replace("\n", "\n// ", $d) ."\n$this->default_value";
1693 function get_instructions($title) {
1694 $group_name = preg_replace("/\W/","",$title);
1695 $i = "<tr class='header' id='$group_name'>\n<td class=\"part\" width=\"100%\" colspan=\"2\" bgcolor=\"#eeaaaa\">\n";
1696 $i .= "<h2>" . $title . "</h2>\n " . nl2p($this->_get_description()) ."\n";
1697 $i .= "<p><a href=\"javascript:toggle_group('$group_name')\" id=\"{$group_name}_text\">Hide options.</a></p>";
1698 return $i ."</td>\n";
1700 function get_html() {
1705 // html utility functions
1706 function nl2p($text) {
1707 preg_match_all("@\s*(<pre>.*?</pre>|<dl>.*?</dl>|.*?(?=\n\n|<pre>|<dl>|$))@s",
1708 $text, $m, PREG_PATTERN_ORDER);
1711 foreach ($m[1] as $par) {
1712 if (!($par = trim($par)))
1714 if (!preg_match('/^<(pre|dl)>/', $par))
1715 $par = "<p>$par</p>";
1721 function stripHtml($text) {
1722 $d = str_replace("<pre>", "", $text);
1723 $d = str_replace("</pre>", "", $d);
1724 $d = str_replace("<dl>", "", $d);
1725 $d = str_replace("</dl>", "", $d);
1726 $d = str_replace("<dt>", "", $d);
1727 $d = str_replace("</dt>", "", $d);
1728 $d = str_replace("<dd>", "", $d);
1729 $d = str_replace("</dd>", "", $d);
1730 $d = str_replace("<p>", "", $d);
1731 $d = str_replace("</p>", "", $d);
1732 //restore html entities into characters
1733 // http://www.php.net/manual/en/function.htmlentities.php
1734 $trans = get_html_translation_table (HTML_ENTITIES);
1735 $trans = array_flip ($trans);
1736 $d = strtr($d, $trans);
1741 * Seed the random number generator.
1743 * better_srand() ensures the randomizer is seeded only once.
1745 * How random do you want it? See:
1746 * http://www.php.net/manual/en/function.srand.php
1747 * http://www.php.net/manual/en/function.mt-srand.php
1749 function better_srand($seed = '') {
1750 static $wascalled = FALSE;
1753 list($usec,$sec)=explode(" ",microtime());
1755 $seed = (double) $usec * $sec;
1756 else // once in a while use the combined LCG entropy
1757 $seed = (double) 1000000 * substr(uniqid("",true),13);
1759 if (function_exists('mt_srand')) {
1760 mt_srand($seed); // mersenne twister
1768 function rand_ascii($length = 1) {
1771 for ($i = 1; $i <= $length; $i++) {
1772 // return only typeable 7 bit ascii, avoid quotes
1773 if (function_exists('mt_rand'))
1774 // the usually bad glibc srand()
1775 $s .= chr(mt_rand(40, 126));
1777 $s .= chr(rand(40, 126));
1783 // Function to create better user passwords (much larger keyspace),
1784 // suitable for user passwords.
1785 // Sequence of random ASCII numbers, letters and some special chars.
1786 // Note: There exist other algorithms for easy-to-remember passwords.
1787 function random_good_password ($minlength = 5, $maxlength = 8) {
1789 // assume ASCII ordering (not valid on EBCDIC systems!)
1790 $valid_chars = "!#%&+-.0123456789=@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz";
1791 $start = ord($valid_chars);
1792 $end = ord(substr($valid_chars,-1));
1794 if (function_exists('mt_rand')) // mersenne twister
1795 $length = mt_rand($minlength, $maxlength);
1796 else // the usually bad glibc rand()
1797 $length = rand($minlength, $maxlength);
1798 while ($length > 0) {
1799 if (function_exists('mt_rand'))
1800 $newchar = mt_rand($start, $end);
1802 $newchar = rand($start, $end);
1803 if (! strrpos($valid_chars,$newchar) ) continue; // skip holes
1804 $newpass .= sprintf("%c",$newchar);
1811 function printArray($a) {
1812 echo "<hr />\n<pre>\n";
1814 echo "\n</pre>\n<hr />\n";
1817 // end of class definitions
1818 /////////////////////////////
1819 // begin auto generation code
1821 if (!function_exists('is_a'))
1823 function is_a($object, $class)
1825 $class = strtolower($class);
1826 return (get_class($object) == $class) or is_subclass_of($object, $class);
1831 if (@$HTTP_POST_VARS['action'] == 'make_config') {
1833 $timestamp = date ('dS of F, Y H:i:s');
1836 /* This is a local configuration file for PhpWiki.
1837 * It was automatically generated by the configurator script
1838 * on the $timestamp.
1843 /////////////////////////////////////////////////////////////////////
1847 $posted = $GLOBALS['HTTP_POST_VARS'];
1849 if (defined('DEBUG'))
1850 printArray($GLOBALS['HTTP_POST_VARS']);
1852 foreach($properties as $option_name => $a) {
1853 $posted_value = $posted[$a->config_item_name];
1854 $config .= $properties[$option_name]->get_config($posted_value);
1857 if (defined('DEBUG')) {
1858 $diemsg = "The configurator.php is provided for testing purposes only.
1859 You can't use this file with your PhpWiki server yet!!";
1860 $config .= "\ndie(\"$diemsg\");\n";
1864 // I think writing this config file is a big security hole.
1865 // If this is installed in such a way that it can write an index-user.php,
1866 // then anyone can create a working index-user.php with, e.g. any
1867 // admin user and pw of their choosing...
1869 // So I'm disabling it...
1871 if (defined(ENABLE_FILE_OUTPUT) and ENABLE_FILE_OUPUT) {
1872 /* We first check if the config-file exists. */
1873 if (file_exists($fs_config_file)) {
1874 /* We make a backup copy of the file */
1875 // $config_file = 'index-user.php';
1876 $new_filename = preg_replace('/\.php$/', time() . '.php', $fs_config_file);
1877 if (@copy($fs_config_file, $new_filename)) {
1878 $fp = @fopen($fs_config_file, 'w');
1881 $fp = @fopen($fs_config_file, 'w');
1890 fputs($fp, $config);
1892 echo "<p>The configuration was written to <code><b>$config_file</b></code>.</p>\n";
1893 if ($new_filename) {
1894 echo "<p>A backup was made to <code><b>$new_filename</b></code>.</p>\n";
1896 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";
1898 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>index.php</b></code>.</p>\n";
1901 echo "<hr />\n<p>Here's the configuration file based on your answers:</p>\n";
1902 echo "<form method='get' action='$PHP_SELF'>\n";
1903 echo "<textarea id='config-output' readonly='readonly' style='width:100%;' rows='30' cols='100'>\n";
1904 echo htmlentities($config);
1905 echo "</textarea></form>\n";
1908 echo "<p>To make any corrections, <a href=\"configurator.php\">edit the settings again</a>.</p>\n";
1910 } else { // first time or create password
1911 $posted = $GLOBALS['HTTP_POST_VARS'];
1912 /* No action has been specified - we make a form. */
1915 <form action="configurator.php" method="post">
1916 <input type="hidden" name="action" value="make_config" />
1917 <table cellpadding="4" cellspacing="0">
1920 while(list($property, $obj) = each($properties)) {
1921 echo $obj->get_instructions($property);
1922 if ($h = $obj->get_html()) {
1923 if (defined('DEBUG')) $h = get_class($obj) . "<br />\n" . $h;
1924 echo "<td>".$h."</td>\n";
1931 <p><input type="submit" value="Save ',$config_file,'" /> <input type="reset" value="Clear" /></p>