1 <?php // $Id: configurator.php,v 1.32 2005-03-06 11:05:45 rurban Exp $
3 * Copyright 2002,2003,2005 $ThePhpWikiProgrammingTeam
4 * Copyright 2002 Martin Geisler <gimpster@gimpster.com>
6 * This file is part of PhpWiki.
7 * Parts of this file were based on PHPWeather's configurator.php file.
8 * http://sourceforge.net/projects/phpweather/
10 * PhpWiki is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * PhpWiki is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with PhpWiki; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 * Starts automatically the first time by IniConfig("config/config.ini")
27 * if it doesn't exist.
30 * o Initial expand ?show=_part1 (the part id)
31 * o read config-default.ini and use this as default_values
32 * o commented / optional: non-default values should not be commented!
33 * default values if optional can be omitted.
34 * o validate input (fix javascript, add POST checks)
35 * o start this automatically the first time
38 * 1.3.11 TODO: (or 1.3.12?)
39 * o fix SQL quotes, AUTH_ORDER quotes and file forward slashes
40 * o posted values validation, extend js validation for sane DB values
41 * o read config-dist.ini into sections, comments, and optional/required settings
43 * A file config/config.ini will be automatically generated, if writable.
45 * NOTE: If you have a starterscript outside PHOWIKI_DIR but no
46 * config/config.ini yet (very unlikely!), you must define DATA_PATH in the
47 * starterscript, otherwise the webpath to configurator is unknown, and
48 * subsequent requests will fail. (POST to save the INI)
51 global $HTTP_SERVER_VARS, $HTTP_POST_VARS, $tdwidth;
52 if (empty($_GET)) $_GET =& $GLOBALS['HTTP_GET_VARS'];
53 if (empty($_ENV)) $_ENV =& $GLOBALS['HTTP_ENV_VARS'];
55 if (empty($configurator))
56 $configurator = "configurator.php";
57 if (!strstr($HTTP_SERVER_VARS["SCRIPT_NAME"], $configurator) and defined('DATA_PATH'))
58 $configurator = DATA_PATH . "/" . $configurator;
59 $scriptname = str_replace('configurator.php', 'index.php', $HTTP_SERVER_VARS["SCRIPT_NAME"]);
62 $config_file = (substr(PHP_OS,0,3) == 'WIN') ? 'config\\config.ini' : 'config/config.ini';
63 $fs_config_file = dirname(__FILE__) . (substr(PHP_OS,0,3) == 'WIN' ? '\\' : '/') . $config_file;
64 if (isset($HTTP_POST_VARS['create'])) header('Location: '.$configurator.'?create=1#create');
66 // helpers from lib/WikiUser/HttpAuth.php
67 function _http_user() {
69 $_SERVER = $GLOBALS['HTTP_SERVER_VARS'];
70 if (!empty($_SERVER['PHP_AUTH_USER']))
71 return array($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']);
72 if (!empty($_SERVER['REMOTE_USER']))
73 return array($_SERVER['REMOTE_USER'], $_SERVER['PHP_AUTH_PW']);
74 if (!empty($GLOBALS['HTTP_ENV_VARS']['REMOTE_USER']))
75 return array($GLOBALS['HTTP_ENV_VARS']['REMOTE_USER'],
76 $GLOBALS['HTTP_ENV_VARS']['PHP_AUTH_PW']);
77 if (!empty($GLOBALS['REMOTE_USER']))
78 return array($GLOBALS['REMOTE_USER'], $GLOBALS['PHP_AUTH_PW']);
81 if (!empty($_SERVER['HTTP_AUTHORIZATION'])) {
82 list($userid, $passwd) = explode(':', base64_decode(substr($_SERVER['HTTP_AUTHORIZATION'], 6)));
83 return array($userid, $passwd);
87 function _http_logout() {
89 $_SERVER =& $GLOBALS['HTTP_SERVER_VARS'];
90 // maybe we should random the realm to really force a logout. but the next login will fail.
91 // better_srand(); $realm = microtime().rand();
92 header('WWW-Authenticate: Basic realm="'.WIKI_NAME.'"');
93 if (strstr(php_sapi_name(), 'apache'))
94 header('HTTP/1.0 401 Unauthorized');
96 header("Status: 401 Access Denied"); //IIS and CGI need that
97 unset($GLOBALS['REMOTE_USER']);
98 unset($_SERVER['PHP_AUTH_USER']);
99 unset($_SERVER['PHP_AUTH_PW']);
101 trigger_error("Permission denied. Require ADMIN_USER.", E_USER_ERROR);
106 // If config.ini exists, we require ADMIN_USER access by faking HttpAuth.
107 // So nobody can see or reset the password(s).
108 if (file_exists($fs_config_file)) {
109 // Require admin user
110 if (!defined('ADMIN_USER') or !defined('ADMIN_PASSWD')) {
111 if (!function_exists("IniConfig")) {
112 include_once("lib/prepend.php");
113 include_once("lib/IniConfig.php");
115 IniConfig($fs_config_file);
117 if (!defined('ADMIN_USER') or ADMIN_USER == '') {
118 trigger_error("Configuration problem:\nADMIN_USER not defined in \"$fs_config_file\".\n"
119 . "Cannot continue: You have to fix that manually.", E_USER_ERROR);
123 list($admin_user, $admin_pw) = _http_user();
124 //$required_user = ADMIN_USER;
125 if (empty($admin_user) or $admin_user != ADMIN_USER)
130 if (ENCRYPTED_PASSWORD and function_exists('crypt')) {
131 if (crypt($admin_pw, ADMIN_PASSWD) != ADMIN_PASSWD)
133 } elseif ($admin_pw != ADMIN_PASSWD) {
137 if (!function_exists("IniConfig")) {
138 include_once("lib/prepend.php");
139 include_once("lib/IniConfig.php");
141 $def_file = (substr(PHP_OS,0,3) == 'WIN') ? 'config\\config-default.ini' : 'config/config-default.ini';
142 $fs_def_file = dirname(__FILE__) . (substr(PHP_OS,0,3) == 'WIN' ? '\\' : '/') . $def_file;
143 IniConfig($fs_def_file);
146 echo "<","?xml version=\"1.0\" encoding=\"'iso-8859-1'\"?",">\n";
148 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
149 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
150 <html xmlns="http://www.w3.org/1999/xhtml">
152 <!-- $Id: configurator.php,v 1.32 2005-03-06 11:05:45 rurban Exp $ -->
153 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
154 <title>Configuration tool for PhpWiki <?php echo $config_file ?></title>
155 <style type="text/css" media="screen">
157 /* TABLE { border: thin solid black } */
158 body { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 80%; }
159 pre { font-size: 120%; }
160 td { border: thin solid black }
162 div.hint { border: thin solid red, background-color: #eeeeee; }
163 tr.hidden { border: none; display: none; }
164 td.part { background-color: #eeeeee; color: inherit; }
165 td.instructions { background-color: #ffffee; width: <?php echo $tdwidth ?>px; color: inherit; }
166 td.unchangeable-variable-top { border-bottom: none; background-color: #ffffee; color:inherit; }
167 td.unchangeable-variable-left { border-top: none; background-color: #ffffee; color:inherit; }
170 <script language="JavaScript" type="text/javascript">
172 function update(accepted, error, value, output) {
173 var msg = document.getElementById(output);
175 /* MSIE 5.0 fails here */
176 if (msg && msg.innerHTML) { msg.innerHTML = "<font color=\"green\">Input accepted.</font>"; }
178 while ((index = error.indexOf("%s")) > -1) {
179 error = error.substring(0, index) + value + error.substring(index+2);
181 if (msg) { msg.innerHTML = "<font color=\"red\">" + error + "</font>"; }
183 if (submit = document.getElementById('submit')) submit.disabled = accepted ? false : true;
186 function validate(error, value, output, field) {
187 update(field.value == value, error, field.value, output);
190 function validate_ereg(error, ereg, output, field) {
191 regex = new RegExp(ereg);
192 update(regex.test(field.value), error, field.value, output);
195 function validate_range(error, low, high, empty_ok, output, field) {
196 update((empty_ok == 1 && field.value == "") ||
197 (field.value >= low && field.value <= high),
198 error, field.value, output);
201 function toggle_group(id) {
202 var text = document.getElementById(id + "_text");
204 if (text.innerHTML == "Hide options.") {
206 text.innerHTML = "Show options.";
208 text.innerHTML = "Hide options.";
211 var rows = document.getElementsByTagName('tr');
213 for (i = 0; i < rows.length; i++) {
215 if (tr.className == 'header' && tr.id == id) {
220 for (; i < rows.length; i++) {
222 if (tr.className == 'header')
224 tr.className = do_hide ? 'hidden': 'nonhidden';
229 // Hide all groups. We do this via JavaScript to avoid
230 // hiding the groups if JavaScript is not supported...
231 var rows = document.getElementsByTagName('tr');
232 var show = '<?php echo $_GET["show"] ?>';
233 for (var i = 0; i < rows.length; i++) {
235 if (tr.className == 'header')
236 if (!show || tr.id != show)
240 // Select text in textarea upon focus
241 var area = document.getElementById('config-output');
243 listener = { handleEvent: function (e) { area.select(); } };
244 area.addEventListener('focus', listener, false);
251 <body onload="do_init();">
253 <h1>Configuration for PhpWiki <?php echo $config_file ?></h1>
256 Using this configurator.php is experimental!<br>
257 On any configuration problems, please edit the resulting config.ini manually.
261 //define('DEBUG', 1);
263 * The Configurator is a php script to aid in the configuration of PhpWiki.
264 * Parts of this file were based on PHPWeather's configurator.php file.
265 * http://sourceforge.net/projects/phpweather/
267 * TO CHANGE THE CONFIGURATION OF YOUR PHPWIKI, DO *NOT* MODIFY THIS FILE!
268 * more instructions go here
272 * * eval config.ini to get the actual settings.
275 //////////////////////////////
276 // begin configuration options
279 * Notes for the description parameter of $property:
281 * - Descriptive text will be changed into comments (preceeded by ; )
282 * for the final output to config.ini.
284 * - Only a limited set of html is allowed: pre, dl dt dd; it will be
285 * stripped from the final output.
287 * - Line breaks and spacing will be preserved for the final output.
289 * - Double line breaks are automatically converted to paragraphs
290 * for the html version of the descriptive text.
292 * - Double-quotes and dollar signs in the descriptive text must be
293 * escaped: \" and \$. Instead of escaping double-quotes you can use
294 * single (') quotes for the enclosing quotes.
296 * - Special characters like < and > must use html entities,
297 * they will be converted back to characters for the final output.
300 $SEPARATOR = ";=========================================================================";
303 ; This is the main configuration file for PhpWiki in INI-style format.
304 ; Note that certain characters are used as comment char and therefore
305 ; these entries must be in double-quotes. Such as \":\", \";\", \",\" and \"|\"
306 ; Take special care for DBAUTH_ sql statements. (Part 3a)
308 ; This file is divided into several parts: Each one has different configuration
309 ; settings you can change; in all cases the default should work on your system,
310 ; however, we recommend you tailor things to your particular setting.
313 $properties["Part Zero"] =
314 new part('_part0', $SEPARATOR."\n", "
315 Part Zero: (optional)
316 Latest Development and Tricky Options");
318 if (defined('INCLUDE_PATH'))
319 $include_path = INCLUDE_PATH;
321 if (substr(PHP_OS,0,3) == 'WIN') {
322 $include_path = dirname(__FILE__) . ';' . ini_get('include_path');
323 if (strchr(ini_get('include_path'),'/'))
324 $include_path = strtr($include_path,'\\','/');
326 $include_path = dirname(__FILE__) . ':' . ini_get('include_path');
330 $properties["PHP include_path"] =
331 new _define('INCLUDE_PATH', $include_path, "
332 If PHP needs help in finding where you installed the rest of the PhpWiki
333 code, you can set the include_path here.
335 Override the PHP include path so that it can find some needed additional libraries.
336 You shouldn't need to do this unless your system include_path esp. your
337 system pear libs are broken or oudated. The PHPWIKI_DIR is automatically
338 put to the front and the local lib/pear path is automatically added to the end.
339 But if you define it, be sure to include either the system pear path or
340 the phpwiki/lib/pear path to override your Pear_DB.
341 Note that on Windows-based servers, you should use ; rather than :
342 as the path separator.");
344 // TODO: convert this a checkbox row as in tests/unit/test.pgp
345 $properties["DEBUG"] =
346 new numeric_define_optional('DEBUG', DEBUG, "
347 Set DEBUG to 1 to view the XHTML and CSS validator icons, page
348 processing timer, and possibly other debugging messages at the
349 bottom of each page. 65 for a more verbose level with AUTH hints.
350 See lib/config.php for all supported values.");
352 // TODO: bring the default to the front
353 $properties["ENABLE_USER_NEW"] =
354 new boolean_define_commented_optional
356 array('true' => "Enabled",
357 'false' => "Disabled."), "
358 Enable the new method of handling WikiUser Authetincation and Preferences.
359 It's best to leave it on, and only disable it if you have problems with it.
360 Servers with memory-limit problems might want to turn it off. It costs ~300KB
363 $properties["ENABLE_PAGEPERM"] =
364 new boolean_define_commented_optional
366 array('true' => "Enabled",
367 'false' => "Disabled."), "
368 Use access control lists (as in Solaris and Windows NTFS) per page and group,
369 not per user for the whole wiki.
371 I suspect ACL page permissions to degrade speed by 10%.
372 GROUP_METHOD=WIKIPAGE is slowest. (See Part 3a)
375 $properties["ENABLE_EDIT_TOOLBAR"] =
376 new boolean_define_commented_optional
377 ('ENABLE_EDIT_TOOLBAR',
378 array('true' => "Enabled",
379 'false' => "Disabled."), "
380 Graphical buttons on edit. Default: true.
381 Reportedly broken on MacOSX Safari");
383 $properties["JS_SEARCHREPLACE"] =
384 new boolean_define_commented_optional
386 array('true' => "Enabled",
387 'false' => "Disabled"), "
388 Adds two additional buttons in EDIT_TOOLBAR, Search&Replace and Undo.
389 Undo is experimental.");
391 $properties["ENABLE_DOUBLECLICKEDIT"] =
392 new boolean_define_commented_optional
393 ('ENABLE_DOUBLECLICKEDIT',
394 array('true' => "Enabled",
395 'false' => "Disabled"), "
398 $properties["ENABLE_XHTML_XML"] =
399 new boolean_define_commented_optional
401 array('false' => "Disabled",
402 'true' => "Enabled"), "
403 Needed for inlined SVG and MathM, but may conflict with javascript:document.write().
404 Experimental. Default: false");
406 $properties["USECACHE"] =
407 new boolean_define_commented_optional
409 array('true' => "Enabled",
410 'false' => "Disabled"), "
411 Store DB query results in memory to avoid duplicate queries.
412 Disable only for old php's with low memory or memory_limit=8MB.
415 $properties["ENABLE_SPAMASSASSIN"] =
416 new boolean_define_commented_optional
417 ('ENABLE_SPAMASSASSIN',
418 array('true' => "Enabled",
419 'false' => "Disabled"), "
420 Needs babycart installed. See http://phpwiki.org/SpamAssassinIntegration
421 Optionally define BABYCART_PATH. Default: /usr/local/bin/babycart");
423 $properties["GOOGLE_LINKS_NOFOLLOW"] =
424 new boolean_define_commented_optional
425 ('GOOGLE_LINKS_NOFOLLOW',
426 array('true' => "Enabled",
427 'false' => "Disabled"), "
428 If enabled ref=nofollow is added to all external links to discourage spam.
429 You might want to turn it off, if you want to improve pageranks on external links.");
431 $properties["ENABLE_LIVESEARCH"] =
432 new boolean_define_commented_optional
433 ('ENABLE_LIVESEARCH',
434 array('true' => "Enabled",
435 'false' => "Disabled"), "
436 LiveSearch enables immediate title search results via XMLHttpRequest.
437 Displays the results in a dropdown under the titlesearch inputbox
438 while typing. (experimental, only with certain themes)
439 You'll have to copy livesearch.js from http://blog.bitflux.ch/wiki/LiveSearch
440 to themes/default/ and define ENABLE_LIVESEARCH in config.ini to true.
441 See themes/blog/themeinfo.php.
442 Currently we use the bitflux.ch library, but we will change to
443 the russian acdropdown soon. http://momche.net/publish/article.php?page=acdropdown");
445 $properties["USE_SAFE_DBSESSION"] =
446 new boolean_define_commented_optional
447 ('USE_SAFE_DBSESSION',
448 array('false' => "Disabled",
449 'true' => "Enabled"), "
450 USE_SAFE_DBSESSION should be enabled, if you encounter session problems, with duplicate INSERT
451 sess_id warnings at the bottom of the page. Reason is a unreliable affected_rows implementation()
452 in the sql backend. Default is Disabled, using the fastest DbSession UPDATE method.");
454 $properties["Part One"] =
455 new part('_part1', $SEPARATOR."\n", "
456 Part One: Authentication and security settings. See Part Three for more.");
458 $properties["Admin Username"] =
459 new _define_notempty('ADMIN_USER', ADMIN_USER, "
460 You must set this! Username and password of the administrator.",
461 "onchange=\"validate_ereg('Sorry, ADMIN_USER cannot be empty.', '^.+$', 'ADMIN_USER', this);\"");
463 $properties["Admin Password"] =
464 new _define_password('ADMIN_PASSWD', ADMIN_PASSWD, "
465 For heaven's sake pick a good password.
466 If your version of PHP supports encrypted passwords, your password will be
467 automatically encrypted within the generated config file.
468 Use the \"Create Random Password\" button to create a good (random) password.
470 ADMIN_PASSWD is ignored on HttpAuth",
471 "onchange=\"validate_ereg('Sorry, ADMIN_PASSWD must be at least 4 chars long.', '^....+$', 'ADMIN_PASSWD', this);\"");
473 $properties["Encrypted Passwords"] =
476 array('true' => "true. use crypt for all passwords",
477 'false' => "false. use plaintest passwords (not recommended)"), "
478 It is recommended that you use encrypted passwords to be stored in the
479 config.ini and the users homepages metadata.
480 You might want to use the passencrypt.php utility to encode the
481 admin password, in the event that someone gains ftp or ssh access to the
482 server and directory containing phpwiki.
483 <i>SQL access passwords cannot be encrypted, besides using external DATABASE_DSN aliases within PDO.</i>
485 If true, all user passwords will be stored encrypted.
486 You might have to set it to false, if your PHP doesn't support crypt().
489 $properties["Wiki Name"] =
490 new _define_optional('WIKI_NAME', WIKI_NAME, "
491 The name of your wiki.
493 This is used to generate a keywords meta tag in the HTML templates,
494 in bookmark titles for any bookmarks made to pages in your wiki,
495 and during RSS generation for the title of the RSS channel.
497 It is recommended this be a relatively short WikiWord like the
498 InterWiki monikers found in the InterWikiMap. (For examples, see
502 $properties["Reverse DNS"] =
503 new boolean_define_optional
504 ('ENABLE_REVERSE_DNS',
505 array('true' => "true. perform additional reverse dns lookups",
506 'false' => "false. just record the address as given by the httpd server"),
508 If set, we will perform reverse dns lookups to try to convert the
509 users IP number to a host name, even if the http server didn't do it for us.");
511 $properties["ZIPdump Authentication"] =
512 new boolean_define_optional('ZIPDUMP_AUTH',
513 array('false' => "false. Everyone may download zip dumps",
514 'true' => "true. Only admin may download zip dumps"), "
515 If true, only the admin user can make zip dumps, else zip dumps
516 require no authentication.");
518 $properties["Enable RawHtml Plugin"] =
519 new boolean_define_commented_optional
521 array('true' => "Enabled",
522 'false' => "Disabled"), "
523 The RawHtml plugin allows page authors to embed real, raw HTML into Wiki
524 pages. This is a possible security threat, as much HTML (or, rather,
525 JavaScript) can be very risky. If you are in a controlled environment,
526 however, it could be of use.");
528 $properties["Allow RawHtml Plugin only on locked pages"] =
529 new boolean_define_commented_optional
530 ('ENABLE_RAW_HTML_LOCKEDONLY',
531 array('true' => "Enabled",
532 'false' => "Disabled"), "
533 If this is set, only pages locked by the Administrator may contain the RawHtml plugin.");
535 $properties["Allow RawHtml Plugin if safe HTML code"] =
536 new boolean_define_commented_optional
537 ('ENABLE_RAW_HTML_SAFE',
538 array('true' => "Enabled",
539 'false' => "Disabled"), "
540 If this is set, all unsafe html code is stripped automatically (experimental!)
541 See <a href=\"http://chxo.com/scripts/safe_html-test.php\" target=\"_new\">chxo.com/scripts/safe_html-test.php</a>
544 $properties["Maximum Upload Size"] =
545 new numeric_define_optional('MAX_UPLOAD_SIZE', MAX_UPLOAD_SIZE /*"16 * 1024 * 1024"*/, "
546 The maximum file upload size.");
548 $properties["Minor Edit Timeout"] =
549 new numeric_define_optional('MINOR_EDIT_TIMEOUT', MINOR_EDIT_TIMEOUT /*"7 * 24 * 3600"*/, "
550 If the last edit is older than MINOR_EDIT_TIMEOUT seconds, the
551 default state for the \"minor edit\" checkbox on the edit page form
554 $properties["Disabled Actions"] =
555 new array_define('DISABLED_ACTIONS', DISABLED_ACTIONS /*array()*/, "
556 Actions listed in this array will not be allowed. Actions are:
557 browse, create, diff, dumphtml, dumpserial, edit, loadfile, lock, remove,
558 unlock, upload, viewsource, zip, ziphtml");
560 $properties["Access Log File"] =
561 new _define_commented_optional('ACCESS_LOG', ACCESS_LOG /*"/var/logs/wiki_access.log"*/, "
562 PhpWiki can generate an access_log (in \"NCSA combined log\" format)
563 for you. If you want one, define this to the name of the log file,
564 such as /tmp/wiki_access_log. Preferred is to use SQL access logging as below.
566 Default: empty - no access log file will be generated.");
568 $properties["Access Log SQL"] =
569 new _define_selection(
571 array('0' => 'disable',
573 '2' => 'read + write'), "
574 PhpWiki can read and/or write apache-style mod_log_sql accesslog tables for faster
575 abuse detection and referer lists.
576 See http://www.outoforder.cc/projects/apache/mod_log_sql/docs-2.0/#id2756178
578 If defined (e.g. 1) only read-access is done via SQL.
579 If flag 2 is set, phpwiki also writes. (Default on SQL or ADODB)
580 This must use DATABASE_TYPE = SQL or ADODB.
583 $properties["Compress Output"] =
584 new boolean_define_commented_optional
586 array('' => 'GZIP compress when PhpWiki thinks appropriate.',
587 'false' => 'Never compress output.',
588 'true' => 'Always try to compress output.'),
590 By default PhpWiki will try to have PHP compress it's output
591 before sending it to the browser (if you have a recent enough
592 version of PHP and the action and the browser supports it.)
594 Define COMPRESS_OUTPUT to false to prevent output compression at all.
596 Define COMPRESS_OUTPUT to true to force output compression,
597 even if we think your version of PHP does this in a buggy
600 Leave it undefined to leave the choice up to PhpWiki.");
602 $properties["HTTP Cache Control"] =
603 new _define_selection_optional
605 array('LOOSE' => 'LOOSE',
606 'STRICT' => 'STRICT',
607 'NO_CACHE' => 'NO_CACHE',
608 'ALLOW_STALE' => 'ALLOW_STALE'),
612 This controls how PhpWiki sets the HTTP cache control
613 headers (Expires: and Cache-Control:)
619 <dd>This is roughly the old (pre 1.3.4) behaviour. PhpWiki will
620 instruct proxies and browsers never to cache PhpWiki output.</dd>
623 <dd>Cached pages will be invalidated whenever the database global
624 timestamp changes. This should behave just like NONE (modulo
625 bugs in PhpWiki and your proxies and browsers), except that
626 things will be slightly more efficient.</dd>
629 <dd>Cached pages will be invalidated whenever they are edited,
630 or, if the pages include plugins, when the plugin output could
631 concievably have changed.
633 <p>Behavior should be much like STRICT, except that sometimes
634 wikilinks will show up as undefined (with the question mark)
635 when in fact they refer to (recently) created pages.
636 (Hitting your browsers reload or perhaps shift-reload button
637 should fix the problem.)</p></dd>
640 <dd>Proxies and browsers will be allowed to used stale pages.
641 (The timeout for stale pages is controlled by CACHE_CONTROL_MAX_AGE.)
643 <p>This setting will result in quirky behavior. When you edit a
644 page your changes may not show up until you shift-reload the
647 <p>This setting is generally not advisable, however it may be useful
648 in certain cases (e.g. if your wiki gets lots of page views,
649 and few edits by knowledgable people who won't freak over the quirks.)</p>
652 The default is currently LOOSE.");
654 // FIXME: should be numeric_define_optional
655 $properties["HTTP Cache Control Max Age"] =
656 new numeric_define_optional('CACHE_CONTROL_MAX_AGE', CACHE_CONTROL_MAX_AGE,
658 Maximum page staleness, in seconds.");
660 $properties["Markup Caching"] =
661 new boolean_define_commented_optional
662 ('WIKIDB_NOCACHE_MARKUP',
663 array('false' => 'Enable markup cache',
664 'true' => 'Disable markup cache'),
668 PhpWiki normally caches a preparsed version (i.e. mostly
669 converted to HTML) of the most recent version of each page.
670 (Parsing the wiki-markup takes a fair amount of CPU.)
672 Define WIKIDB_NOCACHE_MARKUP to true to disable the
673 caching of marked-up page content.
675 Note that you can also disable markup caching on a per-page
676 temporary basis by addinging a query arg of '?nocache=1'
677 to the URL to the page. (Use '?nocache=purge' to completely
678 discard the cached version of the page.)
680 You can also purge the cached markup globally by using the
681 \"Purge Markup Cache\" button on the PhpWikiAdministration page.");
683 $properties["Path for PHP Session Support"] =
684 new _define_optional('SESSION_SAVE_PATH', defined('SESSION_SAVE_PATH') ? SESSION_SAVE_PATH : ini_get('session.save_path'), "
685 The login code now uses PHP session support. Usually, the default
686 configuration of PHP is to store the session state information in
687 /tmp. That probably will work fine, but fails e.g. on clustered
688 servers where each server has their own distinct /tmp (this is the
689 case on SourceForge's project web server.) You can specify an
690 alternate directory in which to store state information like so
691 (whatever user your httpd runs as must have read/write permission
694 On USE_DB_SESSION = true you can ignore this.
697 ///////// database selection
699 $properties["Part Two"] =
700 new part('_part2', $SEPARATOR."\n", "
703 Database Configuration
706 $properties["Database Type"] =
707 new _define_selection("DATABASE_TYPE",
708 array('dba' => "dba",
710 'ADODB' => "SQL ADODB",
711 'PDO' => "PDO (php5 only)",
712 'file' => "flatfile",
713 'cvs' => "CVS File handler"), "
714 Select the database backend type:
715 Choose dba (default) to use one of the standard UNIX dba libraries. This is the fastest.
716 Choose ADODB or SQL to use an SQL database with ADODB or PEAR.
717 Choose PDO on php5 to use an SQL database.
718 flatfile is simple and slow.
719 CVS is highly experimental and slow.
720 Recommended is dba or SQL: PEAR or ADODB.");
722 $properties["SQL DSN Setup"] =
723 new unchangeable_variable('_sqldsnstuff', "", "
724 For SQL based backends, specify the database as a DSN
725 The most general form of a DSN looks like:
727 phptype(dbsyntax)://username:password@protocol+hostspec/database?option=value
729 For a MySQL database, the following should work:
731 mysql://user:password@host/databasename
733 To connect over a unix socket, use something like
735 mysql://user:password@unix(/path/to/socket)/databasename
738 DATABASE_DSN = mysql://guest@:/var/lib/mysql/mysql.sock/phpwiki
739 DATABASE_DSN = mysql://guest@localhost/phpwiki
740 DATABASE_DSN = pgsql://localhost/user_phpwiki
743 // Choose ADODB or SQL to use an SQL database with ADODB or PEAR.
744 // Choose dba to use one of the standard UNIX dbm libraries.
746 $properties["SQL Type"] =
747 new _variable_selection('_dsn_sqltype',
748 array('mysql' => "MySQL",
749 'pgsql' => "PostgreSQL",
750 'mssql' => "Microsoft SQL Server",
751 'oci8' => "Oracle 8",
752 'mysqli' => "mysqli (only ADODB)",
753 'mysqlt' => "mysqlt (only ADODB)",
754 'ODBC' => "ODBC (only ADODB or PDO)",
755 'firebird' => "Firebird (only PDO)",
756 'oracle' => "Oracle (only PDO)",
758 SQL DB types. The DSN hosttype.");
760 $properties["SQL User"] =
761 new _variable('_dsn_sqluser', "wikiuser", "
764 $properties["SQL Password"] =
765 new _variable('_dsn_sqlpass', "", "
768 $properties["SQL Database Host"] =
769 new _variable('_dsn_sqlhostorsock', "localhost", "
770 SQL Database Hostname:
772 To connect over a local named socket, use something like
774 unix(/var/lib/mysql/mysql.sock)
777 mysql on Windows via named pipes might need 127.0.0.1");
779 $properties["SQL Database Name"] =
780 new _variable('_dsn_sqldbname', "phpwiki", "
781 SQL Database Name:");
783 $dsn_sqltype = $properties["SQL Type"]->value();
784 $dsn_sqluser = $properties["SQL User"]->value();
785 $dsn_sqlpass = $properties["SQL Password"]->value();
786 $dsn_sqlhostorsock = $properties["SQL Database Host"]->value();
787 $dsn_sqldbname = $properties["SQL Database Name"]->value();
788 $dsn_sqlstring = $dsn_sqltype."://{$dsn_sqluser}:{$dsn_sqlpass}@{$dsn_sqlhostorsock}/{$dsn_sqldbname}";
790 $properties["SQL dsn"] =
791 new unchangeable_define("DATABASE_DSN",
792 "DATABASE_DSN = \"$dsn_sqlstring\"", "
793 Calculated from the settings above:");
795 $properties["Filename / Table name Prefix"] =
796 new _define_commented("DATABASE_PREFIX", DATABASE_PREFIX, "
797 Used by all DB types:
799 Prefix for filenames or table names, e.g. \"phpwiki_\"
801 Currently <b>you MUST EDIT THE SQL file too!</b> (in the schemas/
802 directory because we aren't doing on the fly sql generation
803 during the installation.");
805 $properties["DB Session table"] =
806 new _define_optional("DATABASE_SESSION_TABLE", DATABASE_SESSION_TABLE, "
807 Tablename to store session information. Only supported by SQL backends.
809 A word of warning - any prefix defined above will be prepended to whatever is given here.
813 $temp = !empty($_ENV['TEMP']) ? $_ENV['TEMP'] : "/tmp";
814 $properties["dba directory"] =
815 new _define("DATABASE_DIRECTORY", $temp, "
818 // TODO: list the available methods
819 $properties["dba handler"] =
820 new _define_selection('DATABASE_DBA_HANDLER',
821 array('gdbm' => "Gdbm - GNU database manager (recommended)",
822 'dbm' => "DBM - Redhat default. On sf.net there's dbm and gdbm",
823 'db2' => "DB2 - Sleepycat Software's DB2",
824 'db3' => "DB3 - Sleepycat Software's DB3. Default on Windows but not on every Linux",
825 'db4' => "DB4 - Sleepycat Software's DB4."), "
826 Use 'gdbm', 'dbm', 'db2', 'db3' or 'db4' depending on your DBA handler methods supported: <br > "
827 . (function_exists("dba_handlers") ? join(", ",dba_handlers()) : ""));
829 $properties["dba timeout"] =
830 new numeric_define("DATABASE_TIMEOUT", DATABASE_TIMEOUT, "
831 Recommended values are 10-20 seconds. The more load the server has, the higher the timeout.");
833 $properties["DATABASE_PERSISTENT"] =
834 new boolean_define_commented_optional
835 ('DATABASE_PERSISTENT',
836 array('false' => "Disabled",
837 'true' => "Enabled"), "
838 Use persistent database connections for SQL databases, if the database backend supports it.
839 Not recommended for heavily loaded servers.
844 $properties["Page Revisions"] =
845 new unchangeable_variable('_parttworevisions', "", "
847 Section 2a: Archive Cleanup
848 The next section controls how many old revisions of each page are kept in the database.
850 There are two basic classes of revisions: major and minor. Which
851 class a revision belongs in is determined by whether the author
852 checked the \"this is a minor revision\" checkbox when they saved the
855 There is, additionally, a third class of revisions: author
856 revisions. The most recent non-mergable revision from each distinct
857 author is and author revision.
859 The expiry parameters for each of those three classes of revisions
860 can be adjusted seperately. For each class there are five
861 parameters (usually, only two or three of the five are actually
862 set) which control how long those revisions are kept in the
865 <dt>max_keep:</dt> <dd>If set, this specifies an absolute maximum for the
866 number of archived revisions of that class. This is
867 meant to be used as a safety cap when a non-zero
868 min_age is specified. It should be set relatively high,
869 and it's purpose is to prevent malicious or accidental
870 database overflow due to someone causing an
871 unreasonable number of edits in a short period of time.</dd>
873 <dt>min_age:</dt> <dd>Revisions younger than this (based upon the supplanted
874 date) will be kept unless max_keep is exceeded. The age
875 should be specified in days. It should be a
876 non-negative, real number,</dd>
878 <dt>min_keep:</dt> <dd>At least this many revisions will be kept.</dd>
880 <dt>keep:</dt> <dd>No more than this many revisions will be kept.</dd>
882 <dt>max_age:</dt> <dd>No revision older than this age will be kept.</dd>
884 Supplanted date: Revisions are timestamped at the instant that they
885 cease being the current revision. Revision age is computed using
886 this timestamp, not the edit time of the page.
888 Merging: When a minor revision is deleted, if the preceding
889 revision is by the same author, the minor revision is merged with
890 the preceding revision before it is deleted. Essentially: this
891 replaces the content (and supplanted timestamp) of the previous
892 revision with the content after the merged minor edit, the rest of
893 the page metadata for the preceding version (summary, mtime, ...)
897 // For now the expiration parameters are statically inserted as
898 // an unchangeable property. You'll have to edit the resulting
899 // config file if you really want to change these from the default.
901 $properties["Major Edits: keep minumum days"] =
902 new numeric_define("MAJOR_MIN_KEEP", MAJOR_MIN_KEEP, "
903 Default: Keep at least for unlimited time.
904 Set to 0 to enable archive cleanup");
905 $properties["Minor Edits: keep minumum days"] =
906 new numeric_define("MINOR_MIN_KEEP", MINOR_MIN_KEEP, "
907 Default: Keep at least for unlimited time.
908 Set to 0 to enable archive cleanup");
910 $properties["Major Edits: how many"] =
911 new numeric_define("MAJOR_KEEP", MAJOR_KEEP, "
912 Keep up to 8 major edits");
913 $properties["Major Edits: how many days"] =
914 new numeric_define("MAJOR_MAX_AGE", MAJOR_MAX_AGE, "
915 keep them no longer than a month");
917 $properties["Minor Edits: how many"] =
918 new numeric_define("MINOR_KEEP", MINOR_KEEP, "
919 Keep up to 4 minor edits");
920 $properties["Minor Edits: how many days"] =
921 new numeric_define("MINOR_MAX_AGE", "7", "
922 keep them no longer than a week");
924 $properties["per Author: how many"] =
925 new numeric_define("AUTHOR_KEEP", "8", "
926 Keep the latest contributions of the last 8 authors,");
927 $properties["per Author: how many days"] =
928 new numeric_define("AUTHOR_MAX_AGE", "365", "
930 $properties["per Author: keep minumum days"] =
931 new numeric_define("AUTHOR_MIN_AGE", "7", "
932 Additionally, (in the case of a particularly active page) try to
933 keep the latest contributions of all authors in the last week (even if there are more than eight of them,)");
934 $properties["per Author: max revisions"] =
935 new numeric_define("AUTHOR_MAX_KEEP", "20", "
936 but in no case keep more than twenty unique author revisions.");
938 /////////////////////////////////////////////////////////////////////
940 $properties["Part Three"] =
941 new part('_part3', $SEPARATOR."\n", "
943 Part Three: (optional)
944 Basic User Authentication Setup
947 $properties["Publicly viewable"] =
948 new boolean_define_optional('ALLOW_ANON_USER',
949 array('true' => "true. Permit anonymous view. (Default)",
950 'false' => "false. Force login even on view (strictly private)"), "
951 If ALLOW_ANON_USER is false, you have to login before viewing any page or doing any other action on a page.");
953 $properties["Allow anonymous edit"] =
954 new boolean_define_optional('ALLOW_ANON_EDIT',
955 array('true' => "true. Permit anonymous users to edit. (Default)",
956 'false' => "false. Force login on edit (moderately locked)"), "
957 If ALLOW_ANON_EDIT is false, you have to login before editing or changing any page. See below.");
959 $properties["Allow Bogo Login"] =
960 new boolean_define_optional('ALLOW_BOGO_LOGIN',
961 array('true' => "true. Users may Sign In with any WikiWord, without password. (Default)",
962 'false' => "false. Require stricter authentication."), "
963 If ALLOW_BOGO_LOGIN is false, you may not login with any wikiword username and empty password.
964 If true, users are allowed to create themselves with any WikiWord username. See below.");
966 $properties["Allow User Passwords"] =
967 new boolean_define_optional('ALLOW_USER_PASSWORDS',
968 array('true' => "True user authentication with password checking. (Default)",
969 'false' => "false. Ignore authentication settings below."), "
970 If ALLOW_USER_PASSWORDS is true, the authentication settings below define where and how to
971 check against given username/passwords. For completely security disable BOGO_LOGIN and ANON_EDIT above.");
973 $properties["Allow User Passwords"] =
974 new array_define('USER_AUTH_ORDER', array("PersonalPage", "Db"), "
975 Many different methods can be used to check user's passwords.
976 Try any of these in the given order:
979 <dd>WikiWord username, with no *actual* password checking,
980 although the user will still have to enter one.</dd>
981 <dt>PersonalPage</dt>
982 <dd>Store passwords in the users homepage metadata (simple)</dd>
984 <dd>Use DBAUTH_AUTH_* (see below) with PearDB or ADODB only.</dd>
986 <dd>Authenticate against LDAP_AUTH_HOST with LDAP_BASE_DN</dd>
988 <dd>Authenticate against IMAP_AUTH_HOST (email account)</dd>
990 <dd>Authenticate against POP3_AUTH_HOST (email account)</dd>
992 <dd>Get username and level from a PHP session variable. (e.g. for gforge)</dd>
994 <dd>Store username:crypted-passwords in .htaccess like files.
995 Use Apache's htpasswd to manage this file.</dd>
997 <dd>Use the protection by the webserver (.htaccess/.htpasswd) (experimental)
998 Enforcing HTTP Auth not yet. Note that the ADMIN_USER should exist also.
999 Using HttpAuth disables all other methods and no userauth sessions are used.</dd>
1002 Several of these methods can be used together, in the manner specified by
1003 USER_AUTH_POLICY, below. To specify multiple authentication methods,
1004 separate the name of each one with colons.
1006 USER_AUTH_ORDER = 'PersonalPage : Db'
1007 USER_AUTH_ORDER = 'BogoLogin : PersonalPage'</pre>");
1009 $properties["PASSWORD_LENGTH_MINIMUM"] =
1010 new numeric_define("PASSWORD_LENGTH_MINIMUM", "6", "
1011 For 'security' purposes, you can specify that a password be at least a
1012 certain number of characters long. This applies even to the BogoLogin method.
1013 Default: 0 (to allow immediate passwordless BogoLogin)");
1015 $properties["USER_AUTH_POLICY"] =
1016 new _define_selection('USER_AUTH_POLICY',
1017 array('first-only' => "first-only - use only the first method in USER_AUTH_ORDER",
1018 'old' => "old - ignore USER_AUTH_ORDER (legacy)",
1019 'strict' => "strict - check all methods for userid + password (recommended)",
1020 'stacked' => "stacked - check all methods for userid, and if found for password"), "
1021 The following policies are available for user authentication:
1024 <dd>use only the first method in USER_AUTH_ORDER</dd>
1026 <dd>ignore USER_AUTH_ORDER and try to use all available
1027 methods as in the previous PhpWiki releases (slow)</dd>
1029 <dd>check if the user exists for all methods:
1030 on the first existing user, try the password.
1031 dont try the other methods on failure then</dd>
1033 <dd>check the given user - password combination for all
1034 methods and return true on the first success.</dd></dl>");
1038 $properties["Part Three A"] =
1039 new part('_part3a', $SEPARATOR."\n", "
1041 Part Three A: (optional)
1044 $properties["Group membership"] =
1045 new _define_selection("GROUP_METHOD",
1046 array('WIKIPAGE' => "WIKIPAGE - List at \"CategoryGroup\". (Slowest, but easiest to maintain)",
1047 '"NONE"' => "NONE - Disable group membership (Fastest)",
1048 'DB' => "DB - SQL Database, Optionally external. See USERS/GROUPS queries",
1049 'FILE' => "Flatfile. See AUTH_GROUP_FILE below.",
1050 'LDAP' => "LDAP - See \"LDAP authentication options\" above. (Experimental)"), "
1051 Group membership. PhpWiki supports defining permissions for a group as
1052 well as for individual users. This defines how group membership information
1053 is obtained. Supported values are:
1056 <dd>Disable group membership (Fastest). Note the required quoting.</dd>
1058 <dd>Define groups as list at \"CategoryGroup\". (Slowest, but easiest to maintain)</dd>
1060 <dd>Stored in an SQL database. Optionally external. See USERS/GROUPS queries</dd>
1062 <dd>Flatfile. See AUTH_GROUP_FILE below.</dd>
1064 <dd>LDAP groups. See \"LDAP authentication options\" above and
1065 lib/WikiGroup.php. (experimental)</dd></dl>");
1067 $properties["CATEGORY_GROUP_PAGE"] =
1068 new _define_optional('CATEGORY_GROUP_PAGE', _("CategoryGroup"), "
1069 If GROUP_METHOD = WIKIPAGE:
1071 Page where all groups are listed.");
1073 $properties["AUTH_GROUP_FILE"] =
1074 new _define_optional('AUTH_GROUP_FILE', _("/etc/groups"), "
1075 For GROUP_METHOD = FILE, the file given below is referenced to obtain
1076 group membership information. It should be in the same format as the
1077 standard unix /etc/groups(5) file.");
1079 $properties["Part Three B"] =
1080 new part('_part3b', $SEPARATOR."\n", "
1082 Part Three B: (optional)
1083 External database authentication and authorization.
1085 If USER_AUTH_ORDER includes Db, or GROUP_METHOD = DB, the options listed
1086 below define the SQL queries used to obtain the information out of the
1087 database, and (optionally) store the information back to the DB.");
1089 $properties["DBAUTH_AUTH_DSN"] =
1090 new _define_optional('DBAUTH_AUTH_DSN', $dsn_sqlstring, "
1091 A database DSN to connect to. Defaults to the DSN specified for the Wiki as a whole.");
1093 $properties["User Exists Query"] =
1094 new _define('DBAUTH_AUTH_USER_EXISTS', "SELECT userid FROM user WHERE userid='\$userid'", "
1095 USER/PASSWORD queries:
1097 For USER_AUTH_POLICY=strict and the Db method is required");
1099 $properties["Check Query"] =
1100 new _define_optional('DBAUTH_AUTH_CHECK', "SELECT IF(passwd='\$password',1,0) AS ok FROM user WHERE userid='\$userid'", "
1102 Check to see if the supplied username/password pair is OK
1104 Plaintext passwords: (DBAUTH_AUTH_CRYPT_METHOD = plain)<br>
1105 ; DBAUTH_AUTH_CHECK = \"SELECT IF(passwd='\$password',1,0) AS ok FROM user WHERE userid='\$userid'\"
1107 database-hashed passwords (more secure):<br>
1108 ; DBAUTH_AUTH_CHECK = \"SELECT IF(passwd=PASSWORD('\$password'),1,0) AS ok FROM user WHERE userid='\$userid'\"");
1110 $properties["Crypt Method"] =
1111 new _define_selection_optional
1112 ('DBAUTH_AUTH_CRYPT_METHOD',
1113 array('plain' => 'plain',
1114 'crypt' => 'crypt'), "
1115 If you want to use Unix crypt()ed passwords, you can use DBAUTH_AUTH_CHECK
1116 to get the password out of the database with a simple SELECT query, and
1117 specify DBAUTH_AUTH_USER_EXISTS and DBAUTH_AUTH_CRYPT_METHOD:
1119 ; DBAUTH_AUTH_CHECK = \"SELECT passwd FROM user where userid='\$userid'\" <br>
1120 ; DBAUTH_AUTH_CRYPT_METHOD = crypt");
1122 $properties["Update the user's authentication credential"] =
1123 new _define('DBAUTH_AUTH_UPDATE', "UPDATE user SET passwd='\$password' WHERE userid='\$userid'", "
1124 If this is not defined but DBAUTH_AUTH_CHECK is, then the user will be unable to update their
1127 Plaintext passwords:<br>
1128 DBAUTH_AUTH_UPDATE = \"UPDATE user SET passwd='\$password' WHERE userid='\$userid'\"<br>
1129 Database-hashed passwords:<br>
1130 DBAUTH_AUTH_UPDATE = \"UPDATE user SET passwd=PASSWORD('\$password') WHERE userid='\$userid'\"");
1132 $properties["Allow the user to create their own account"] =
1133 new _define_optional('DBAUTH_AUTH_CREATE', "INSERT INTO user SET passwd=PASSWORD('\$password'),userid='\$userid'", "
1134 If this is empty, Db users cannot subscribe by their own.");
1136 $properties["USER/PREFERENCE queries"] =
1137 new _define_optional('DBAUTH_PREF_SELECT', "SELECT prefs FROM user WHERE userid='\$userid'", "
1138 If you choose to store your preferences in an external database, enable
1139 the following queries. Note that if you choose to store user preferences
1140 in the 'user' table, only registered users get their prefs from the database,
1141 self-created users do not. Better to use the special 'pref' table.
1143 The prefs field stores the serialized form of the user's preferences array,
1144 to ease the complication of storage.
1146 DBAUTH_PREF_SELECT = \"SELECT prefs FROM user WHERE userid='\$userid'\"
1147 DBAUTH_PREF_SELECT = \"SELECT prefs FROM pref WHERE userid='\$userid'\"
1150 $properties["Update the user's preferences"] =
1151 new _define_optional('DBAUTH_PREF_UPDATE', "UPDATE user SET prefs='\$pref_blob' WHERE userid='\$userid'", "
1152 Note that REPLACE works only with mysql and destroy all other columns!
1154 Mysql: DBAUTH_PREF_UPDATE = \"REPLACE INTO pref SET prefs='\$pref_blob',userid='\$userid'\"");
1156 $properties["USERS/GROUPS queries"] =
1157 new _define_optional('DBAUTH_IS_MEMBER', "SELECT user FROM user WHERE user='\$userid' AND group='\$groupname'", "
1158 You can define 1:n or n:m user<=>group relations, as you wish.
1160 Sample configurations:
1162 only one group per user (1:n):<br>
1163 DBAUTH_IS_MEMBER = \"SELECT user FROM user WHERE user='\$userid' AND group='\$groupname'\"<br>
1164 DBAUTH_GROUP_MEMBERS = \"SELECT user FROM user WHERE group='\$groupname'\"<br>
1165 DBAUTH_USER_GROUPS = \"SELECT group FROM user WHERE user='\$userid'\"<br>
1166 multiple groups per user (n:m):<br>
1167 DBAUTH_IS_MEMBER = \"SELECT userid FROM member WHERE userid='\$userid' AND groupname='\$groupname'\"<br>
1168 DBAUTH_GROUP_MEMBERS = \"SELECT DISTINCT userid FROM member WHERE groupname='\$groupname'\"<br>
1169 DBAUTH_USER_GROUPS = \"SELECT groupname FROM member WHERE userid='\$userid'\"<br>");
1170 $properties["DBAUTH_GROUP_MEMBERS"] =
1171 new _define_optional('DBAUTH_GROUP_MEMBERS', "SELECT user FROM user WHERE group='\$groupname'", "");
1172 $properties["DBAUTH_USER_GROUPS"] =
1173 new _define_optional('DBAUTH_USER_GROUPS', "SELECT group FROM user WHERE user='\$userid'", "");
1175 if (function_exists('ldap_connect')) {
1177 $properties["LDAP AUTH Host"] =
1178 new _define_optional('LDAP_AUTH_HOST', "ldap://localhost:389", "
1179 If USER_AUTH_ORDER contains Ldap:
1181 The LDAP server to connect to. Can either be a hostname, or a complete
1182 URL to the server (useful if you want to use ldaps or specify a different
1185 $properties["LDAP BASE DN"] =
1186 new _define_optional('LDAP_BASE_DN', "ou=mycompany.com,o=My Company", "
1187 The organizational or domain BASE DN: e.g. \"dc=mydomain,dc=com\".
1189 Note: ou=Users and ou=Groups are used for GroupLdap Membership
1190 Better use LDAP_OU_USERS and LDAP_OU_GROUP with GROUP_METHOD=LDAP.");
1192 $properties["LDAP SET OPTION"] =
1193 new _define_optional('LDAP_SET_OPTION', "LDAP_OPT_PROTOCOL_VERSION=3:LDAP_OPT_REFERRALS=0", "
1194 Some LDAP servers need some more options, such as the Windows Active
1195 Directory Server. Specify the options (as allowed by the PHP LDAP module)
1196 and their values as NAME=value pairs separated by colons.");
1198 $properties["LDAP AUTH USER"] =
1199 new _define_optional('LDAP_AUTH_USER', "CN=ldapuser,ou=Users,o=Development,dc=mycompany.com", "
1200 DN to initially bind to the LDAP server as. This is needed if the server doesn't
1201 allow anonymous queries. (Windows Active Directory Server)");
1203 $properties["LDAP AUTH PASSWORD"] =
1204 new _define_optional('LDAP_AUTH_PASSWORD', "secret", "
1205 Password to use to initially bind to the LDAP server, as the DN
1206 specified in the LDAP_AUTH_USER option (above).");
1208 $properties["LDAP SEARCH FIELD"] =
1209 new _define_optional('LDAP_SEARCH_FIELD', "uid", "
1210 If you want to match usernames against an attribute other than uid,
1211 specify it here. Default: uid
1213 e.g.: LDAP_SEARCH_FIELD = sAMAccountName");
1215 $properties["LDAP OU USERS"] =
1216 new _define_optional('LDAP_OU_USERS', "ou=Users", "
1217 If you have an organizational unit for all users, define it here.
1218 This narrows the search, and is needed for LDAP group membership (if GROUP_METHOD=LDAP)
1219 Default: ou=Users");
1221 $properties["LDAP OU GROUP"] =
1222 new _define_optional('LDAP_OU_GROUP', "ou=Groups", "
1223 If you have an organizational unit for all groups, define it here.
1224 This narrows the search, and is needed for LDAP group membership (if GROUP_METHOD=LDAP)
1225 The entries in this ou must have a gidNumber and cn attribute.
1226 Default: ou=Groups");
1228 } else { // function_exists('ldap_connect')
1230 $properties["LDAP Authentication"] =
1231 new unchangeable_define('LDAP Authentication', "
1232 If USER_AUTH_ORDER contains Ldap:
1234 The LDAP server to connect to. Can either be a hostname, or a complete
1235 URL to the server (useful if you want to use ldaps or specify a different
1237 ;LDAP_AUTH_HOST = \"ldap://localhost:389\"
1239 ; The organizational or domain BASE DN: e.g. \"dc=mydomain,dc=com\".
1241 ; Note: ou=Users and ou=Groups are used for GroupLdap Membership
1242 ; Better use LDAP_OU_USERS and LDAP_OU_GROUP with GROUP_METHOD=LDAP.
1243 ;LDAP_BASE_DN = \"ou=Users,o=Development,dc=mycompany.com\"
1245 ; Some LDAP servers need some more options, such as the Windows Active
1246 ; Directory Server. Specify the options (as allowed by the PHP LDAP module)
1247 ; and their values as NAME=value pairs separated by colons.
1248 ; LDAP_SET_OPTION = \"LDAP_OPT_PROTOCOL_VERSION=3:LDAP_OPT_REFERRALS=0\"
1250 ; DN to initially bind to the LDAP server as. This is needed if the server doesn't
1251 ; allow anonymous queries. (Windows Active Directory Server)
1252 ; LDAP_AUTH_USER = \"CN=ldapuser,ou=Users,o=Development,dc=mycompany.com\"
1254 ; Password to use to initially bind to the LDAP server, as the DN
1255 ; specified in the LDAP_AUTH_USER option (above).
1256 ; LDAP_AUTH_PASSWORD = secret
1258 ; If you want to match usernames against an attribute other than uid,
1259 ; specify it here. Default: uid
1260 ; LDAP_SEARCH_FIELD = sAMAccountName
1262 ; If you have an organizational unit for all users, define it here.
1263 ; This narrows the search, and is needed for LDAP group membership (if GROUP_METHOD=LDAP)
1265 ; LDAP_OU_USERS = ou=Users
1267 ; If you have an organizational unit for all groups, define it here.
1268 ; This narrows the search, and is needed for LDAP group membership (if GROUP_METHOD=LDAP)
1269 ; The entries in this ou must have a gidNumber and cn attribute.
1270 ; Default: ou=Groups
1271 ; LDAP_OU_GROUP = ou=Groups", "
1272 ; Ignored. No LDAP support in this php. configure --with-ldap");
1275 if (function_exists('imap_open')) {
1277 $properties["IMAP Auth Host"] =
1278 new _define_optional('IMAP_AUTH_HOST', 'localhost:143/imap/notls', "
1279 If USER_AUTH_ORDER contains IMAP:
1281 The IMAP server to check usernames from. Defaults to localhost.
1283 Some IMAP_AUTH_HOST samples:
1284 localhost, localhost:143/imap/notls,
1285 localhost:993/imap/ssl/novalidate-cert (SuSE refuses non-SSL conections)");
1287 } else { // function_exists('imap_open')
1289 $properties["IMAP Authentication"] =
1290 new unchangeable_define('IMAP_AUTH_HOST',"
1291 ; If USER_AUTH_ORDER contains IMAP:
1292 ; The IMAP server to check usernames from. Defaults to localhost.
1294 ; Some IMAP_AUTH_HOST samples:
1295 ; localhost, localhost:143/imap/notls,
1296 ; localhost:993/imap/ssl/novalidate-cert (SuSE refuses non-SSL conections)
1297 ;IMAP_AUTH_HOST = localhost:143/imap/notls", "
1298 Ignored. No IMAP support in this php. configure --with-imap");
1302 $properties["POP3 Authentication"] =
1303 new _define_optional('POP3_AUTH_HOST', 'localhost:110', "
1304 If USER_AUTH_ORDER contains POP3:
1306 The POP3 mail server to check usernames and passwords against.");
1307 $properties["File Authentication"] =
1308 new _define_optional('AUTH_USER_FILE', '/etc/shadow', "
1309 If USER_AUTH_ORDER contains File:
1311 File to read for authentication information.
1312 Popular choices are /etc/shadow and /etc/httpd/.htpasswd");
1314 $properties["File Storable?"] =
1315 new boolean_define_commented_optional
1316 ('AUTH_USER_FILE_STORABLE',
1317 array('false' => "Disabled",
1318 'true' => "Enabled"), "
1319 Defines whether the user is able to change their own password via PhpWiki.
1320 Note that this means that the webserver user must be able to write to the
1321 file specified in AUTH_USER_FILE.");
1323 $properties["Session Auth USER"] =
1324 new _define_optional('AUTH_SESS_USER', 'userid', "
1325 If USER_AUTH_ORDER contains Session:
1327 Name of the session variable which holds the already authenticated username.
1328 Sample: 'userid', 'user[username]', 'user->username'");
1330 $properties["Session Auth LEVEL"] =
1331 new numeric_define('AUTH_SESS_LEVEL', '2', "
1332 Which level will the user be? 1 = Bogo or 2 = Pass");
1334 /////////////////////////////////////////////////////////////////////
1336 $properties["Part Four"] =
1337 new part('_part4', $SEPARATOR."\n", "
1340 Page appearance and layout");
1342 $properties["Theme"] =
1343 new _define_selection_optional('THEME',
1344 array('default' => "default",
1345 'MacOSX' => "MacOSX",
1346 'smaller' => 'smaller',
1347 'Wordpress'=> 'Wordpress',
1348 'Portland' => "Portland",
1349 'Hawaiian' => "Hawaiian",
1350 'Sidebar' => "Sidebar",
1352 'wikilens' => 'wikilens (Ratings)',
1353 'SpaceWiki' => "SpaceWiki",
1354 'shamino_com' => 'shamino_com',
1355 'MonoBook' => 'MonoBook [experimental]',
1356 'blog' => 'blog [experimental]',
1360 Most of the page appearance is controlled by files in the theme
1363 There are a number of pre-defined themes shipped with PhpWiki.
1364 Or you may create your own (e.g. by copying and then modifying one of
1369 THEME = MonoBook (WikiPedia) [experimental. MSIE problems]
1370 THEME = blog (Kubrick) [experimental. Several links missing]
1373 $properties["Character Set"] =
1374 new _define_optional('CHARSET', 'iso-8859-1', "
1375 Select a valid charset name to be inserted into the xml/html pages,
1376 and to reference links to the stylesheets (css). For more info see:
1377 http://www.iana.org/assignments/character-sets. Note that PhpWiki
1378 has been extensively tested only with the latin1 (iso-8859-1)
1381 If you change the default from iso-8859-1 PhpWiki may not work
1382 properly and it will require code modifications. However, character
1383 sets similar to iso-8859-1 may work with little or no modification
1384 depending on your setup. The database must also support the same
1385 charset, and of course the same is true for the web browser. (Some
1386 work is in progress hopefully to allow more flexibility in this
1387 area in the future).");
1389 $properties["Language"] =
1390 new _define_selection_optional('DEFAULT_LANGUAGE',
1391 array('en' => "English",
1392 '' => "<empty> (user-specific)",
1393 'fr' => "Français",
1395 'nl' => "Nederlands",
1400 'zh' => "Chinese"), "
1401 Select your language/locale - default language is \"en\" for English.
1402 Other languages available:<pre>
1403 English \"en\" (English - HomePage)
1404 German \"de\" (Deutsch - StartSeite)
1405 French \"fr\" (Français - Accueil)
1406 Dutch \"nl\" (Nederlands - ThuisPagina)
1407 Spanish \"es\" (Español - PáginaPrincipal)
1408 Swedish \"sv\" (Svenska - Framsida)
1409 Italian \"it\" (Italiano - PaginaPrincipale)
1410 Japanese \"ja\" (Japanese - ¥Û¡¼¥à ¥Ú¡¼¥¸)
1411 Chinese \"zh\" (Chinese)
1413 If you set DEFAULT_LANGUAGE to the empty string, your systems default language
1414 (as determined by the applicable environment variables) will be
1417 $properties["Wiki Page Source"] =
1418 new _define_optional('WIKI_PGSRC', 'pgsrc', "
1419 WIKI_PGSRC -- specifies the source for the initial page contents of
1420 the Wiki. The setting of WIKI_PGSRC only has effect when the wiki is
1421 accessed for the first time (or after clearing the database.)
1422 WIKI_PGSRC can either name a directory or a zip file. In either case
1423 WIKI_PGSRC is scanned for files -- one file per page.
1425 // Default (old) behavior:
1426 define('WIKI_PGSRC', 'pgsrc');
1428 define('WIKI_PGSRC', 'wiki.zip');
1429 define('WIKI_PGSRC',
1430 '../Logs/Hamwiki/hamwiki-20010830.zip');
1434 $properties["Default Wiki Page Source"] =
1435 new _define('DEFAULT_WIKI_PGSRC', 'pgsrc', "
1436 DEFAULT_WIKI_PGSRC is only used when the language is *not* the
1437 default (English) and when reading from a directory: in that case
1438 some English pages are inserted into the wiki as well.
1439 DEFAULT_WIKI_PGSRC defines where the English pages reside.
1441 FIXME: is this really needed?
1444 $properties["Generic Pages"] =
1445 new array_variable('GenericPages', array('ReleaseNotes', 'SteveWainstead', 'TestPage'), "
1446 These are the pages which will get loaded from DEFAULT_WIKI_PGSRC.
1448 FIXME: is this really needed? Cannot we just copy these pages into
1449 the localized pgsrc?
1455 $properties["Part Five"] =
1456 new part('_part5', $SEPARATOR."\n", "
1461 $properties["Allowed Protocols"] =
1462 new list_define('ALLOWED_PROTOCOLS', 'http|https|mailto|ftp|news|nntp|ssh|gopher', "
1463 Allowed protocols for links - be careful not to allow \"javascript:\"
1464 URL of these types will be automatically linked.
1465 within a named link [name|uri] one more protocol is defined: phpwiki");
1467 $properties["Inline Images"] =
1468 new list_define('INLINE_IMAGES', 'png|jpg|gif', "
1469 URLs ending with the following extension should be inlined as images.
1470 Scripts shoud not be allowed!");
1472 $properties["WikiName Regexp"] =
1473 new _define('WIKI_NAME_REGEXP', "(?<![[:alnum:]])(?:[[:upper:]][[:lower:]]+){2,}(?![[:alnum:]])", "
1474 Perl regexp for WikiNames (\"bumpy words\")
1475 (?<!..) & (?!...) used instead of '\b' because \b matches '_' as well");
1477 $properties["Subpage Separator"] =
1478 new _define_optional('SUBPAGE_SEPARATOR', '"/"', "
1479 One character which seperates pages from subpages. Defaults to '/', but '.' or ':' were also used.",
1480 "onchange=\"validate_ereg('Sorry, \'%s\' must be a single character. Currently only :, / or .', '^[/:.]$', 'SUBPAGE_SEPARATOR', this);\""
1483 $properties["InterWiki Map File"] =
1484 new _define('INTERWIKI_MAP_FILE', 'lib/interwiki.map', "
1485 InterWiki linking -- wiki-style links to other wikis on the web
1487 The map will be taken from a page name InterWikiMap.
1488 If that page is not found (or is not locked), or map
1489 data can not be found in it, then the file specified
1490 by INTERWIKI_MAP_FILE (if any) will be used.");
1492 $properties["WARN_NONPUBLIC_INTERWIKIMAP"] =
1493 new boolean_define('WARN_NONPUBLIC_INTERWIKIMAP',
1494 array('true' => "true",
1495 'false' => "false"), "
1496 Display a warning if the internal lib/interwiki.map is used, and
1497 not the public InterWikiMap page. This map is not readable from outside.");
1500 $properties["Keyword Link Regexp"] =
1501 new _define_optional('KEYWORDS', '\"Category* OR Topic*\"', "
1502 Search term used for automatic page classification by keyword extraction.
1504 Any links on a page to pages whose names match this search
1505 will be used keywords in the keywords html meta tag. This is an aid to
1506 classification by search engines. The value of the match is
1507 used as the keyword.
1509 The default behavior is to match Category* or Topic* links.");
1511 $properties["Author and Copyright Site Navigation Links"] =
1512 new _define_commented_optional('COPYRIGHTPAGE_TITLE', "GNU General Public License", "
1514 These will be inserted as <link rel> tags in the html header of
1515 every page, for search engines and for browsers like Mozilla which
1516 take advantage of link rel site navigation.
1518 If you have your own copyright and contact information pages change
1519 these as appropriate.");
1521 $properties["COPYRIGHTPAGE URL"] =
1522 new _define_commented_optional('COPYRIGHTPAGE_URL', "http://www.gnu.org/copyleft/gpl.html#SEC1", "
1524 Other useful alternatives to consider:
1526 COPYRIGHTPAGE_TITLE = \"GNU Free Documentation License\"
1527 COPYRIGHTPAGE_URL = \"http://www.gnu.org/copyleft/fdl.html\"
1528 COPYRIGHTPAGE_TITLE = \"Creative Commons License 2.0\"
1529 COPYRIGHTPAGE_URL = \"http://creativecommons.org/licenses/by/2.0/\"</pre>
1530 See http://creativecommons.org/learn/licenses/ for variations");
1532 $properties["AUTHORPAGE_TITLE"] =
1533 new _define_commented_optional('AUTHORPAGE_TITLE', "The PhpWiki Programming Team", "
1534 Default Author Names");
1535 $properties["AUTHORPAGE_URL"] =
1536 new _define_commented_optional('AUTHORPAGE_URL', "http://phpwiki.org/ThePhpWikiProgrammingTeam", "
1537 Default Author URL");
1539 new boolean_define_optional
1541 array('true' => "Enabled",
1542 'false' => "Disabled"), "
1543 Allow full markup in headers to be parsed by the CreateToc plugin.
1545 If false you may not use WikiWords or [] links or any other markup in
1546 headers in pages with the CreateToc plugin. But if false the parsing is
1547 faster and more stable.");
1551 $properties["Part Six"] =
1552 new part('_part6', $SEPARATOR."\n", "
1554 Part Six (optional):
1555 URL options -- you can probably skip this section.
1557 For a pretty wiki (no index.php in the url) set a seperate DATA_PATH.");
1559 global $HTTP_SERVER_VARS;
1560 $properties["Server Name"] =
1561 new _define_commented_optional('SERVER_NAME', $HTTP_SERVER_VARS['SERVER_NAME'], "
1562 Canonical name of the server on which this PhpWiki resides.");
1564 $properties["Server Port"] =
1565 new numeric_define_commented('SERVER_PORT', $HTTP_SERVER_VARS['SERVER_PORT'], "
1566 Canonical httpd port of the server on which this PhpWiki resides.",
1567 "onchange=\"validate_ereg('Sorry, \'%s\' is no valid port number.', '^[0-9]+$', 'SERVER_PORT', this);\"");
1569 $properties["Script Name"] =
1570 new _define_commented_optional('SCRIPT_NAME', $scriptname, "
1571 Relative URL (from the server root) of the PhpWiki script.");
1573 $properties["Data Path"] =
1574 new _define_commented_optional('DATA_PATH', dirname($scriptname), "
1575 URL of the PhpWiki install directory. (You only need to set this
1576 if you've moved index.php out of the install directory.) This can
1577 be either a relative URL (from the directory where the top-level
1578 PhpWiki script is) or an absolute one.");
1581 $properties["PhpWiki Install Directory"] =
1582 new _define_commented_optional('PHPWIKI_DIR', dirname(__FILE__), "
1583 Path to the PhpWiki install directory. This is the local
1584 filesystem counterpart to DATA_PATH. (If you have to set
1585 DATA_PATH, your probably have to set this as well.) This can be
1586 either an absolute path, or a relative path interpreted from the
1587 directory where the top-level PhpWiki script (normally index.php)
1590 $properties["Use PATH_INFO"] =
1591 new _define_selection_optional_commented('USE_PATH_INFO',
1592 array('' => 'automatic',
1593 'true' => 'use PATH_INFO',
1594 'false' => 'do not use PATH_INFO'), "
1595 PhpWiki will try to use short urls to pages, eg
1596 http://www.example.com/index.php/HomePage
1597 If you want to use urls like
1598 http://www.example.com/index.php?pagename=HomePage
1599 then define 'USE_PATH_INFO' as false by uncommenting the line below.
1600 NB: If you are using Apache >= 2.0.30, then you may need to to use
1601 the directive \"AcceptPathInfo On\" in your Apache configuration file
1602 (or in an appropriate <.htaccess> file) for the short urls to work:
1603 See http://httpd.apache.org/docs-2.0/mod/core.html#acceptpathinfo
1605 See also http://phpwiki.sourceforge.net/phpwiki/PrettyWiki for more ideas
1606 on prettifying your urls.
1608 Default: PhpWiki will try to divine whether use of PATH_INFO
1609 is supported in by your webserver/PHP configuration, and will
1610 use PATH_INFO if it thinks that is possible.");
1612 $properties["Virtual Path"] =
1613 new _define_commented_optional('VIRTUAL_PATH', '/SomeWiki', "
1614 VIRTUAL_PATH is the canonical URL path under which your your wiki
1615 appears. Normally this is the same as dirname(SCRIPT_NAME), however
1616 using e.g. seperate starter scripts, apaches mod_actions (or mod_rewrite),
1617 you can make it something different.
1619 If you do this, you should set VIRTUAL_PATH here or in the starter scripts.
1621 E.g. your phpwiki might be installed at at /scripts/phpwiki/index.php,
1622 but you've made it accessible through eg. /wiki/HomePage.
1624 One way to do this is to create a directory named 'wiki' in your
1625 server root. The directory contains only one file: an .htaccess
1626 file which reads something like:
1628 Action x-phpwiki-page /scripts/phpwiki/index.php
1629 SetHandler x-phpwiki-page
1630 DirectoryIndex /scripts/phpwiki/index.php
1632 In that case you should set VIRTUAL_PATH to '/wiki'.
1634 (VIRTUAL_PATH is only used if USE_PATH_INFO is true.)
1639 $properties["Part Seven"] =
1640 new part('_part7', $SEPARATOR."\n", "
1644 Miscellaneous settings
1647 $properties["Strict Mailable Pagedumps"] =
1648 new boolean_define_optional
1649 ('STRICT_MAILABLE_PAGEDUMPS',
1650 array('false' => "binary",
1651 'true' => "quoted-printable"),
1653 If you define this to true, (MIME-type) page-dumps (either zip dumps,
1654 or \"dumps to directory\" will be encoded using the quoted-printable
1655 encoding. If you're actually thinking of mailing the raw page dumps,
1656 then this might be useful, since (among other things,) it ensures
1657 that all lines in the message body are under 80 characters in length.
1659 Also, setting this will cause a few additional mail headers
1660 to be generated, so that the resulting dumps are valid
1661 RFC 2822 e-mail messages.
1663 Probably, you can just leave this set to false, in which case you get
1664 raw ('binary' content-encoding) page dumps.");
1666 $properties["HTML Dump Filename Suffix"] =
1667 new _define_optional('HTML_DUMP_SUFFIX', ".html", "
1668 Here you can change the filename suffix used for XHTML page dumps.
1669 If you don't want any suffix just comment this out.");
1671 $properties["Default local Dump Directory"] =
1672 new _define_optional('DEFAULT_DUMP_DIR', "/tmp/wikidump", "
1673 Specify the default directory for local backups.");
1675 $properties["Default local HTML Dump Directory"] =
1676 new _define_optional('HTML_DUMP_DIR', "/tmp/wikidumphtml", "
1677 Specify the default directory for local XHTML dumps.");
1679 $properties["Pagename of Recent Changes"] =
1680 new _define_optional('RECENT_CHANGES', 'RecentChanges', "
1681 Page name of RecentChanges page. Used for RSS Auto-discovery.");
1683 $properties["Disable HTTP Redirects"] =
1684 new boolean_define_commented_optional
1685 ('DISABLE_HTTP_REDIRECT',
1686 array('false' => 'Enable HTTP Redirects',
1687 'true' => 'Disable HTTP Redirects'),
1689 (You probably don't need to touch this.)
1691 PhpWiki uses HTTP redirects for some of it's functionality.
1692 (e.g. after saving changes, PhpWiki redirects your browser to
1693 view the page you just saved.)
1695 Some web service providers (notably free European Lycos) don't seem to
1696 allow these redirects. (On Lycos the result in an \"Internal Server Error\"
1697 report.) In that case you can set DISABLE_HTTP_REDIRECT to true.
1698 (In which case, PhpWiki will revert to sneakier tricks to try to
1699 redirect the browser...)");
1701 $properties["Disable GETIMAGESIZE"] =
1702 new boolean_define_commented_optional
1703 ('DISABLE_GETIMAGESIZE',
1704 array('false' => 'Enable',
1705 'true' => 'Disable'), "
1706 Set GETIMAGESIZE to disabled, if your php fails to calculate the size on
1707 inlined images, or you don't want to disable too small images to be inlined.
1709 Per default too small ploaded or external images are not displayed,
1710 to prevent from external 1 pixel spam.");
1712 $properties["EDITING_POLICY"] =
1713 new _define_optional('EDITING_POLICY', "EditingPolicy", "
1714 An interim page which gets displayed on every edit attempt, if it exists.");
1716 $properties["ENABLE_MODERATEDPAGE_ALL"] =
1717 new boolean_define_commented_optional
1718 ('ENABLE_MODERATEDPAGE_ALL',
1719 array('false' => 'Disable',
1720 'true' => 'Enable'), "
1723 $properties["FORTUNE_DIR"] =
1724 new _define_commented_optional('FORTUNE_DIR', "/usr/share/fortune", "
1726 $properties["DBADMIN_USER"] =
1727 new _define_commented_optional('DBADMIN_USER', "", "
1729 $properties["DBADMIN_PASSWD"] =
1730 new _define_commented_optional('DBADMIN_PASSWD', "", "
1732 $properties["USE_EXTERNAL_HTML2PDF"] =
1733 new _define_commented_optional('USE_EXTERNAL_HTML2PDF', "htmldoc --quiet --format pdf14 --no-toc --no-title %s", "
1735 $properties["BABYCART_PATH"] =
1736 new _define_commented_optional('BABYCART_PATH', "/usr/local/bin/babycart", "
1739 $properties["Part Seven A"] =
1740 new part('_part7a', $SEPARATOR."\n", "
1744 Cached Plugin Settings. (pear Cache)
1747 $properties["pear Cache USECACHE"] =
1748 new boolean_define_optional('PLUGIN_CACHED_USECACHE',
1749 array('true' => 'Enabled',
1750 'false' => 'Disabled'), "
1751 Enable or disable pear caching of plugins.");
1752 $properties["pear Cache Database Container"] =
1753 new _define_selection_optional('PLUGIN_CACHED_DATABASE',
1754 array('file' => 'file'), "
1755 Curently only file is supported.
1756 db, trifile and imgfile might be supported, but you must hack that by yourself.");
1758 $properties["pear Cache cache directory"] =
1759 new _define_commented_optional('PLUGIN_CACHED_CACHE_DIR', "/tmp/cache", "
1760 Should be writable to the webserver.");
1761 $properties["pear Cache Filename Prefix"] =
1762 new _define_optional('PLUGIN_CACHED_FILENAME_PREFIX', "phpwiki", "");
1763 $properties["pear Cache HIGHWATER"] =
1764 new numeric_define_optional('PLUGIN_CACHED_HIGHWATER', "4194304", "
1765 Garbage collection parameter.");
1766 $properties["pear Cache LOWWATER"] =
1767 new numeric_define_optional('PLUGIN_CACHED_LOWWATER', "3145728", "
1768 Garbage collection parameter.");
1769 $properties["pear Cache MAXLIFETIME"] =
1770 new numeric_define_optional('PLUGIN_CACHED_MAXLIFETIME', "2592000", "
1771 Garbage collection parameter.");
1772 $properties["pear Cache MAXARGLEN"] =
1773 new numeric_define_optional('PLUGIN_CACHED_MAXARGLEN', "1000", "
1774 max. generated url length.");
1775 $properties["pear Cache FORCE_SYNCMAP"] =
1776 new boolean_define_optional('PLUGIN_CACHED_FORCE_SYNCMAP',
1777 array('true' => 'Enabled',
1778 'false' => 'Disabled'), "");
1779 $properties["pear Cache IMGTYPES"] =
1780 new list_define('PLUGIN_CACHED_IMGTYPES', "png|gif|gd|gd2|jpeg|wbmp|xbm|xpm", "
1781 Handle those image types via GD handles. Check your GD supported image types.");
1783 $end = "\n".$SEPARATOR."\n";
1785 // end of configuration options
1786 ///////////////////////////////
1787 // begin class definitions
1790 * A basic config-dist.ini configuration line in the form of a variable.
1791 * (not needed anymore, we have only defines)
1793 * Produces a string in the form "$name = value;"
1795 * $WikiNameRegexp = "value";
1799 var $config_item_name;
1805 function _variable($config_item_name, $default_value, $description, $jscheck = '') {
1806 $this->config_item_name = $config_item_name;
1807 $this->description = $description;
1808 if (defined($config_item_name)
1809 and !preg_match("/(selection|boolean)/", get_class($this))
1810 and !preg_match("/(SCRIPT_NAME|VIRTUAL_PATH)/", $config_item_name))
1811 $this->default_value = constant($config_item_name); // ignore given default value
1813 $this->default_value = $default_value;
1814 $this->jscheck = $jscheck;
1815 if (preg_match("/variable/i",get_class($this)))
1816 $this->prefix = "\$";
1817 elseif (preg_match("/ini_set/i",get_class($this)))
1818 $this->prefix = "ini_get: ";
1824 global $HTTP_POST_VARS;
1825 if (isset($HTTP_POST_VARS[$this->config_item_name]))
1826 return $HTTP_POST_VARS[$this->config_item_name];
1828 return $this->default_value;
1831 function _config_format($value) {
1832 $v = $this->get_config_item_name();
1833 // handle arrays: a|b --> a['b']
1834 if (strpos($v, '|')) {
1835 list($a, $b) = explode('|', $v);
1836 $v = sprintf("%s['%s']", $a, $b);
1838 if (preg_match("/[\"']/", $value))
1839 $value = '"' . $value . '"';
1840 return sprintf("%s = \"%s\"", $v, $value);
1843 function get_config_item_name() {
1844 return $this->config_item_name;
1847 function get_config_item_id() {
1848 return str_replace('|', '-', $this->config_item_name);
1851 function get_config_item_header() {
1852 if (strchr($this->config_item_name,'|')) {
1853 list($var,$param) = explode('|',$this->config_item_name);
1854 return "<b>" . $this->prefix . $var . "['" . $param . "']</b><br />";
1856 elseif ($this->config_item_name[0] != '_')
1857 return "<b>" . $this->prefix . $this->config_item_name . "</b><br />";
1862 function _get_description() {
1863 return $this->description;
1866 function _get_config_line($posted_value) {
1867 return "\n" . $this->_config_format($posted_value);
1870 function get_config($posted_value) {
1871 $d = stripHtml($this->_get_description());
1872 $d = str_replace("\n", "\n; ", $d) . $this->_get_config_line($posted_value) ."\n";
1876 function get_instructions($title) {
1878 $i = "<h3>" . $title . "</h3>\n " . nl2p($this->_get_description()) . "\n";
1879 return "<tr>\n<td width=\"$tdwidth\" class=\"instructions\">\n" . $i . "</td>\n";
1882 function get_html() {
1883 $size = strlen($this->default_value) > 45 ? 90 : 50;
1884 return $this->get_config_item_header() .
1885 "<input type=\"text\" size=\"$50\" name=\"" . $this->get_config_item_name() . "\" value=\"" . htmlspecialchars($this->default_value) . "\" " .
1886 $this->jscheck . " />" . "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: green\">Input accepted.</p>";
1890 class unchangeable_variable
1892 function _config_format($value) {
1895 // function get_html() { return false; }
1896 function get_html() {
1897 return $this->get_config_item_header() .
1898 "<em>Not editable.</em>" .
1899 "<pre>" . $this->default_value."</pre>";
1901 function _get_config_line($posted_value) {
1902 if ($this->description)
1904 return "${n}".$this->default_value;
1906 function get_instructions($title) {
1908 $i = "<h3>" . $title . "</h3>\n " . nl2p($this->_get_description()) . "\n";
1909 // $i .= "<em>Not editable.</em><br />\n<pre>" . $this->default_value."</pre>";
1910 return '<tr><td width="100%" class="unchangeable-variable-top" colspan="2">'."\n".$i."</td></tr>\n"
1911 . '<tr style="border-top: none;"><td class="unchangeable-variable-left" width="'.$tdwidth.'"> </td>';
1915 class unchangeable_define
1916 extends unchangeable_variable {
1917 function _config_format($value) {
1921 class unchangeable_ini_set
1922 extends unchangeable_variable {
1923 function _config_format($value) {
1928 class _variable_selection
1931 global $HTTP_POST_VARS;
1932 if (!empty($HTTP_POST_VARS[$this->config_item_name]))
1933 return $HTTP_POST_VARS[$this->config_item_name];
1935 list($option, $label) = each($this->default_value);
1939 function get_html() {
1940 $output = $this->get_config_item_header();
1941 $output .= '<select name="' . $this->get_config_item_name() . "\">\n";
1942 /* The first option is the default */
1943 $values = $this->default_value;
1944 if (defined($this->get_config_item_name()))
1945 $this->default_value = constant($this->get_config_item_name());
1947 $this->default_value = null;
1948 while(list($option, $label) = each($values)) {
1949 if (!is_null($this->default_value) and $this->default_value === $option)
1950 $output .= " <option value=\"$option\" selected=\"selected\">$label</option>\n";
1952 $output .= " <option value=\"$option\">$label</option>\n";
1954 $output .= "</select>\n";
1962 function _config_format($value) {
1963 return sprintf("%s = \"%s\"", $this->get_config_item_name(), $value);
1965 function _get_config_line($posted_value) {
1966 if ($this->description)
1968 if ($posted_value == '')
1969 return "${n};" . $this->_config_format("");
1971 return "${n}" . $this->_config_format($posted_value);
1973 function get_html() {
1974 $size = strlen($this->default_value) > 45 ? 90 : 50;
1975 return $this->get_config_item_header()
1976 . "<input type=\"text\" size=\"$size\" name=\"" . htmlentities($this->get_config_item_name())
1977 . "\" value=\"" . htmlentities($this->default_value) . "\" {$this->jscheck} />"
1978 . "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: green\">Input accepted.</p>";
1982 class _define_commented
1984 function _get_config_line($posted_value) {
1985 if ($this->description)
1987 if ($posted_value == $this->default_value)
1988 return "${n};" . $this->_config_format($posted_value);
1989 elseif ($posted_value == '')
1990 return "${n};" . $this->_config_format("");
1992 return "${n}" . $this->_config_format($posted_value);
1997 * We don't use _optional anymore, because INI-style config's don't need that.
1998 * IniConfig.php does the optional logic now.
1999 * But we use _optional for config-default.ini options
2001 class _define_commented_optional
2002 extends _define_commented { }
2004 class _define_optional
2007 class _define_notempty
2009 function get_html() {
2010 $s = $this->get_config_item_header()
2011 . "<input type=\"text\" size=\"50\" name=\"" . $this->get_config_item_name()
2012 . "\" value=\"" . $this->default_value . "\" {$this->jscheck} />";
2013 if (empty($this->default_value))
2014 return $s . "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: red\">Cannot be empty.</p>";
2016 return $s . "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: green\">Input accepted.</p>";
2020 class _variable_commented
2022 function _get_config_line($posted_value) {
2023 if ($this->description)
2025 if ($posted_value == $this->default_value)
2026 return "${n};" . $this->_config_format($posted_value);
2027 elseif ($posted_value == '')
2028 return "${n};" . $this->_config_format("");
2030 return "${n}" . $this->_config_format($posted_value);
2034 class numeric_define
2037 function numeric_define($config_item_name, $default_value, $description, $jscheck = '') {
2038 $this->_define($config_item_name, $default_value, $description, $jscheck);
2040 $this->jscheck = "onchange=\"validate_ereg('Sorry, \'%s\' is not an integer.', '^[-+]?[0-9]+$', '" . $this->get_config_item_name() . "', this);\"";
2042 function _config_format($value) {
2043 //return sprintf("define('%s', %s);", $this->get_config_item_name(), $value);
2044 return sprintf("%s = %s", $this->get_config_item_name(), $value);
2046 function _get_config_line($posted_value) {
2047 if ($this->description)
2049 if ($posted_value == '')
2050 return "${n};" . $this->_config_format('0');
2052 return "${n}" . $this->_config_format($posted_value);
2056 class numeric_define_optional
2057 extends numeric_define {}
2059 class numeric_define_commented
2060 extends numeric_define {
2061 function _get_config_line($posted_value) {
2062 if ($this->description)
2064 if ($posted_value == $this->default_value)
2065 return "${n};" . $this->_config_format($posted_value);
2066 elseif ($posted_value == '')
2067 return "${n};" . $this->_config_format('0');
2069 return "${n}" . $this->_config_format($posted_value);
2073 class _define_selection
2074 extends _variable_selection {
2075 function _config_format($value) {
2076 return sprintf("%s = %s", $this->get_config_item_name(), $value);
2078 function _get_config_line($posted_value) {
2079 return _define::_get_config_line($posted_value);
2081 function get_html() {
2082 return _variable_selection::get_html();
2086 class _define_selection_optional
2087 extends _define_selection { }
2089 class _variable_selection_optional
2090 extends _variable_selection { }
2092 class _define_selection_optional_commented
2093 extends _define_selection_optional {
2094 function _get_config_line($posted_value) {
2095 if ($this->description)
2097 if ($posted_value == $this->default_value)
2098 return "${n};" . $this->_config_format($posted_value);
2099 elseif ($posted_value == '')
2100 return "${n};" . $this->_config_format("");
2102 return "${n}" . $this->_config_format($posted_value);
2106 class _define_password
2109 function _define_password($config_item_name, $default_value, $description, $jscheck = '') {
2110 $this->_define($config_item_name, $default_value, $description, $jscheck);
2112 $this->jscheck = "onchange=\"validate_ereg('Sorry, \'%s\' cannot be empty.', '^.+$', '" . $this->get_config_item_name() . "', this);\"";
2114 function _get_config_line($posted_value) {
2115 if ($this->description)
2117 if ($posted_value == '') {
2118 $p = "${n};" . $this->_config_format("");
2119 $p .= "\n; If you used the passencrypt.php utility to encode the password";
2120 $p .= "\n; then uncomment this line:";
2121 $p .= "\n;ENCRYPTED_PASSWD = true";
2124 if (function_exists('crypt')) {
2125 $salt_length = max(CRYPT_SALT_LENGTH,
2129 16 * CRYPT_BLOWFISH);
2130 // generate an encrypted password
2131 $crypt_pass = crypt($posted_value, rand_ascii($salt_length));
2132 $p = "${n}" . $this->_config_format($crypt_pass);
2133 return $p . "\nENCRYPTED_PASSWD = true";
2135 $p = "${n}" . $this->_config_format($posted_value);
2136 $p .= "\n; Encrypted passwords cannot be used:";
2137 $p .= "\n; 'function crypt()' not available in this version of php";
2138 $p .= "\nENCRYPTED_PASSWD = false";
2143 function get_html() {
2144 return _variable_password::get_html();
2148 class _define_password_optional
2149 extends _define_password { }
2151 class _variable_password
2153 function _variable_password($config_item_name, $default_value, $description, $jscheck = '') {
2154 $this->_define($config_item_name, $default_value, $description, $jscheck);
2156 $this->jscheck = "onchange=\"validate_ereg('Sorry, \'%s\' cannot be empty.', '^.+$', '" . $this->get_config_item_name() . "', this);\"";
2158 function get_html() {
2159 global $HTTP_POST_VARS, $HTTP_GET_VARS;
2160 $s = $this->get_config_item_header();
2161 if (isset($HTTP_POST_VARS['create']) or isset($HTTP_GET_VARS['create'])) {
2162 $new_password = random_good_password();
2163 $this->default_value = $new_password;
2164 $s .= "Created password: <strong>$new_password</strong><br /> <br />";
2166 $s .= "<input type=\"password\" name=\"" . $this->get_config_item_name()
2167 . "\" value=\"" . $this->default_value
2168 . "\" {$this->jscheck} />"
2169 . " <input type=\"submit\" name=\"create\" value=\"Create Random Password\" />";
2170 if (empty($this->default_value))
2171 $s .= "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: red\">Cannot be empty.</p>";
2172 elseif (strlen($this->default_value) < 4)
2173 $s .= "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: red\">Must be longer than 4 chars.</p>";
2175 $s .= "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: green\">Input accepted.</p>";
2182 function _get_config_line($posted_value) {
2183 // split the phrase by any number of commas or space characters,
2184 // which include " ", \r, \t, \n and \f
2185 $list_values = preg_split("/[\s,]+/", $posted_value, -1, PREG_SPLIT_NO_EMPTY);
2186 $list_values = join("|", $list_values);
2187 return _variable::_get_config_line($list_values);
2189 function get_html() {
2190 $list_values = explode("|", $this->default_value);
2191 $rows = max(3, count($list_values) +1);
2192 $list_values = join("\n", $list_values);
2193 $ta = $this->get_config_item_header();
2194 $ta .= "<textarea cols=\"18\" rows=\"". $rows ."\" name=\"".$this->get_config_item_name()."\" {$this->jscheck}>";
2195 $ta .= $list_values . "</textarea>";
2196 $ta .= "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: green\">Input accepted.</p>";
2203 function _get_config_line($posted_value) {
2204 $list_values = preg_split("/[\s,]+/", $posted_value, -1, PREG_SPLIT_NO_EMPTY);
2205 $list_values = join("|", $list_values);
2206 return _variable::_get_config_line($list_values);
2208 function get_html() {
2209 $list_values = explode("|", $this->default_value);
2210 $rows = max(3, count($list_values) +1);
2211 $list_values = join("\n", $list_values);
2212 $ta = $this->get_config_item_header();
2213 $ta .= "<textarea cols=\"18\" rows=\"". $rows ."\" name=\"".$this->get_config_item_name()."\" {$this->jscheck}>";
2214 $ta .= $list_values . "</textarea>";
2215 $ta .= "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: green\">Input accepted.</p>";
2220 class array_variable
2222 function _config_format($value) {
2223 return sprintf("%s = \"%s\"", $this->get_config_item_name(),
2224 is_array($value) ? join(':', $value) : $value);
2226 function _get_config_line($posted_value) {
2227 // split the phrase by any number of commas or space characters,
2228 // which include " ", \r, \t, \n and \f
2229 $list_values = preg_split("/[\s,]+/", $posted_value, -1, PREG_SPLIT_NO_EMPTY);
2230 if (!empty($list_values)) {
2231 $list_values = "'".join("', '", $list_values)."'";
2232 return "\n" . $this->_config_format($list_values);
2234 return "\n;" . $this->_config_format('');
2236 function get_html() {
2237 $list_values = join("\n", $this->default_value);
2238 $rows = max(3, count($this->default_value) +1);
2239 $ta = $this->get_config_item_header();
2240 $ta .= "<textarea cols=\"18\" rows=\"". $rows ."\" name=\"".$this->get_config_item_name()."\" {$this->jscheck}>";
2241 $ta .= $list_values . "</textarea>";
2242 $ta .= "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: green\">Input accepted.</p>";
2249 function _config_format($value) {
2250 return sprintf("%s = \"%s\"", $this->get_config_item_name(),
2251 is_array($value) ? join(' : ', $value) : $value);
2253 function _get_config_line($posted_value) {
2254 // split the phrase by any number of commas or space characters,
2255 // which include " ", \r, \t, \n and \f
2256 $list_values = preg_split("/[\s,:]+/", $posted_value, -1, PREG_SPLIT_NO_EMPTY);
2257 if (!empty($list_values)) {
2258 $list_values = "'".join("' : '", $list_values)."'";
2259 return "\n" . $this->_config_format($list_values);
2261 return "\n;" . $this->_config_format('');
2263 function get_html() {
2264 $list_values = join("\n", $this->default_value);
2265 $rows = max(3, count($this->default_value) +1);
2266 $ta = $this->get_config_item_header();
2267 $ta .= "<textarea cols=\"18\" rows=\"". $rows ."\" name=\"".$this->get_config_item_name()."\" {$this->jscheck}>";
2268 $ta .= $list_values . "</textarea>";
2269 $ta .= "<p id=\"" . $this->get_config_item_id() . "\" style=\"color: green\">Input accepted.</p>";
2278 global $HTTP_POST_VARS;
2279 if ($v = $HTTP_POST_VARS[$this->config_item_name])
2282 return ini_get($this->get_config_item_name);
2285 function _config_format($value) {
2286 return sprintf("ini_set('%s', '%s');", $this->get_config_item_name(), $value);
2288 function _get_config_line($posted_value) {
2289 if ($posted_value && ! $posted_value == $this->default_value)
2290 return "\n" . $this->_config_format($posted_value);
2292 return "\n;" . $this->_config_format($this->default_value);
2297 class boolean_define
2299 function _get_config_line($posted_value) {
2300 if ($this->description)
2302 return "${n}" . $this->_config_format($posted_value);
2304 function _config_format($value) {
2305 if (strtolower(trim($value)) == 'false')
2307 return sprintf("%s = %s", $this->get_config_item_name(),
2308 (bool)$value ? 'true' : 'false');
2310 function get_html() {
2311 $output = $this->get_config_item_header();
2312 $output .= '<select name="' . $this->get_config_item_name() . "\" {$this->jscheck}>\n";
2313 $values = $this->default_value;
2314 if (defined($this->get_config_item_name()))
2315 $this->default_value = constant($this->get_config_item_name());
2317 $this->default_value = null;
2318 list($option, $label) = each($values);
2319 $output .= " <option value=\"$option\" selected=\"selected\">$label</option>\n";
2321 /* There can usually, only be two options, there can be
2322 * three options in the case of a boolean_define_commented_optional */
2323 while (list($option, $label) = each($values)) {
2324 if (!is_null($this->default_value) and $this->default_value === $option)
2325 $output .= " <option value=\"$option\" selected=\"selected\">$label</option>\n";
2327 $output .= " <option value=\"$option\">$label</option>\n";
2329 $output .= "</select>\n";
2334 class boolean_define_optional
2335 extends boolean_define {}
2337 class boolean_define_commented
2338 extends boolean_define {
2339 function _get_config_line($posted_value) {
2340 if ($this->description)
2342 list($default_value, $label) = each($this->default_value);
2343 if ($posted_value == $default_value)
2344 return "${n};" . $this->_config_format($posted_value);
2345 elseif ($posted_value == '')
2346 return "${n};" . $this->_config_format('false');
2348 return "${n}" . $this->_config_format($posted_value);
2352 class boolean_define_commented_optional
2353 extends boolean_define_commented {}
2357 function value () { return; }
2358 function get_config($posted_value) {
2359 $d = stripHtml($this->_get_description());
2361 return "\n".$SEPARATOR . str_replace("\n", "\n; ", $d) ."\n".$this->default_value;
2363 function get_instructions($title) {
2364 $id = preg_replace("/\W/","",$this->config_item_name);
2365 $group_name = preg_replace("/\W/","",$title);
2366 $i = "<tr class=\"header\" id=\"$id\">\n<td class=\"part\" width=\"100%\" colspan=\"2\" bgcolor=\"#eeeeee\">\n";
2367 $i .= "<h2>" . $title . "</h2>\n " . nl2p($this->_get_description()) ."\n";
2368 $i .= "<p><a href=\"javascript:toggle_group('$id')\" id=\"{$id}_text\">Hide options.</a></p>";
2369 return $i ."</td>\n";
2371 function get_html() {
2376 // html utility functions
2377 function nl2p($text) {
2378 preg_match_all("@\s*(<pre>.*?</pre>|<dl>.*?</dl>|.*?(?=\n\n|<pre>|<dl>|$))@s",
2379 $text, $m, PREG_PATTERN_ORDER);
2382 foreach ($m[1] as $par) {
2383 if (!($par = trim($par)))
2385 if (!preg_match('/^<(pre|dl)>/', $par))
2386 $par = "<p>$par</p>";
2392 function stripHtml($text) {
2393 $d = str_replace("<pre>", "", $text);
2394 $d = str_replace("</pre>", "", $d);
2395 $d = str_replace("<dl>", "", $d);
2396 $d = str_replace("</dl>", "", $d);
2397 $d = str_replace("<dt>", "", $d);
2398 $d = str_replace("</dt>", "", $d);
2399 $d = str_replace("<dd>", "", $d);
2400 $d = str_replace("</dd>", "", $d);
2401 $d = str_replace("<p>", "", $d);
2402 $d = str_replace("</p>", "", $d);
2403 //restore html entities into characters
2404 // http://www.php.net/manual/en/function.htmlentities.php
2405 $trans = get_html_translation_table (HTML_ENTITIES);
2406 $trans = array_flip ($trans);
2407 $d = strtr($d, $trans);
2411 include_once(dirname(__FILE__)."/lib/stdlib.php");
2414 // Function to create better user passwords (much larger keyspace),
2415 // suitable for user passwords.
2416 // Sequence of random ASCII numbers, letters and some special chars.
2417 // Note: There exist other algorithms for easy-to-remember passwords.
2418 function random_good_password ($minlength = 5, $maxlength = 8) {
2420 // assume ASCII ordering (not valid on EBCDIC systems!)
2421 $valid_chars = "!#%&+-.0123456789=@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz";
2422 $start = ord($valid_chars);
2423 $end = ord(substr($valid_chars,-1));
2425 if (function_exists('mt_rand')) // mersenne twister
2426 $length = mt_rand($minlength, $maxlength);
2427 else // the usually bad glibc rand()
2428 $length = rand($minlength, $maxlength);
2429 while ($length > 0) {
2430 if (function_exists('mt_rand'))
2431 $newchar = mt_rand($start, $end);
2433 $newchar = rand($start, $end);
2434 if (! strrpos($valid_chars,$newchar) ) continue; // skip holes
2435 $newpass .= sprintf("%c", $newchar);
2442 function printArray($a) {
2443 echo "<hr />\n<pre>\n";
2445 echo "\n</pre>\n<hr />\n";
2448 // end of class definitions
2449 /////////////////////////////
2450 // begin auto generation code
2452 if (!function_exists('is_a')) {
2453 function is_a($object, $class) {
2454 $class = strtolower($class);
2455 return (get_class($object) == $class) or is_subclass_of($object, $class);
2460 if (!empty($HTTP_POST_VARS['action'])
2461 and $HTTP_POST_VARS['action'] == 'make_config'
2462 and !empty($HTTP_POST_VARS['ADMIN_USER'])
2463 and !empty($HTTP_POST_VARS['ADMIN_PASSWD'])
2467 $timestamp = date ('dS of F, Y H:i:s');
2470 ; This is a local configuration file for PhpWiki.
2471 ; It was automatically generated by the configurator script
2472 ; on the $timestamp.
2477 $posted = $GLOBALS['HTTP_POST_VARS'];
2478 /*if (defined('DEBUG'))
2479 printArray($GLOBALS['HTTP_POST_VARS']);*/
2481 foreach ($properties as $option_name => $a) {
2482 $posted_value = stripslashes($posted[$a->config_item_name]);
2483 $config .= $properties[$option_name]->get_config($posted_value);
2488 if (is_writable($fs_config_file)) {
2489 // We first check if the config-file exists.
2490 if (file_exists($fs_config_file)) {
2491 // We make a backup copy of the file
2492 $new_filename = preg_replace('/\.ini$/', '-' . time() . '.ini', $fs_config_file);
2493 if (@copy($fs_config_file, $new_filename)) {
2494 $fp = @fopen($fs_config_file, 'w');
2497 $fp = @fopen($fs_config_file, 'w');
2505 fputs($fp, $config);
2507 echo "<p>The configuration was written to <code><b>$config_file</b></code>.</p>\n";
2508 if ($new_filename) {
2509 echo "<p>A backup was made to <code><b>$new_filename</b></code>.</p>\n";
2511 ; //echo "<p><strong>You must rename or copy this</strong> <code><b>$config_file</b></code> <strong>file to</strong> <code><b>config/config.ini</b></code>.</p>\n";
2514 echo "<p>The configuration file could <b>not</b> be written.<br />\n",
2515 " You should copy the above configuration to a file, ",
2516 "and manually save it as <code><b>config/config.ini</b></code>.</p>\n";
2519 echo "<hr />\n<p>Here's the configuration file based on your answers:</p>\n";
2520 echo "<form method=\"get\" action=\"", $configurator, "\">\n";
2521 echo "<textarea id='config-output' readonly='readonly' style='width:100%;' rows='30' cols='100'>\n";
2522 echo htmlentities($config);
2523 echo "</textarea></form>\n";
2526 echo "<p>To make any corrections, <a href=\"configurator.php\">edit the settings again</a>.</p>\n";
2528 } else { // first time or create password
2529 $posted = $GLOBALS['HTTP_POST_VARS'];
2530 // No action has been specified - we make a form.
2533 <form action="',$configurator,'" method="post">
2534 <input type="hidden" name="action" value="make_config" />
2535 <table cellpadding="4" cellspacing="0">
2538 while (list($property, $obj) = each($properties)) {
2539 echo $obj->get_instructions($property);
2540 if ($h = $obj->get_html()) {
2541 if (defined('DEBUG') and DEBUG) $h = get_class($obj) . "<br />\n" . $h;
2542 echo "<td>".$h."</td>\n";
2549 <p><input type="submit" id="submit" value="Save ',$config_file,'" /> <input type="reset" value="Clear" /></p>