]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - configurator.php
fixed some minor bugs.
[SourceForge/phpwiki.git] / configurator.php
1 <?php 
2 $tdwidth = 700;
3 $config_file = 'index-user.php';
4 $fs_config_file = dirname(__FILE__) . (substr(PHP_OS,0,3) == 'WIN' ? '\\' : "/") . $config_file;
5 if ($HTTP_POST_VARS['create'])  header('Location: configurator.php?create=1#create');
6 printf("<?xml version=\"1.0\" encoding=\"%s\"?>\n", 'iso-8859-1'); 
7 ?>
8 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
9   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
10 <html xmlns="http://www.w3.org/1999/xhtml">
11 <head>
12 <!-- $Id: configurator.php,v 1.7 2002-09-15 16:17:37 rurban Exp $ -->
13 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
14 <title>Configuration tool for PhpWiki 1.3.x</title>
15 <style type="text/css" media="screen">
16 <!--
17 /* TABLE { border: thin solid black } */
18 body { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 80%; }
19 pre { font-size: 120%; }
20 td { border: thin solid black }
21 tr { border: none }
22 td.part { background-color: #eeaaaa; }
23 td.full_instructions { background-color: #eeeeee; }
24 td.instructions { background-color: #ffffee; width: <?php echo $tdwidth ?>; }
25 td.unchangeable_variable_top   { border-bottom: none; background-color: #eeeeee; }
26 td.unchangeable_variable_left  { top-bottom: none; background-color: #eeeeee; }
27 /* td.unchangeable_variable_right { top-bottom: none; background-color: #ffffff; } */
28 -->
29 </style>
30 <script language="JavaScript" type="text/javascript">
31 <!--
32 function update(accepted, error, value, output) {
33   if (accepted) {
34     document.getElementById(output).innerHTML = "<font color=\"green\">Input accepted.</font>";
35   } else {
36     while ((index = error.indexOf("%s")) > -1) {
37       error = error.substring(0, index) + value + error.substring(index+2);
38     }
39     document.getElementById(output).innerHTML = "<font color=\"red\">" + error + "</font>";
40   }
41 }
42
43 function validate(error, value, output, field) {
44   update(field.value == value, error, field.value, output);
45 }
46
47 function validate_ereg(error, ereg, output, field) {
48   regex = new RegExp(ereg);
49   update(regex.test(field.value), error, field.value, output);
50 }
51
52 function validate_range(error, low, high, empty_ok, output, field) {
53   update((empty_ok == 1 && field.value == "") ||
54          (field.value >= low && field.value <= high),
55          error, field.value, output);
56 }
57
58 function toggle_group(id) {
59   group = document.getElementById(id);
60   text = document.getElementById(id + "_text");
61   input = document.getElementById(id + "_input");
62   if (group.style.display == "none") {
63     text.innerHTML = "Hide options.";
64     group.style.display = "block";
65     input.value = 1;
66   } else {
67     text.innerHTML = "Show options.";
68     group.style.display = "none";
69     input.value = 0;
70   }
71 }
72 -->
73 </script>
74 </head>
75 <body>
76
77 <h1>Configuration tool for PhpWiki 1.3.x</h1>
78
79 <?php
80 //define('DEBUG', 1);
81 /**
82  * The Configurator is a php script to aid in the configuration of PhpWiki.
83  * Parts of this file are based on PHPWeather's configurator.php file.
84  * http://sourceforge.net/projects/phpweather/
85  *
86  *
87  * TO CHANGE THE CONFIGURATION OF YOUR PHPWIKI, DO *NOT* MODIFY THIS FILE!
88  * more instructions go here
89  *
90  * Todo: 
91  *   * start this automatically the first time
92  *   * fix include_path
93  *   * eval index.php to get the actual settings.
94  *   * ask to store it in index.php or settings.php
95  * 
96  * The file settings.php will be generated which you can use as your index.php.
97  */
98
99
100 //////////////////////////////
101 // begin configuration options
102
103
104 /**
105  * Notes for the description parameter of $property:
106  *
107  * - Descriptive text will be changed into comments (preceeded by //)
108  *   for the final output to index.php.
109  *
110  * - Only a limited set of html is allowed: pre, dl dt dd; it will be
111  *   stripped from the final output.
112  *
113  * - Line breaks and spacing will be preserved for the final output.
114  *
115  * - Double line breaks are automatically converted to paragraphs
116  *   for the html version of the descriptive text.
117  *
118  * - Double-quotes and dollar signs in the descriptive text must be
119  *   escaped: \" and \$. Instead of escaping double-quotes you can use 
120  *   single (') quotes for the enclosing quotes. 
121  *
122  * - Special characters like < and > must use html entities,
123  *   they will be converted back to characters for the final output.
124  */
125
126 $SEPARATOR = "///////////////////////////////////////////////////////////////////";
127
128 $copyright = '
129 Copyright 1999, 2000, 2001, 2002 $ThePhpWikiProgrammingTeam = array(
130 "Steve Wainstead", "Clifford A. Adams", "Lawrence Akka", 
131 "Scott R. Anderson", "Jon Åslund", "Neil Brown", "Jeff Dairiki",
132 "Stéphane Gourichon", "Jan Hidders", "Arno Hollosi", "John Jorgensen",
133 "Antti Kaihola", "Jeremie Kass", "Carsten Klapp", "Marco Milanesi",
134 "Grant Morgan", "Jan Nieuwenhuizen", "Aredridel Niothke", 
135 "Pablo Roca Rozas", "Sandino Araico Sánchez", "Joel Uckelman", 
136 "Reini Urban", "Tim Voght");
137
138 This file is part of PhpWiki.
139
140 PhpWiki is free software; you can redistribute it and/or modify
141 it under the terms of the GNU General Public License as published by
142 the Free Software Foundation; either version 2 of the License, or
143 (at your option) any later version.
144
145 PhpWiki is distributed in the hope that it will be useful,
146 but WITHOUT ANY WARRANTY; without even the implied warranty of
147 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
148 GNU General Public License for more details.
149
150 You should have received a copy of the GNU General Public License
151 along with PhpWiki; if not, write to the Free Software
152 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
153 ';
154
155
156
157 $preamble = "
158   This is the starting file for PhpWiki. All this file does is set
159   configuration options, and at the end of the file it includes() the
160   file lib/main.php, where the real action begins.
161
162   If you include this file to override the default settings here, 
163   you must also include lib/main.php.
164
165   This file is divided into seven parts: Parts Zero, One, Two, Three,
166   Four, Five and Six. Each one has different configuration settings you can
167   change; in all cases the default should work on your system,
168   however, we recommend you tailor things to your particular setting.
169 ";
170
171
172
173 $properties["Part Zero"] =
174 new part('_part0', false, "
175 Part Zero: If PHP needs help in finding where you installed the
176 rest of the PhpWiki code, you can set the include_path here.");
177
178 if (substr(PHP_OS,0,3) == 'WIN') {
179     $include_path = ini_get('include_path') . ';' . dirname(__FILE__);
180     if (strchr(ini_get('include_path'),'/'))
181         $include_path = strtr($include_path,'\\','/');
182 } else {
183     $include_path = ini_get('include_path') . ':' . dirname(__FILE__);
184 }
185
186 $properties["PHP include_path"] =
187 new _ini_set('include_path', $include_path, "
188 NOTE: phpwiki uses the PEAR library of php code for SQL database
189 access. Your PHP is probably already configured to set
190 include_path so that PHP can find the pear code. If not (or if you
191 change include_path here) make sure you include the path to the
192 PEAR code in include_path. (To find the PEAR code on your system,
193 search for a file named 'PEAR.php'. Some common locations are:
194 <pre>
195   Unixish systems:
196     /usr/share/php
197     /usr/local/share/php
198   Mac OS X:
199     /System/Library/PHP
200 </pre>
201 The above examples are already included by PhpWiki. You shouldn't
202 have to change this unless you see a WikiFatalError:
203 <pre>
204     lib/FileFinder.php:82: Fatal[256]: 
205     DB.php: file not found
206 </pre>
207 Define the include path for this wiki: pear plus the phpwiki path
208 <pre>
209 \$include_path = '.:/Apache/php/pear:/prog/php/phpwiki';
210 </pre>
211 Windows needs ';' as path delimiter. cygwin, mac and unix ':'
212 <pre>
213 if (substr(PHP_OS,0,3) == 'WIN') {
214   \$include_path = implode(';',explode(':',\$include_path));
215 } elseif (substr(PHP_OS,0,6) == 'CYGWIN') {
216   \$include_path = '.:/usr/local/lib/php/pear'.
217                      ':/usr/src/php/phpwiki';
218 } else {
219   ;
220 }</pre>");
221
222 $properties["Part Null"] =
223 new part('_partnullheader', "", "
224 Part Null: Don't touch this!");
225
226
227
228 $properties["Part Null Settings"] =
229 new unchangeable_variable('_partnullsettings', "
230 define ('PHPWIKI_VERSION', '1.3.4pre');
231 require \"lib/prepend.php\";
232 rcs_id('\$Id: configurator.php,v 1.7 2002-09-15 16:17:37 rurban Exp $');", "");
233
234
235 $properties["Part One"] =
236 new part('_partone', $SEPARATOR."\n", "
237
238 Part One:
239 Authentication and security settings. See Part Three for more.
240 ");
241
242
243
244 $properties["Wiki Name"] =
245 new _define_optional('WIKI_NAME', 'PhpWiki', "
246 The name of your wiki.
247 This is used to generate a keywords meta tag in the HTML templates,
248 in bookmark titles for any bookmarks made to pages in your wiki,
249 and during RSS generation for the title of the RSS channel.");
250
251
252 $properties["Reverse DNS"] =
253 new boolean_define('ENABLE_REVERSE_DNS',
254                     array('true'  => "true. perform additional reverse dns lookups",
255                           'false' => "false. just record the address as given by the httpd server"), "
256 If set, we will perform reverse dns lookups to try to convert the
257 users IP number to a host name, even if the http server didn't do
258 it for us.");
259
260
261
262 $properties["Admin Username"] =
263 new _define_optional('ADMIN_USER', "", "
264 <a name=\"create\">You must set this! Username and password of the administrator.</a>");
265
266 $properties["Admin Password"] =
267 new _define_password_optional('ADMIN_PASSWD', "", "
268 For heaven's sake pick a good password.
269 You can also use our <a target=\"_new\" href=\"passencrypt.php\">passwordencrypter</a> to encrypt an existing password.");
270
271 $properties["Encrypted Password"] = 
272 new boolean_define_optional('ENCRYPTED_PASSWD',
273                     array('true'  => "true. ADMIN_PASSWD is encrypted",
274                           'false' => "false. ADMIN_PASSWD is plaintext. Not recommended!"), "
275 If you used the passencrypt.php utility to encode the password or use an existing unix-crypt password,
276 then set this to true. Recommended!");
277
278 $properties["ZIPdump Authentication"] =
279 new boolean_define_optional('ZIPDUMP_AUTH', 
280                     array('false' => "false. Everyone may download zip dumps",
281                           'true'  => "true. Only admin may download zip dumps"), "
282 If true, only the admin user can make zip dumps, else zip dumps
283 require no authentication.");
284
285 $properties["Enable Plugin RawHtml"] =
286 new boolean_define_optional('ENABLE_RAW_HTML', 
287                     array('false' => "Disabled. Recommended on public sites.",
288                           'true'  => "Enabled"), "
289 Allow < ?plugin RawHtml ...>. Don't do this on a publicly accessable wiki for now.");
290
291 $properties["Strict Mailable Pagedumps"] =
292 new boolean_define('STRICT_MAILABLE_PAGEDUMPS', 
293                     array('false' => "binary",
294                           'true'  => "quoted-printable"), "
295 If you define this to true, (MIME-type) page-dumps (either zip dumps,
296 or \"dumps to directory\" will be encoded using the quoted-printable
297 encoding.  If you're actually thinking of mailing the raw page dumps,
298 then this might be useful, since (among other things,) it ensures
299 that all lines in the message body are under 80 characters in length.
300
301 Also, setting this will cause a few additional mail headers
302 to be generated, so that the resulting dumps are valid
303 RFC 2822 e-mail messages.
304
305 Probably, you can just leave this set to false, in which case you get
306 raw ('binary' content-encoding) page dumps.");
307
308
309
310 $properties["HTML Dump Filename Suffix"] =
311 new _variable('HTML_DUMP_SUFFIX', ".html", "
312 Here you can change the filename suffix used for XHTML page dumps.
313 If you don't want any suffix just comment this out.");
314
315
316
317 $properties["Maximum Upload Size"] =
318 new numeric_define('MAX_UPLOAD_SIZE', "16 * 1024 * 1024", "
319 The maximum file upload size.");
320
321
322
323 $properties["Minor Edit Timeout"] =
324 new numeric_define('MINOR_EDIT_TIMEOUT', "7 * 24 * 3600", "
325 If the last edit is older than MINOR_EDIT_TIMEOUT seconds, the
326 default state for the \"minor edit\" checkbox on the edit page form
327 will be off.");
328
329
330
331 $properties["Disabled Actions"] =
332 new array_variable('DisabledActions', array(), "
333 Actions listed in this array will not be allowed. Actions are:
334 browse, diff, dumphtml, dumpserial, edit, loadfile, lock, remove, 
335 unlock, upload, viewsource, zip, ziphtml");
336
337 $properties["Access Log"] =
338 new _define_commented('ACCESS_LOG', "/var/logs/wiki_access.log", "
339 PhpWiki can generate an access_log (in \"NCSA combined log\" format)
340 for you. If you want one, define this to the name of the log file,
341 such as /tmp/wiki_access_log.");
342
343
344 $properties["Path for PHP Session Support"] =
345 new _ini_set('session.save_path', '/tmp', "
346 The login code now uses PHP's session support. Usually, the default
347 configuration of PHP is to store the session state information in
348 /tmp. That probably will work fine, but fails e.g. on clustered
349 servers where each server has their own distinct /tmp (this is the
350 case on SourceForge's project web server.) You can specify an
351 alternate directory in which to store state information like so
352 (whatever user your httpd runs as must have read/write permission
353 in this directory):");
354
355
356
357 $properties["Disable PHP Transparent Session ID"] =
358 new unchangeable_ini_set('session.use_trans_sid', "@ini_set('session.use_trans_sid', 0);", "
359 If your php was compiled with --enable-trans-sid it tries to
360 add a PHPSESSID query argument to all URL strings when cookie
361 support isn't detected in the client browser.  For reasons
362 which aren't entirely clear (PHP bug) this screws up the URLs
363 generated by PhpWiki.  Therefore, transparent session ids
364 should be disabled.  This next line does that.
365
366 (At the present time, you will not be able to log-in to PhpWiki,
367 or set any user preferences, unless your browser supports cookies.)");
368
369
370
371 ///////// database selection
372
373
374 $properties["Part Two"] =
375 new part('_parttwo', $SEPARATOR."\n", "
376
377 Part Two:
378 Database Selection
379 ");
380
381
382 $properties["Database Type"] =
383 new _variable_selection("DBParams|dbtype",
384               array('dba'   => "dba DBM",
385                     'SQL'   => "SQL PEAR",
386                     'ADODB' => "SQL ADODB",
387                     'cvs'   => "CVS File handler"), "
388 Select the database backend type:
389 Choose ADODB or SQL to use an SQL database with ADODB or PEAR.
390 Choose dba to use one of the standard UNIX dbm libraries.
391 CVS is not yet tested nor supported.
392 Recommended is SQL PEAR.");
393
394 $properties["Filename / Table name Prefix"] =
395 new _variable_commented("DBParams|prefix", "phpwiki_", "
396 Used by all DB types:
397
398 Prefix for filenames or table names
399
400 Currently you MUST EDIT THE SQL file too (in the schemas/
401 directory because we aren't doing on the fly sql generation
402 during the installation.");
403
404
405 $properties["SQL dsn Setup"] =
406 new unchangeable_variable('_sqldsnstuff', "", "
407 For SQL based backends, specify the database as a DSN
408 The most general form of a DSN looks like:
409 <pre>
410   phptype(dbsyntax)://username:password@protocol+hostspec/database
411 </pre>
412 For a MySQL database, the following should work:
413 <pre>
414    mysql://user:password@host/databasename
415 </pre>
416 <dl><dd>FIXME:</dd> <dt>My version Pear::DB seems to be broken enough that there
417         is no way to connect to a mysql server over a socket right now.</dt></dl>
418 <pre>'dsn' => 'mysql://guest@:/var/lib/mysql/mysql.sock/test',
419 'dsn' => 'mysql://guest@localhost/test',
420 'dsn' => 'pgsql://localhost/test',</pre>");
421
422 // Choose ADODB or SQL to use an SQL database with ADODB or PEAR.
423 // Choose dba to use one of the standard UNIX dbm libraries.
424
425 $properties["SQL Type"] =
426 new _variable_selection('_dsn_sqltype',
427               array('mysql' => "MySQL",
428                     'pgsql' => "PostgreSQL"), "
429 SQL DB types");
430
431
432
433 $properties["SQL User"] =
434 new _variable('_dsn_sqluser', "wikiuser", "
435 SQL User Id:");
436
437
438
439 $properties["SQL Password"] =
440 new _variable('_dsn_sqlpass', "", "
441 SQL Password:");
442
443
444
445 $properties["SQL Database Host"] =
446 new _variable('_dsn_sqlhostorsock', "localhost", "
447 SQL Database Hostname:");
448
449
450
451 $properties["SQL Database Name"] =
452 new _variable('_dsn_sqldbname', "phpwiki", "
453 SQL Database Name:");
454
455 list($dsn_sqltype,) = $properties["SQL Type"]->value();
456 $dsn_sqluser = $properties["SQL User"]->value();
457 $dsn_sqlpass = $properties["SQL Password"]->value();
458 $dsn_sqlhostorsock = $properties["SQL Database Host"]->value();
459 $dsn_sqldbname = $properties["SQL Database Name"]->value();
460
461 $properties["SQL dsn"] =
462 new unchangeable_variable("DBParams['dsn']", 
463   "\$DBParams['dsn'] = \"\$_dsn_sqltype://{$dsn_sqluser}:{$dsn_sqlpass}@{$dsn_sqlhostorsock}/{$dsn_sqldbname}\";", "");
464
465 $properties["dba directory"] =
466 new _variable("DBParams|directory", "/tmp", "
467 dba directory:");
468
469
470 $properties["dba handler"] =
471 new _variable_selection('DBParams|dba_handler',
472               array('gdbm' => "Gdbm - GNU database manager",
473                     'dbm'  => "DBM - Redhat default. On sf.net there's dbm and gdbm",
474                     'db2'  => "DB2 - Sleepycat Software's DB2",
475                     'db3'  => "DB3 - Sleepycat Software's DB3. Fine on Windows but not on every Linux"), "
476 Use 'gdbm', 'dbm', 'db2' or 'db3' depending on your DBA handler methods supported:");
477
478 $properties["dba timeout"] =
479 new _variable("DBParams|timeout", "20", "
480 Recommended values are 20 or 5.");
481
482
483
484 ///////////////////
485
486
487
488 $properties["Page Revisions"] =
489 new unchangeable_variable('_parttworevisions', "", "
490
491 The next section controls how many old revisions of each page are
492 kept in the database.
493
494 There are two basic classes of revisions: major and minor. Which
495 class a revision belongs in is determined by whether the author
496 checked the \"this is a minor revision\" checkbox when they saved the
497 page.
498  
499 There is, additionally, a third class of revisions: author
500 revisions. The most recent non-mergable revision from each distinct
501 author is and author revision.
502
503 The expiry parameters for each of those three classes of revisions
504 can be adjusted seperately. For each class there are five
505 parameters (usually, only two or three of the five are actually
506 set) which control how long those revisions are kept in the
507 database.
508 <dl>
509    <dt>max_keep:</dt> <dd>If set, this specifies an absolute maximum for the
510             number of archived revisions of that class. This is
511             meant to be used as a safety cap when a non-zero
512             min_age is specified. It should be set relatively high,
513             and it's purpose is to prevent malicious or accidental
514             database overflow due to someone causing an
515             unreasonable number of edits in a short period of time.</dd>
516
517   <dt>min_age:</dt>  <dd>Revisions younger than this (based upon the supplanted
518             date) will be kept unless max_keep is exceeded. The age
519             should be specified in days. It should be a
520             non-negative, real number,</dd>
521
522   <dt>min_keep:</dt> <dd>At least this many revisions will be kept.</dd>
523
524   <dt>keep:</dt>     <dd>No more than this many revisions will be kept.</dd>
525
526   <dt>max_age:</dt>  <dd>No revision older than this age will be kept.</dd>
527 </dl>
528 Supplanted date: Revisions are timestamped at the instant that they
529 cease being the current revision. Revision age is computed using
530 this timestamp, not the edit time of the page.
531
532 Merging: When a minor revision is deleted, if the preceding
533 revision is by the same author, the minor revision is merged with
534 the preceding revision before it is deleted. Essentially: this
535 replaces the content (and supplanted timestamp) of the previous
536 revision with the content after the merged minor edit, the rest of
537 the page metadata for the preceding version (summary, mtime, ...)
538 is not changed.
539 ");
540
541
542 // For now the expiration parameters are statically inserted as
543 // an unchangeable property. You'll have to edit the resulting
544 // config file if you really want to change these from the default.
545
546 $properties["Expiration Parameters for Major Edits"] =
547 new unchangeable_variable('ExpireParams|major',
548 "\$ExpireParams['major'] = array('max_age' => 32,
549                                'keep'    => 8);", "
550 Keep up to 8 major edits, but keep them no longer than a month.");
551
552 $properties["Expiration Parameters for Minor Edits"] =
553 new unchangeable_variable('ExpireParams|minor',
554 "\$ExpireParams['minor'] = array('max_age' => 7,
555                                'keep'    => 4);", "
556 Keep up to 4 minor edits, but keep them no longer than a week.");
557
558
559
560 $properties["Expiration Parameters by Author"] =
561 new unchangeable_variable('ExpireParams|author',
562 "\$ExpireParams['author'] = array('max_age'  => 365,
563                                 'keep'     => 8,
564                                 'min_age'  => 7,
565                                 'max_keep' => 20);", "
566 Keep the latest contributions of the last 8 authors up to a year.
567 Additionally, (in the case of a particularly active page) try to
568 keep the latest contributions of all authors in the last week (even
569 if there are more than eight of them,) but in no case keep more
570 than twenty unique author revisions.");
571
572 /////////////////////////////////////////////////////////////////////
573
574 $properties["Part Three"] =
575 new part('_partthree', $SEPARATOR."\n", "
576
577 Part Three: (optional)
578 User Authentification
579 ");
580
581 $properties["User Authentication"] =
582 new boolean_define_optional('ALLOW_USER_LOGIN',
583                     array('true'  => "true. Check any defined passwords. (Default)",
584                           'false' => "false. Don't check passwords. Legacy < 1.3.4"), "
585 If ALLOW_USER_LOGIN is true, any defined internal and external
586 authentication method is tried. 
587 If not, we don't care about passwords, but check the next two constants.");
588
589 $properties["HTTP Authentication"] =
590 new boolean_define_optional('ALLOW_HTTP_AUTH_LOGIN',
591                     array('false' => "false. Ignore HTTP Authentication. (Default)",
592                           'true'  => "true. Allow .htpasswd users login automatically."), "
593 The wiki can be optionally be protected by HTTP Auth. Use the username and password 
594 from there, and if this fails, try the other methods also.");
595
596 $properties["Strict Login"] =
597 new boolean_define_optional('ALLOW_BOGO_LOGIN',
598                     array('true'  => "Users may Sign In with any WikiWord",
599                           'false' => "Only admin may Sign In"), "
600 If ALLOW_BOGO_LOGIN is true, users are allowed to login (with
601 any/no password) using any userid which: 1) is not the ADMIN_USER,
602 2) is a valid WikiWord (matches \$WikiNameRegexp.)
603 If true, users may be created by themselves. Otherwise we need seperate auth. 
604 This might be renamed to ALLOW_SELF_REGISTRATION");
605
606 $properties["Require Sign In Before Editing"] =
607 new boolean_define_optional('REQUIRE_SIGNIN_BEFORE_EDIT',
608                     array('false' => "Do not require Sign In",
609                           'true'  => "Require Sign In"), "
610 If set, then if an anonymous user attempts to edit a page he will
611 be required to sign in.  (If ALLOW_BOGO_LOGIN is true, of course,
612 no password is required, but the user must still sign in under
613 some sort of BogoUserId.)");
614
615 if (function_exists('ldap_connect')) {
616 $properties["LDAP Authentication"] =
617   new boolean_define_optional('ALLOW_LDAP_LOGIN',
618                     array('true'  => "Allow LDAP Authentication",
619                           'false' => "Ignore LDAP"), "LDAP Authentication");
620 $properties["LDAP Host"] =
621   new _define_optional('LDAP_AUTH_HOST', "localhost", "");
622 $properties["LDAP Root Search"] =
623   new _define_optional('LDAP_AUTH_SEARCH', "ou=mycompany.com,o=My Company", 
624   "Give the right LDAP root search information in the next statement.");
625
626 } else {
627
628 $properties["LDAP Authentication"] =
629 new unchangeable_define('ALLOW_LDAP_LOGIN', "
630 if (!defined('ALLOW_LDAP_LOGIN')) define('ALLOW_LDAP_LOGIN', true and function_exists('ldap_connect'));
631 if (!defined('LDAP_AUTH_HOST'))   define('LDAP_AUTH_HOST', 'localhost');
632 // Give the right LDAP root search information in the next statement. 
633 if (!defined('LDAP_AUTH_SEARCH')) define('LDAP_AUTH_SEARCH', 'ou=mycompany.com,o=My Company');
634 ", "
635 Ignored. No LDAP support in this php. configure --with-ldap");
636 }
637
638 if (function_exists('imap_open')) {
639 $properties["IMAP Authentication"] =
640   new boolean_define_optional('ALLOW_IMAP_LOGIN',
641                     array('true'  => "Allow IMAP Authentication",
642                           'false' => "Ignore IMAP"), "IMAP Authentication");
643 $properties["IMAP Host"] =
644   new _define_optional('IMAP_AUTH_HOST', 'localhost', '');
645 } else {
646 $properties["IMAP Authentication"] =
647   new unchangeable_define('ALLOW_IMAP_LOGIN',"
648 // IMAP auth: check userid/passwords from a imap server, defaults to localhost
649 if (!defined('ALLOW_IMAP_LOGIN')) define('ALLOW_IMAP_LOGIN', true and function_exists('imap_open'));
650 if (!defined('IMAP_AUTH_HOST'))   define('IMAP_AUTH_HOST', 'localhost');
651 ", "Ignored. No IMAP support in this php. configure --with-imap");
652 }
653
654
655 /////////////////////////////////////////////////////////////////////
656
657 $properties["Part Four"] =
658 new part('_partfour', $SEPARATOR."\n", "
659
660 Part Four:
661 Page appearance and layout
662 ");
663
664
665
666 $properties["Theme"] =
667 new _define_selection_optional('THEME',
668               array('default'  => "default",
669                     'Hawaiian' => "Hawaiian",
670                     'MacOSX'   => "MacOSX",
671                     'Portland' => "Portland",
672                     'Sidebar'  => "Sidebar",
673                     'SpaceWiki' => "SpaceWiki"), "
674 THEME
675
676 Most of the page appearance is controlled by files in the theme
677 subdirectory.
678
679 There are a number of pre-defined themes shipped with PhpWiki.
680 Or you may create your own (e.g. by copying and then modifying one of
681 stock themes.)
682
683 Pick one.
684 <pre>
685 define('THEME', 'default');
686 define('THEME', 'Hawaiian');
687 define('THEME', 'MacOSX');
688 define('THEME', 'Portland');
689 define('THEME', 'Sidebar');
690 define('THEME', 'SpaceWiki');</pre>");
691
692
693
694 $properties["Character Set"] =
695 new _define_optional('CHARSET', 'iso-8859-1', "
696 Select a valid charset name to be inserted into the xml/html pages, 
697 and to reference links to the stylesheets (css). For more info see: 
698 http://www.iana.org/assignments/character-sets. Note that PhpWiki 
699 has been extensively tested only with the latin1 (iso-8859-1) 
700 character set.
701
702 If you change the default from iso-8859-1 PhpWiki may not work 
703 properly and it will require code modifications. However, character 
704 sets similar to iso-8859-1 may work with little or no modification 
705 depending on your setup. The database must also support the same 
706 charset, and of course the same is true for the web browser. (Some 
707 work is in progress hopefully to allow more flexibility in this 
708 area in the future).");
709
710
711
712 $properties["Language"] =
713 new _variable_selection_optional('LANG',
714               array('en' => "English",
715                     'nl' => "Nederlands",
716                     'es' => "Español",
717                     'fr' => "Français",
718                     'de' => "Deutsch",
719                     'sv' => "Svenska",
720                     'it' => "Italiano",
721                     ''   => "none"), "
722 Select your language/locale - default language is \"en\" for English.
723 Other languages available:<pre>
724 English \"en\"  (English    - HomePage)
725 Dutch   \"nl\" (Nederlands - ThuisPagina)
726 Spanish \"es\" (Español    - PáginaPrincipal)
727 French  \"fr\" (Français   - Accueil)
728 German  \"de\" (Deutsch    - StartSeite)
729 Swedish \"sv\" (Svenska    - Framsida)
730 Italian \"it\" (Italiano   - PaginaPrincipale)
731 </pre>
732 If you set \$LANG to the empty string, your systems default language
733 (as determined by the applicable environment variables) will be
734 used.");
735
736 $properties["Language Locales"] =
737 new unchangeable_variable('language_locales',
738 "\$language_locales = array('en' => 'C',
739                             'de' => 'de_DE',
740                             'es' => 'es_MX',
741                             'nl' => 'nl_NL',
742                             'fr' => 'fr_FR',
743                             'it' => 'it_IT',
744                             'sv' => 'sv_SV'
745                             );
746 if (empty(\$LC_ALL)) {
747   if (empty(\$language_locales[\$LANG]))
748      \$LC_ALL = \$LANG;
749   else <br />
750      \$LC_ALL = \$language_locales[\$LANG];
751 }
752 putenv(\"LC_TIME=\$LC_ALL\");
753 ", "
754 Setting the LANG environment variable (accomplished above) may or
755 may not be sufficient to cause PhpWiki to produce dates in your
756 native language. (It depends on the configuration of the operating
757 system on your http server.)  The problem is that, e.g. 'de' is
758 often not a valid locale.
759
760 A standard locale name is typically of  the  form
761 language[_territory][.codeset][@modifier],  where  language is
762 an ISO 639 language code, territory is an ISO 3166 country code,
763 and codeset  is  a  character  set or encoding identifier like
764 ISO-8859-1 or UTF-8.
765
766 You can tailor the locale used for time and date formatting by
767 setting the LC_TIME environment variable. You'll have to experiment
768 to find the correct setting.
769 gettext() fix: With setlocale() we must use the long form, 
770 like 'de_DE','nl_NL', 'es_MX', 'es_AR', 'fr_FR'. 
771 For Windows maybe even 'german'. You might fix this accordingly.");
772
773 $properties["Wiki Page Source"] =
774 new _define_optional('WIKI_PGSRC', 'pgsrc', "
775 WIKI_PGSRC -- specifies the source for the initial page contents of
776 the Wiki. The setting of WIKI_PGSRC only has effect when the wiki is
777 accessed for the first time (or after clearing the database.)
778 WIKI_PGSRC can either name a directory or a zip file. In either case
779 WIKI_PGSRC is scanned for files -- one file per page.
780 <pre>
781 // Default (old) behavior:
782 define('WIKI_PGSRC', 'pgsrc'); 
783 // New style:
784 define('WIKI_PGSRC', 'wiki.zip'); 
785 define('WIKI_PGSRC', 
786        '../Logs/Hamwiki/hamwiki-20010830.zip'); 
787 </pre>");
788
789
790
791 $properties["Default Wiki Page Source"] =
792 new _define('DEFAULT_WIKI_PGSRC', 'pgsrc', "
793 DEFAULT_WIKI_PGSRC is only used when the language is *not* the
794 default (English) and when reading from a directory: in that case
795 some English pages are inserted into the wiki as well.
796 DEFAULT_WIKI_PGSRC defines where the English pages reside.
797
798 FIXME: is this really needed?
799 ");
800
801
802
803 $properties["Generic Pages"] =
804 new array_variable('GenericPages', array('ReleaseNotes', 'SteveWainstead', 'TestPage'), "
805 These are the pages which will get loaded from DEFAULT_WIKI_PGSRC.      
806
807 FIXME: is this really needed?  Can't we just copy these pages into
808 the localized pgsrc?
809 ");
810
811
812
813
814 $properties["Part Five"] =
815 new part('_partfive', $SEPARATOR."\n", "
816
817 Part Five:
818 Mark-up options.
819 ");
820
821
822
823 $properties["Allowed Protocols"] =
824 new list_variable('AllowedProtocols', 'http|https|mailto|ftp|news|nntp|ssh|gopher', "
825 allowed protocols for links - be careful not to allow \"javascript:\"
826 URL of these types will be automatically linked.
827 within a named link [name|uri] one more protocol is defined: phpwiki");
828
829
830
831 $properties["Inline Images"] =
832 new list_variable('InlineImages', 'png|jpg|gif', "
833 URLs ending with the following extension should be inlined as images");
834
835
836
837 $properties["WikiName Regexp"] =
838 new _variable('WikiNameRegexp', "(?<![[:alnum:]])(?:[[:upper:]][[:lower:]]+){2,}(?![[:alnum:]])", "
839 Perl regexp for WikiNames (\"bumpy words\")
840 (?&lt;!..) & (?!...) used instead of '\b' because \b matches '_' as well");
841
842 $properties["Subpage Separator"] =
843 new _define_optional('SUBPAGE_SEPARATOR', '/', "
844 One character which seperates pages from subpages. Defaults to '/', but '.' or ':' were also used.");
845
846 $properties["InterWiki Map File"] =
847 new _define('INTERWIKI_MAP_FILE', 'lib/interwiki.map', "
848 InterWiki linking -- wiki-style links to other wikis on the web
849
850 The map will be taken from a page name InterWikiMap.
851 If that page is not found (or is not locked), or map
852 data can not be found in it, then the file specified
853 by INTERWIKI_MAP_FILE (if any) will be used.");
854
855 $properties["WARN_NONPUBLIC_INTERWIKIMAP"] =
856 new boolean_define('WARN_NONPUBLIC_INTERWIKIMAP',   
857         array('true'  => "true",
858                           'false' => "false"), "
859 Display a warning if the internal lib/interwiki.map is used, and 
860 not the public InterWikiMap page. This map is not readable from outside.");
861
862
863 $properties["Part Six"] =
864 new part('_partsix', $SEPARATOR."\n", "
865
866 Part Six (optional):
867 URL options -- you can probably skip this section.
868 ");
869
870 $properties["Server Name"] =
871 new _define_commented_optional('SERVER_NAME', $HTTP_SERVER_VARS['SERVER_NAME'], "
872 Canonical name and httpd port of the server on which this PhpWiki
873 resides.");
874
875
876
877 $properties["Server Port"] =
878 new numeric_define_commented('SERVER_PORT', $HTTP_SERVER_VARS['SERVER_PORT'], "");
879
880 $scriptname = preg_replace('/configurator.php/','index.php',$HTTP_SERVER_VARS["SCRIPT_NAME"]);
881
882 $properties["Script Name"] =
883 new _define_commented_optional('SCRIPT_NAME', $scriptname, "
884 Relative URL (from the server root) of the PhpWiki script.");
885
886 $properties["Data Path"] =
887 new _define_commented_optional('DATA_PATH', dirname($scriptname), "
888 URL of the PhpWiki install directory.  (You only need to set this
889 if you've moved index.php out of the install directory.)  This can
890 be either a relative URL (from the directory where the top-level
891 PhpWiki script is) or an absolute one.");
892
893
894
895 $properties["PhpWiki Install Directory"] =
896 new _define_commented_optional('PHPWIKI_DIR', dirname(__FILE__), "
897 Path to the PhpWiki install directory.  This is the local
898 filesystem counterpart to DATA_PATH.  (If you have to set
899 DATA_PATH, your probably have to set this as well.)  This can be
900 either an absolute path, or a relative path interpreted from the
901 directory where the top-level PhpWiki script (normally index.php)
902 resides.");
903
904
905
906 $properties["Use PATH_INFO"] =
907 new boolean_define_commented_optional('USE_PATH_INFO', 
908                     array('true'  => 'use PATH_INFO',
909                           'false' => 'do not use PATH_INFO'), "
910 Define to 'true' to use PATH_INFO to pass the pagenames.
911 e.g. http://www.some.where/index.php/HomePage instead
912 of http://www.some.where/index.php?pagename=HomePage
913 FIXME: more docs (maybe in README). Default: true");
914
915
916
917 $properties["Virtual Path"] =
918 new _define_commented_optional('VIRTUAL_PATH', '/SomeWiki', "
919 VIRTUAL_PATH is the canonical URL path under which your your wiki
920 appears. Normally this is the same as dirname(SCRIPT_NAME), however
921 using, e.g. apaches mod_actions (or mod_rewrite), you can make it
922 something different.
923
924 If you do this, you should set VIRTUAL_PATH here.
925
926 E.g. your phpwiki might be installed at at /scripts/phpwiki/index.php,
927 but you've made it accessible through eg. /wiki/HomePage.
928
929 One way to do this is to create a directory named 'wiki' in your
930 server root. The directory contains only one file: an .htaccess
931 file which reads something like:
932 <pre>
933     Action x-phpwiki-page /scripts/phpwiki/index.php
934     SetHandler x-phpwiki-page
935     DirectoryIndex /scripts/phpwiki/index.php
936 </pre>
937 In that case you should set VIRTUAL_PATH to '/wiki'.
938
939 (VIRTUAL_PATH is only used if USE_PATH_INFO is true.)
940 ");
941
942
943
944 $end = "
945
946 $SEPARATOR
947 // Check if we were included by some other wiki version (getimg, en, ...) 
948 // or not. 
949 // If the server requested this index.php fire up the code by loading lib/main.php.
950 // Parallel wiki scripts can now simply include /index.php for the 
951 // main configuration, extend or redefine some settings and 
952 // load lib/main.php by themselves. 
953 // This overcomes the index as config problem.
954 $SEPARATOR
955
956 // This doesn't work with php as CGI yet!
957 if (defined('VIRTUAL_PATH') and defined('USE_PATH_INFO')) {
958     if (\$HTTP_SERVER_VARS['SCRIPT_NAME'] == VIRTUAL_PATH) {
959         include \"lib/main.php\";
960     }
961 } else {
962     if (defined('SCRIPT_NAME') and 
963         (\$HTTP_SERVER_VARS['SCRIPT_NAME'] == SCRIPT_NAME)) {
964         include \"lib/main.php\";
965     } elseif (strstr(\$HTTP_SERVER_VARS['PHP_SELF'],'index.php')) {
966         include \"lib/main.php\";
967     }
968 }
969
970 // (c-file-style: \"gnu\")
971 // Local Variables:
972 // mode: php
973 // tab-width: 8
974 // c-basic-offset: 4
975 // c-hanging-comment-ender-p: nil
976 // indent-tabs-mode: nil
977 // End:   
978 ?>
979 ";
980
981
982
983 // end of configuration options
984 ///////////////////////////////
985 // begin class definitions
986
987 /**
988  * A basic index.php configuration line in the form of a variable.
989  *
990  * Produces a string in the form "$name = value;"
991  * e.g.:
992  * $WikiNameRegexp = "value";
993  */
994 class _variable {
995
996     var $config_item_name;
997     var $default_value;
998     var $description;
999     var $prefix;
1000
1001     function _variable($config_item_name, $default_value, $description) {
1002         $this->config_item_name = $config_item_name;
1003         $this->description = $description;
1004         $this->default_value = $default_value;
1005         if (preg_match("/variable/i",get_class($this)))
1006             $this->prefix = "\$";
1007         elseif (preg_match("/ini_set/i",get_class($this)))
1008             $this->prefix = "ini_get: ";
1009         else
1010             $this->prefix = "";
1011     }
1012
1013     function value() {
1014       global $HTTP_POST_VARS;
1015       if ($v = $HTTP_POST_VARS[$this->config_item_name])
1016           return $v;
1017       else 
1018           return $this->default_value;
1019     }
1020
1021     function _config_format($value) {
1022         $v = $this->get_config_item_name();
1023         // handle arrays: a|b --> a['b']
1024         if (strpos($v, '|')) {
1025             list($a, $b) = explode('|', $v);
1026             $v = sprintf("%s['%s']", $a, $b);
1027         }
1028         return sprintf("\$%s = \"%s\";", $v, $value);
1029     }
1030
1031     function get_config_item_name() {
1032         return $this->config_item_name;
1033     }
1034
1035     function get_config_item_header() {
1036        if (strchr($this->config_item_name,'|')) {
1037           list($var,$param) = explode('|',$this->config_item_name);
1038           return "<b>" . $this->prefix . $var . "['" . $param . "']</b><br />";
1039        }
1040        elseif ($this->config_item_name[0] != '_')
1041           return "<b>" . $this->prefix . $this->config_item_name . "</b><br />";
1042        else 
1043           return '';
1044     }
1045
1046     function _get_description() {
1047         return $this->description;
1048     }
1049
1050     function _get_config_line($posted_value) {
1051         return "\n" . $this->_config_format($posted_value);
1052     }
1053
1054     function get_config($posted_value) {
1055         $d = stripHtml($this->_get_description());
1056         $d = str_replace("\n", "\n// ", $d) . $this->_get_config_line($posted_value) ."\n";
1057         return $d;
1058     }
1059
1060     function get_instructions($title) {
1061         global $tdwidth;
1062         $i = "<p><b><h3>" . $title . "</h3></b></p>\n    " . nl2p($this->_get_description()) . "\n";
1063         return "<tr>\n<td width=\"$tdwidth\" class=\"instructions\">\n" . $i . "</td>\n";
1064     }
1065
1066     function get_html() {
1067         return $this->get_config_item_header() . 
1068             "<input type=\"text\" size=\"50\" name=\"" . $this->get_config_item_name() . "\" value=\"" . $this->default_value . "\" />";
1069     }
1070 }
1071
1072 class unchangeable_variable
1073 extends _variable {
1074     function _config_format($value) {
1075         return "";
1076     }
1077     // function get_html() { return false; }
1078     function get_html() {
1079         return $this->get_config_item_header() . 
1080         "<em>Not editable.</em>" . 
1081         "<pre>" . $this->default_value."</pre>";
1082     }
1083     function _get_config_line($posted_value) {
1084         if ($this->description)
1085             $n = "\n";
1086         return "${n}".$this->default_value;
1087     }
1088     function get_instructions($title) {
1089         global $tdwidth;
1090         $i = "<p><b><h3>" . $title . "</h3></b></p>\n    " . nl2p($this->_get_description()) . "\n";
1091         // $i = $i ."<em>Not editable.</em><br />\n<pre>" . $this->default_value."</pre>";
1092         return "<tr><td width=\"100%\" class=\"unchangeable_variable_top\" colspan=\"2\">\n".$i ."</td></tr>\n".
1093         "<tr style=\"border-top: none\"><td class=\"unchangeable_variable_left\" width=\"$tdwidth\" bgcolor=\"#eeeeee\">&nbsp;</td>";
1094     }
1095 }
1096
1097 class unchangeable_define
1098 extends unchangeable_variable {
1099     function _config_format($value) {
1100         return "";
1101     }
1102 }
1103 class unchangeable_ini_set
1104 extends unchangeable_variable {
1105     function _config_format($value) {
1106         return "";
1107     }
1108 }
1109
1110
1111 class _variable_selection
1112 extends _variable {
1113     function value() {
1114         global $HTTP_POST_VARS;
1115         if ($v = $HTTP_POST_VARS[$this->config_item_name])
1116             return $v;
1117         else {
1118             list($option, $label) = current($this->default_value);
1119             return $this->$option;
1120         }
1121     }
1122     function get_html() {
1123         $output = $this->get_config_item_header();
1124         $output .= '<select name="' . $this->get_config_item_name() . "\">\n";
1125         /* The first option is the default */
1126         while(list($option, $label) = each($this->default_value)) {
1127             $output .= "  <option value=\"$option\">$label</option>\n";
1128         }
1129         $output .= "</select>\n  </td>\n";
1130         return $output;
1131     }
1132 }
1133
1134
1135 class _define
1136 extends _variable {
1137     function _config_format($value) {
1138         return sprintf("define('%s', '%s');", $this->get_config_item_name(), $value);
1139     }
1140     function _get_config_line($posted_value) {
1141         if ($this->description)
1142             $n = "\n";
1143         if ($posted_value == '')
1144             return "${n}//" . $this->_config_format("");
1145         else
1146             return "${n}" . $this->_config_format($posted_value);
1147     }
1148     function get_html() {
1149         return $this->get_config_item_header() . 
1150             "<input type=\"text\" size=\"50\" name=\"" . $this->get_config_item_name() . "\" value=\"" . $this->default_value . "\" />";
1151     }
1152 }
1153
1154 class _define_commented
1155 extends _define {
1156     function _get_config_line($posted_value) {
1157         if ($this->description)
1158             $n = "\n";
1159         if ($posted_value == $this->default_value)
1160             return "${n}//" . $this->_config_format($posted_value);
1161         else if ($posted_value == '')
1162             return "${n}//" . $this->_config_format("");
1163         else
1164             return "${n}" . $this->_config_format($posted_value);
1165     }
1166 }
1167
1168 class _define_commented_optional
1169 extends _define_commented {
1170     function _config_format($value) {
1171         $name = $this->get_config_item_name();
1172         return sprintf("if (!defined('%s')) define('%s', '%s');", $name, $name, $value);
1173     }
1174 }
1175
1176 class _define_optional
1177 extends _define {
1178     function _config_format($value) {
1179         $name = $this->get_config_item_name();
1180         return sprintf("if (!defined('%s')) define('%s', '%s');", $name, $name, $value);
1181     }
1182 }
1183
1184 class _variable_commented
1185 extends _variable {
1186     function _get_config_line($posted_value) {
1187         if ($this->description)
1188             $n = "\n";
1189         if ($posted_value == $this->default_value)
1190             return "${n}//" . $this->_config_format($posted_value);
1191         else if ($posted_value == '')
1192             return "${n}//" . $this->_config_format("");
1193         else
1194             return "${n}" . $this->_config_format($posted_value);
1195     }
1196 }
1197
1198 class numeric_define_commented
1199 extends _define {
1200     function get_html() {
1201         return numeric_define::get_html();
1202     }
1203     function _get_config_line($posted_value) {
1204         if ($this->description)
1205             $n = "\n";
1206         if ($posted_value == $this->default_value)
1207             return "${n}//" . $this->_config_format($posted_value);
1208         else if ($posted_value == '')
1209             return "${n}//" . $this->_config_format('0');
1210         else
1211             return "${n}" . $this->_config_format($posted_value);
1212     }
1213 }
1214
1215 class _define_selection
1216 extends _variable_selection {
1217     function _config_format($value) {
1218         return sprintf("define('%s', '%s');", $this->get_config_item_name(), $value);
1219     }
1220     function _get_config_line($posted_value) {
1221         return _define::_get_config_line($posted_value);
1222     }
1223     function get_html() {
1224         return _variable_selection::get_html();
1225     }
1226 }
1227
1228 class _define_selection_optional
1229 extends _define_selection {
1230     function _config_format($value) {
1231         $name = $this->get_config_item_name();
1232         return sprintf("if (!defined('%s')) define('%s', '%s');", $name, $name, $value);
1233     }
1234 }
1235
1236 class _variable_selection_optional
1237 extends _variable_selection {
1238     function _config_format($value) {
1239         $v = $this->get_config_item_name();
1240         // handle arrays: a|b --> a['b']
1241         if (strpos($v, '|')) {
1242             list($a, $b) = explode('|', $v);
1243             $v = sprintf("%s['%s']", $a, $b);
1244         }
1245         return sprintf("if (!isset(\$%s)) { \$%s = \"%s\"; }", $v, $v, $value);
1246     }
1247 }
1248
1249 class _define_password
1250 extends _define {
1251     function _get_config_line($posted_value) {
1252         if ($this->description)
1253             $n = "\n";
1254         if ($posted_value == '') {
1255             $p = "${n}//" . $this->_config_format("");
1256             $p = $p . "\n// If you used the passencrypt.php utility to encode the password";
1257             $p = $p . "\n// then uncomment this line:";
1258             $p = $p . "\n//if (!defined('ENCRYPTED_PASSWD')) define('ENCRYPTED_PASSWD', true);";
1259             return $p;
1260         } else {
1261             if (function_exists('crypt')) {
1262                 $salt_length = max(CRYPT_SALT_LENGTH,
1263                                     2 * CRYPT_STD_DES,
1264                                     9 * CRYPT_EXT_DES,
1265                                    12 * CRYPT_MD5,
1266                                    16 * CRYPT_BLOWFISH);
1267                 // generate an encrypted password
1268                 $crypt_pass = crypt($posted_value, rand_ascii($salt_length));
1269                 $p = "${n}" . $this->_config_format($crypt_pass);
1270                 return $p . "\ndefine('ENCRYPTED_PASSWD', true);";
1271             } else {
1272                 $p = "${n}" . $this->_config_format($posted_value);
1273                 $p = $p . "\n// If you used the passencrypt.php utility to encode the password";
1274                 $p = $p . "\n// then uncomment this line:";
1275                 $p = $p . "\n//define('ENCRYPTED_PASSWD', false);";
1276                 $p = $p . "\n// Encrypted passwords cannot be used:";
1277                 $p = $p . "\n// 'function crypt()' not available in this version of php";
1278                 return $p;
1279             }
1280         }
1281     }
1282     function get_html() {
1283         return _variable_password::get_html();
1284     }
1285 }
1286
1287 class _define_password_optional
1288 extends _define_password {
1289     function _config_format($value) {
1290         $name = $this->get_config_item_name();
1291         return sprintf("if (!defined('%s')) define('%s', '%s');", $name, $name, $value);
1292     }
1293 }
1294
1295
1296 class _variable_password
1297 extends _variable {
1298     function get_html() {
1299         global $HTTP_POST_VARS, $HTTP_GET_VARS;
1300         $s = $this->get_config_item_header();
1301         $s .= "<input type=\"password\" name=\"" . $this->get_config_item_name() . "\" value=\"" . $this->default_value . "\" />" . 
1302 "&nbsp;&nbsp;<input type=\"submit\" name=\"create\" value=\"Create Password\" />";
1303         if ($HTTP_POST_VARS['create'] or $HTTP_GET_VARS['create']) {
1304             $new_password = random_good_password();
1305             $this->default_value = $new_password;
1306             $s .= "<br />&nbsp;<br />Created password: <strong>$new_password</strong>";
1307         }
1308         return $s;
1309     }
1310 }
1311
1312 class numeric_define
1313 extends _define {
1314     function _config_format($value) {
1315         return sprintf("define('%s', %s);", $this->get_config_item_name(), $value);
1316     }
1317     function get_html() {
1318         $ori = _define::get_html();
1319         return substr($ori,0,-2) . " onchange=\"validate_ereg('Sorry, \'%s\' is not an integer.', '^[-+]?[0-9]+$', '" . $this->get_config_item_name() . "', this);" . '" />';
1320     }
1321     function _get_config_line($posted_value) {
1322         if ($this->description)
1323             $n = "\n";
1324         if ($posted_value == '')
1325             return "${n}//" . $this->_config_format('0');
1326         else
1327             return "${n}" . $this->_config_format($posted_value);
1328     }
1329 }
1330
1331 class list_variable
1332 extends _variable {
1333     function _get_config_line($posted_value) {
1334         // split the phrase by any number of commas or space characters,
1335         // which include " ", \r, \t, \n and \f
1336         $list_values = preg_split("/[\s,]+/", $posted_value, -1, PREG_SPLIT_NO_EMPTY);
1337         $list_values = join("|", $list_values);
1338         return _variable::_get_config_line($list_values);
1339     }
1340     function get_html() {
1341         $list_values = explode("|", $this->default_value);
1342         $rows = max(3, count($list_values) +1);
1343         $list_values = join("\n", $list_values);
1344         $ta = $this->get_config_item_header();
1345         $ta .= "<textarea cols=\"18\" rows=\"". $rows ."\" name=\"".$this->get_config_item_name()."\">";
1346         $ta .= $list_values . "</textarea>";
1347         return $ta;
1348     }
1349 }
1350
1351 class array_variable
1352 extends _variable {
1353     function _config_format($value) {
1354         return sprintf("\$%s = array(%s);", $this->get_config_item_name(), $value);
1355     }
1356     function _get_config_line($posted_value) {
1357         // split the phrase by any number of commas or space characters,
1358         // which include " ", \r, \t, \n and \f
1359         $list_values = preg_split("/[\s,]+/", $posted_value, -1, PREG_SPLIT_NO_EMPTY);
1360         if (!empty($list_values)) {
1361             $list_values = "'".join("', '", $list_values)."'";
1362             return "\n" . $this->_config_format($list_values);
1363         } else
1364             return "\n//" . $this->_config_format('');
1365     }
1366     function get_html() {
1367         $list_values = join("\n", $this->default_value);
1368         $rows = max(3, count($this->default_value) +1);
1369         $ta = $this->get_config_item_header();
1370         $ta .= "<textarea cols=\"18\" rows=\"". $rows ."\" name=\"".$this->get_config_item_name()."\">";
1371         $ta .= $list_values . "</textarea>";
1372         return $ta;
1373     }
1374
1375 }
1376
1377 class _ini_set
1378 extends _variable {
1379     function value() {
1380         global $HTTP_POST_VARS;
1381         if ($v = $HTTP_POST_VARS[$this->config_item_name])
1382             return $v;
1383         else {
1384             return ini_get($this->get_config_item_name);
1385         }
1386     }
1387     function _config_format($value) {
1388         return sprintf("ini_set('%s', '%s');", $this->get_config_item_name(), $value);
1389     }
1390     function _get_config_line($posted_value) {
1391         if ($posted_value && ! $posted_value == $this->default_value)
1392             return "\n" . $this->_config_format($posted_value);
1393         else
1394             return "\n//" . $this->_config_format($this->default_value);
1395     }
1396 }
1397
1398 class boolean_define
1399 extends _define {
1400     function _get_config_line($posted_value) {
1401         if ($this->description)
1402             $n = "\n";
1403         return "${n}" . $this->_config_format($posted_value);
1404     }
1405     function get_html() {
1406         $output = $this->get_config_item_header();
1407         $output .= '<select name="' . $this->get_config_item_name() . "\">\n";
1408         /* The first option is the default */
1409         list($option, $label) = each($this->default_value);
1410         $output .= "  <option value=\"$option\" selected>$label</option>\n";
1411         /* There can only be two options */
1412         list($option, $label) = each($this->default_value);
1413         $output .= "  <option value=\"$option\">$label</option>\n";
1414         $output .= "</select>\n  </td>\n";
1415         return $output;
1416     }
1417 }
1418
1419 class boolean_define_optional
1420 extends boolean_define {
1421     function _config_format($value) {
1422         $name = $this->get_config_item_name();
1423         return sprintf("if (!defined('%s')) define('%s', '%s');", $name, $name, $value);
1424     }
1425 }
1426
1427 class boolean_define_commented
1428 extends boolean_define {
1429     function _get_config_line($posted_value) {
1430         if ($this->description)
1431             $n = "\n";
1432         list($default_value, $label) = each($this->default_value);
1433         if ($posted_value == $default_value)
1434             return "${n}//" . $this->_config_format($posted_value);
1435         else if ($posted_value == '')
1436             return "${n}//" . $this->_config_format('false');
1437         else
1438             return "${n}" . $this->_config_format($posted_value);
1439     }
1440 }
1441
1442 class boolean_define_commented_optional
1443 extends boolean_define_commented {
1444     function _config_format($value) {
1445         $name = $this->get_config_item_name();
1446         return sprintf("if (!defined('%s')) define('%s', '%s');", $name, $name, $value);
1447     }
1448 }
1449
1450 class part
1451 extends _variable {
1452     function value () { return; }
1453     function get_config($posted_value) {
1454         $d = stripHtml($this->_get_description());
1455         global $SEPARATOR;
1456         return "\n".$SEPARATOR . str_replace("\n", "\n// ", $d) ."\n$this->default_value";
1457     }
1458     function get_instructions($title) {
1459         $group_name = preg_replace("/\W/","",$title);
1460         $i = "<tr>\n<td class=\"part\" width=\"100%\" colspan=\"2\" bgcolor=\"#eeaaaa\">\n";
1461         if ($group_name == 'PartZero') $i = "</dl>" . $i;
1462         $i .= "<p><b><h2>" . $title . "</h2></b></p>\n    " . nl2p($this->_get_description()) ."\n";
1463         $i .= "<input id=\"{$group_name}_input\" type=\"hidden\" name=\"$group_name\" value=\"0\" />";
1464         $i .= "<p><a href=\"javascript:toggle_group('$group_name')\" id=\"{$group_name}_text\">Show options.</a></p>";
1465         return  $i ."</td></tr>\n" . "<dl id=\"$group_name\" style=\"display: none\">";
1466     }
1467     function get_html() {
1468         return "";
1469     }
1470 }
1471
1472 // html utility functions
1473 function nl2p($text) {
1474     return "<p>" . str_replace("\n\n", "</p>\n<p>", $text) . "</p>";
1475 }
1476
1477 function stripHtml($text) {
1478         $d = str_replace("<pre>", "", $text);
1479         $d = str_replace("</pre>", "", $d);
1480         $d = str_replace("<dl>", "", $d);
1481         $d = str_replace("</dl>", "", $d);
1482         $d = str_replace("<dt>", "", $d);
1483         $d = str_replace("</dt>", "", $d);
1484         $d = str_replace("<dd>", "", $d);
1485         $d = str_replace("</dd>", "", $d);
1486         //restore html entities into characters
1487         // http://www.php.net/manual/en/function.htmlentities.php
1488         $trans = get_html_translation_table (HTML_ENTITIES);
1489         $trans = array_flip ($trans);
1490         $d = strtr($d, $trans);
1491         return $d;
1492 }
1493
1494 /**
1495  * Seed the random number generator.
1496  *
1497  * better_srand() ensures the randomizer is seeded only once.
1498  * 
1499  * How random do you want it? See:
1500  * http://www.php.net/manual/en/function.srand.php
1501  * http://www.php.net/manual/en/function.mt-srand.php
1502  */
1503 function better_srand($seed = '') {
1504     static $wascalled = FALSE;
1505     if (!$wascalled) {
1506         if ($seed === '') {
1507             list($usec,$sec)=explode(" ",microtime());
1508             if ($usec > 0.1) 
1509                 $seed = (double) $usec * $sec;
1510             else // once in a while use the combined LCG entropy
1511                 $seed = (double) 1000000 * substr(uniqid("",true),13);
1512         }
1513         if (function_exists('mt_srand')) {
1514             mt_srand($seed); // mersenne twister
1515         } else {
1516             srand($seed);    
1517         }
1518         $wascalled = TRUE;
1519     }
1520 }
1521
1522 function rand_ascii($length = 1) {
1523     better_srand();
1524     $s = "";
1525     for ($i = 1; $i <= $length; $i++) {
1526         // return only typeable 7 bit ascii, avoid quotes
1527         if (function_exists('mt_rand'))
1528             // the usually bad glibc srand()
1529             $s .= chr(mt_rand(40, 126)); 
1530         else
1531             $s .= chr(rand(40, 126));
1532     }
1533     return $s;
1534 }
1535
1536 ////
1537 // Function to create better user passwords (much larger keyspace),
1538 // suitable for user passwords.
1539 // Sequence of random ASCII numbers, letters and some special chars.
1540 // Note: There exist other algorithms for easy-to-remember passwords.
1541 function random_good_password ($minlength = 5, $maxlength = 8) {
1542   $newpass = '';
1543   // assume ASCII ordering (not valid on EBCDIC systems!)
1544   $valid_chars = "!#%&+-.0123456789=@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz";
1545   $start = ord($valid_chars);
1546   $end   = ord(substr($valid_chars,-1));
1547   better_srand();
1548   if (function_exists('mt_rand')) // mersenne twister
1549       $length = mt_rand($minlength, $maxlength);
1550   else  // the usually bad glibc rand()
1551       $length = rand($minlength, $maxlength);
1552   while ($length > 0) {
1553       if (function_exists('mt_rand'))
1554           $newchar = mt_rand($start, $end);
1555       else
1556           $newchar = rand($start, $end);
1557       if (! strrpos($valid_chars,$newchar) ) continue; // skip holes
1558       $newpass .= sprintf("%c",$newchar);
1559       $length--;
1560   }
1561   return($newpass);
1562 }
1563
1564 // debugging
1565 function printArray($a) {
1566     echo "<hr />\n<pre>\n";
1567     print_r($a);
1568     echo "\n</pre>\n<hr />\n";
1569 }
1570
1571 // end of class definitions
1572 /////////////////////////////
1573 // begin auto generation code
1574
1575 if ($HTTP_POST_VARS['action'] == 'make_config') {
1576
1577     $timestamp = date ('dS of F, Y H:i:s');
1578
1579     $config = "<?php
1580 /* This is a local configuration file for PhpWiki.
1581  * It was automatically generated by the configurator script
1582  * on the $timestamp.
1583  */
1584
1585 /*$copyright*/
1586
1587 /////////////////////////////////////////////////////////////////////
1588 /*$preamble*/
1589 ";
1590
1591     $posted = $GLOBALS['HTTP_POST_VARS'];
1592
1593     if (defined('DEBUG'))
1594         printArray($GLOBALS['HTTP_POST_VARS']);
1595
1596     foreach($properties as $option_name => $a) {
1597         $posted_value = $posted[$a->config_item_name];
1598         $config .= $properties[$option_name]->get_config($posted_value);
1599     }
1600
1601     if (defined('DEBUG')) {
1602         $diemsg = "The configurator.php is provided for testing purposes only.
1603 You can't use this file with your PhpWiki server yet!!";
1604         $config .= "\ndie(\"$diemsg\");\n";
1605     }
1606     $config .= $end;
1607
1608     /* We first check if the config-file exists. */
1609     if (file_exists($fs_config_file)) {
1610         /* We make a backup copy of the file */
1611         // $config_file = 'index-user.php';
1612         $new_filename = preg_replace('/\.php$/', time() . '.php', $fs_config_file);
1613         if (@copy($fs_config_file, $new_filename)) {
1614             $fp = @fopen($fs_config_file, 'w');
1615         }
1616     } else {
1617         $fp = @fopen($fs_config_file, 'w');
1618     }
1619
1620     if ($fp) {
1621         fputs($fp, $config);
1622         fclose($fp);
1623         echo "<p>The configuration was written to <code><b>$config_file</b></code>.</p>\n";
1624         if ($new_filename) {
1625             echo "<p>A backup was made to <code><b>$new_filename</b></code>.</p>\n";
1626         }
1627         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";
1628     } else {
1629         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";
1630     }
1631
1632     echo "<hr />\n<p>Here's the configuration file based on your answers:</p>\n<pre>\n";
1633     echo htmlentities($config);
1634     echo "</pre>\n<hr />\n";
1635
1636     echo "<p>To make any corrections, <a href=\"configurator.php\">edit the settings again</a>.</p>\n";
1637
1638 } else { // first time or create password
1639     $posted = $GLOBALS['HTTP_POST_VARS'];
1640     /* No action has been specified - we make a form. */
1641
1642     echo '
1643 <form action="configurator.php" method="POST">
1644 <table cellpadding="4" cellspacing="0">
1645   <input type="hidden" name="action" value="make_config">
1646 ';
1647
1648     while(list($property, $obj) = each($properties)) {
1649         echo $obj->get_instructions($property);
1650         if ($h = $obj->get_html()) {
1651             if (defined('DEBUG'))  $h = get_class($obj) . "<br />\n" . $h;
1652             echo "<td>".$h."</td>\n";
1653         }
1654         echo '</tr>';
1655     }
1656
1657     echo '
1658 </dl></table>
1659 <p><input type="submit" value="Save ',$config_file,'"> <input type="reset" value="Clear"></p>
1660 </form>
1661 ';
1662 }
1663 ?>
1664 </body>
1665 </html>