]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/upgrade.php
rename genericQuery to genericSqlQuery
[SourceForge/phpwiki.git] / lib / upgrade.php
1 <?php //-*-php-*-
2 rcs_id('$Id: upgrade.php,v 1.25 2004-09-06 08:28:00 rurban Exp $');
3
4 /*
5  Copyright 2004 $ThePhpWikiProgrammingTeam
6
7  This file is part of PhpWiki.
8
9  PhpWiki is free software; you can redistribute it and/or modify
10  it under the terms of the GNU General Public License as published by
11  the Free Software Foundation; either version 2 of the License, or
12  (at your option) any later version.
13
14  PhpWiki is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  GNU General Public License for more details.
18
19  You should have received a copy of the GNU General Public License
20  along with PhpWiki; if not, write to the Free Software
21  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  */
23
24
25 /**
26  * Upgrade the WikiDB and config settings after installing a new 
27  * PhpWiki upgrade.
28  * Status: experimental, no queries for verification yet, no db update,
29  *         no merge conflict
30  *
31  * Installation on an existing PhpWiki database needs some 
32  * additional worksteps. Each step will require multiple pages.
33  *
34  * This is the plan:
35  *  1. Check for new or changed database schema and update it 
36  *     according to some predefined upgrade tables. (medium)
37  *  2. Check for new or changed (localized) pgsrc/ pages and ask 
38  *     for upgrading these. Check timestamps, upgrade silently or 
39  *     show diffs if existing. Overwrite or merge (easy)
40  *  3. Check for new or changed or deprecated index.php/config.ini settings
41  *     and help in upgrading these. (hard)
42  *  3a Convert old-style index.php into config/config.ini. (easy)
43  *  4. Check for changed plugin invocation arguments. (hard)
44  *  5. Check for changed theme variables. (hard)
45  *  6. Convert the automatic update to a class-based multi-page 
46  *     version. (hard)
47
48  * TODO: overwrite=1 link on edit conflicts at end of page to overwrite all.
49  *
50  * @author: Reini Urban
51  */
52 require_once("lib/loadsave.php");
53 //define('DBADMIN_USER','rurban');
54 //define('DBADMIN_PASSWD','');
55
56 /**
57  * TODO: check for the pgsrc_version number, not the revision mtime only
58  */
59 function doPgsrcUpdate(&$request,$pagename,$path,$filename) {
60     $dbi = $request->getDbh(); 
61     $page = $dbi->getPage($pagename);
62     if ($page->exists()) {
63         // check mtime: update automatically if pgsrc is newer
64         $rev = $page->getCurrentRevision();
65         $page_mtime = $rev->get('mtime');
66         $data  = implode("", file($path."/".$filename));
67         if (($parts = ParseMimeifiedPages($data))) {
68             usort($parts, 'SortByPageVersion');
69             reset($parts);
70             $pageinfo = $parts[0];
71             $stat  = stat($path."/".$filename);
72             $new_mtime = @$pageinfo['versiondata']['mtime'];
73             if (!$new_mtime)
74                 $new_mtime = @$pageinfo['versiondata']['lastmodified'];
75             if (!$new_mtime)
76                 $new_mtime = @$pageinfo['pagedata']['date'];
77             if (!$new_mtime)
78                 $new_mtime = $stat[9];
79             if ($new_mtime > $page_mtime) {
80                 echo "$path/$pagename: ",_("newer than the existing page."),
81                     _(" replace "),"($new_mtime &gt; $page_mtime)","<br />\n";
82                 LoadAny($request,$path."/".$filename);
83                 echo "<br />\n";
84             } else {
85                 echo "$path/$pagename: ",_("older than the existing page."),
86                     _(" skipped"),".<br />\n";
87             }
88         } else {
89             echo "$path/$pagename: ",("unknown format."),
90                     _(" skipped"),".<br />\n";
91         }
92     } else {
93         echo sprintf(_("%s does not exist"),$pagename),"<br />\n";
94         LoadAny($request,$path."/".$filename);
95         echo "<br />\n";
96     }
97 }
98
99 /** need the english filename (required precondition: urlencode == urldecode)
100  *  returns the plugin name.
101  */ 
102 function isActionPage($filename) {
103     static $special = array("DebugInfo"         => "_BackendInfo",
104                             "PhpWikiRecentChanges" => "RssFeed",
105                             "ProjectSummary"    => "RssFeed",
106                             "RecentReleases"    => "RssFeed",
107                             );
108     $base = preg_replace("/\..{1,4}$/","",basename($filename));
109     if (isset($special[$base])) return $special[$base];
110     if (FindFile("lib/plugin/".$base.".php",true)) return $base;
111     else return false;
112 }
113
114 function CheckActionPageUpdate(&$request) {
115     echo "<h3>",_("check for necessary ActionPage updates"),"</h3>\n";
116     $dbi = $request->getDbh(); 
117     $path = FindFile('pgsrc');
118     $pgsrc = new fileSet($path);
119     // most actionpages have the same name as the plugin
120     $loc_path = FindLocalizedFile('pgsrc');
121     foreach ($pgsrc->getFiles() as $filename) {
122         if (substr($filename,-1,1) == '~') continue;
123         $pagename = urldecode($filename);
124         if (isActionPage($filename)) {
125             $translation = gettext($pagename);
126             if ($translation == $pagename)
127                 doPgsrcUpdate($request, $pagename, $path, $filename);
128             elseif (FindLocalizedFile('pgsrc/'.urlencode($translation),1))
129                 doPgsrcUpdate($request, $translation, $loc_path, 
130                               urlencode($translation));
131             else
132                 doPgsrcUpdate($request, $pagename, $path, $filename);
133         }
134     }
135 }
136
137 // see loadsave.php for saving new pages.
138 function CheckPgsrcUpdate(&$request) {
139     echo "<h3>",_("check for necessary pgsrc updates"),"</h3>\n";
140     $dbi = $request->getDbh(); 
141     $path = FindLocalizedFile(WIKI_PGSRC);
142     $pgsrc = new fileSet($path);
143     // fixme: verification, ...
144     $isHomePage = false;
145     foreach ($pgsrc->getFiles() as $filename) {
146         if (substr($filename,-1,1) == '~') continue;
147         $pagename = urldecode($filename);
148         // don't ever update the HomePage
149         if (defined(HOME_PAGE))
150             if ($pagename == HOME_PAGE) $isHomePage = true;
151         else
152             if ($pagename == _("HomePage")) $isHomePage = true;
153         if ($pagename == "HomePage") $isHomePage = true;
154         if ($isHomePage) {
155             echo "$path/$pagename: ",_("always skip the HomePage."),
156                 _(" skipped"),".<br />\n";
157             $isHomePage = false;
158             continue;
159         }
160         if (!isActionPage($filename)) {
161             doPgsrcUpdate($request,$pagename,$path,$filename);
162         }
163     }
164     return;
165 }
166
167 /**
168  * TODO: Search table definition in appropriate schema
169  *       and create it.
170  * Supported: mysql and generic SQL, for ADODB and PearDB.
171  */
172 function installTable(&$dbh, $table, $backend_type) {
173     global $DBParams;
174     if (!in_array($DBParams['dbtype'],array('SQL','ADODB'))) return;
175     echo _("MISSING")," ... \n";
176     $backend = &$dbh->_backend->_dbh;
177     /*
178     $schema = findFile("schemas/${backend_type}.sql");
179     if (!$schema) {
180         echo "  ",_("FAILED"),": ",sprintf(_("no schema %s found"),"schemas/${backend_type}.sql")," ... <br />\n";
181         return false;
182     }
183     */
184     extract($dbh->_backend->_table_names);
185     $prefix = isset($DBParams['prefix']) ? $DBParams['prefix'] : '';
186     switch ($table) {
187     case 'session':
188         assert($session_tbl);
189         if ($backend_type == 'mysql') {
190             $dbh->genericSqlQuery("
191 CREATE TABLE $session_tbl (
192         sess_id         CHAR(32) NOT NULL DEFAULT '',
193         sess_data       BLOB NOT NULL,
194         sess_date       INT UNSIGNED NOT NULL,
195         sess_ip         CHAR(15) NOT NULL,
196         PRIMARY KEY (sess_id),
197         INDEX (sess_date)
198 )");
199         } else {
200             $dbh->genericSqlQuery("
201 CREATE TABLE $session_tbl (
202         sess_id         CHAR(32) NOT NULL DEFAULT '',
203         sess_data       ".($backend_type == 'pgsql'?'TEXT':'BLOB')." NOT NULL,
204         sess_date       INT,
205         sess_ip         CHAR(15) NOT NULL
206 )");
207             $dbh->genericSqlQuery("CREATE UNIQUE INDEX sess_id ON $session_tbl (sess_id)");
208         }
209         $dbh->genericSqlQuery("CREATE INDEX sess_date on session (sess_date)");
210         break;
211     case 'user':
212         $user_tbl = $prefix.'user';
213         if ($backend_type == 'mysql') {
214             $dbh->genericSqlQuery("
215 CREATE TABLE $user_tbl (
216         userid  CHAR(48) BINARY NOT NULL UNIQUE,
217         passwd  CHAR(48) BINARY DEFAULT '',
218         PRIMARY KEY (userid)
219 )");
220         } else {
221             $dbh->genericSqlQuery("
222 CREATE TABLE $user_tbl (
223         userid  CHAR(48) NOT NULL,
224         passwd  CHAR(48) DEFAULT ''
225 )");
226             $dbh->genericSqlQuery("CREATE UNIQUE INDEX userid ON $user_tbl (userid)");
227         }
228         break;
229     case 'pref':
230         $pref_tbl = $prefix.'pref';
231         if ($backend_type == 'mysql') {
232             $dbh->genericSqlQuery("
233 CREATE TABLE $pref_tbl (
234         userid  CHAR(48) BINARY NOT NULL UNIQUE,
235         prefs   TEXT NULL DEFAULT '',
236         PRIMARY KEY (userid)
237 )");
238         } else {
239             $dbh->genericSqlQuery("
240 CREATE TABLE $pref_tbl (
241         userid  CHAR(48) NOT NULL,
242         prefs   TEXT NULL DEFAULT '',
243 )");
244             $dbh->genericSqlQuery("CREATE UNIQUE INDEX userid ON $pref_tbl (userid)");
245         }
246         break;
247     case 'member':
248         $member_tbl = $prefix.'member';
249         if ($backend_type == 'mysql') {
250             $dbh->genericSqlQuery("
251 CREATE TABLE $member_tbl (
252         userid    CHAR(48) BINARY NOT NULL,
253         groupname CHAR(48) BINARY NOT NULL DEFAULT 'users',
254         INDEX (userid),
255         INDEX (groupname)
256 )");
257         } else {
258             $dbh->genericSqlQuery("
259 CREATE TABLE $member_tbl (
260         userid    CHAR(48) NOT NULL,
261         groupname CHAR(48) NOT NULL DEFAULT 'users',
262 )");
263             $dbh->genericSqlQuery("CREATE INDEX userid ON $member_tbl (userid)");
264             $dbh->genericSqlQuery("CREATE INDEX groupname ON $member_tbl (groupname)");
265         }
266         break;
267     case 'rating':
268         $rating_tbl = $prefix.'rating';
269         if ($backend_type == 'mysql') {
270             $dbh->genericSqlQuery("
271 CREATE TABLE $rating_tbl (
272         dimension INT(4) NOT NULL,
273         raterpage INT(11) NOT NULL,
274         rateepage INT(11) NOT NULL,
275         ratingvalue FLOAT NOT NULL,
276         rateeversion INT(11) NOT NULL,
277         tstamp TIMESTAMP(14) NOT NULL,
278         PRIMARY KEY (dimension, raterpage, rateepage)
279 )");
280         } else {
281             $dbh->genericSqlQuery("
282 CREATE TABLE $rating_tbl (
283         dimension INT(4) NOT NULL,
284         raterpage INT(11) NOT NULL,
285         rateepage INT(11) NOT NULL,
286         ratingvalue FLOAT NOT NULL,
287         rateeversion INT(11) NOT NULL,
288         tstamp TIMESTAMP(14) NOT NULL,
289 )");
290             $dbh->genericSqlQuery("CREATE UNIQUE INDEX rating ON $rating_tbl (dimension, raterpage, rateepage)");
291         }
292         break;
293     }
294     echo "  ",_("CREATED"),"<br />\n";
295 }
296
297 /**
298  * currently update only session, user, pref and member
299  * jeffs-hacks database api (around 1.3.2) later
300  *   people should export/import their pages if using that old versions.
301  */
302 function CheckDatabaseUpdate(&$request) {
303     global $DBParams, $DBAuthParams;
304     if (!in_array($DBParams['dbtype'], array('SQL','ADODB'))) return;
305     echo "<h3>",_("check for necessary database updates"),"</h3>\n";
306     if (defined('DBADMIN_USER') and DBADMIN_USER) {
307         // if need to connect as the root user, for alter permissions
308         $AdminParams = $DBParams;
309         if ($DBParams['dbtype'] == 'SQL')
310             $dsn = DB::parseDSN($AdminParams['dsn']);
311         else
312             $dsn = parseDSN($AdminParams['dsn']);
313         $AdminParams['dsn'] = sprintf("%s://%s:%s@%s/%s",
314                                       $dsn['phptype'],
315                                       DBADMIN_USER,
316                                       DBADMIN_PASSWD,
317                                       $dsn['hostspec'],
318                                       $dsn['database']);
319         $dbh = WikiDB::open($AdminParams);
320     } else {
321         $dbh = &$request->_dbi;
322     }
323     $tables = $dbh->_backend->listOfTables();
324     $backend_type = $dbh->_backend->backendType();
325     $prefix = isset($DBParams['prefix']) ? $DBParams['prefix'] : '';
326     extract($dbh->_backend->_table_names);
327     foreach (explode(':','session:user:pref:member') as $table) {
328         echo sprintf(_("check for table %s"), $table)," ...";
329         if (!in_array($prefix.$table, $tables)) {
330             installTable($dbh, $table, $backend_type);
331         } else {
332             echo _("OK")," <br />\n";
333         }
334     }
335     $backend = &$dbh->_backend->_dbh;
336     // 1.3.8 added session.sess_ip
337     if (phpwiki_version() >= 1030.08 and USE_DB_SESSION and isset($request->_dbsession)) {
338         echo _("check for new session.sess_ip column")," ... ";
339         $database = $dbh->_backend->database();
340         assert(!empty($DBParams['db_session_table']));
341         $session_tbl = $prefix . $DBParams['db_session_table'];
342         $sess_fields = $dbh->_backend->listOfFields($database, $session_tbl);
343         if (!strstr(strtolower(join(':', $sess_fields)),"sess_ip")) {
344             // TODO: postgres test (should be able to add columns at the end, but not in between)
345             echo "<b>",_("ADDING"),"</b>"," ... ";              
346             $dbh->genericSqlQuery("ALTER TABLE $session_tbl ADD sess_ip CHAR(15) NOT NULL");
347             $dbh->genericSqlQuery("CREATE INDEX sess_date ON $session_tbl (sess_date)");
348         } else {
349             echo _("OK");
350         }
351         echo "<br />\n";
352     }
353     // 1.3.10 mysql requires page.id auto_increment
354     // mysql, mysqli or mysqlt
355     if (phpwiki_version() >= 1030.099 and substr($backend_type,0,5) == 'mysql') {
356         echo _("check for page.id auto_increment flag")," ...";
357         assert(!empty($page_tbl));
358         $database = $dbh->_backend->database();
359         $fields = mysql_list_fields($database, $page_tbl, $dbh->_backend->connection());
360         $columns = mysql_num_fields($fields); 
361         for ($i = 0; $i < $columns; $i++) {
362             if (mysql_field_name($fields, $i) == 'id') {
363                 $flags = mysql_field_flags($fields, $i);
364                 //DONE: something was wrong with ADODB here.
365                 if (!strstr(strtolower($flags), "auto_increment")) {
366                     echo "<b>",_("ADDING"),"</b>"," ... ";
367                     // MODIFY col_def valid since mysql 3.22.16,
368                     // older mysql's need CHANGE old_col col_def
369                     $dbh->genericSqlQuery("ALTER TABLE $page_tbl CHANGE id id INT NOT NULL AUTO_INCREMENT");
370                     $fields = mysql_list_fields($database, $page_tbl);
371                     if (!strstr(strtolower(mysql_field_flags($fields, $i)), "auto_increment"))
372                         echo " <b><font color=\"red\">", _("FAILED"), "</font></b><br />\n";
373                     else     
374                         echo _("OK"), "<br />\n";
375                 } else {
376                     echo _("OK"), "<br />\n";                           
377                 }
378                 break;
379             }
380         }
381         mysql_free_result($fields);
382     }
383     // check for mysql 4.1.x/5.0.0a binary search problem.
384     //   http://bugs.mysql.com/bug.php?id=4398
385     // "select * from page where LOWER(pagename) like '%search%'" does not apply LOWER!
386     // confirmed for 4.1.0alpha,4.1.3-beta,5.0.0a; not yet tested for 4.1.2alpha,
387     // TODO: there's a known workaround, not yet applied. on windows only.
388     if (substr($backend_type,0,5) == 'mysql') {
389         echo _("check for mysql 4.1.x/5.0.0 binary search problem")," ...";
390         $result = mysql_query("SELECT VERSION()",$dbh->_backend->connection());
391         $row = mysql_fetch_row($result);
392         $mysql_version = $row[0];
393         $arr = explode('.',$mysql_version);
394         $version = (string)(($arr[0] * 100) + $arr[1]) . "." . (integer)$arr[2];
395         if ($version >= 401.0) {
396             $dbh->genericSqlQuery("ALTER TABLE $page_tbl CHANGE pagename pagename VARCHAR(100) NOT NULL;");
397             echo sprintf(_("version <em>%s</em> <b>FIXED</b>"), $mysql_version),"<br />\n";     
398         } else {
399             echo sprintf(_("version <em>%s</em> not affected"), $mysql_version),"<br />\n";
400         }
401     }
402     return;
403 }
404
405 function fixConfigIni($match, $new) {
406     $file = FindFile("config/config.ini");
407     $found = false;
408     if (is_writable($file)) {
409         $in = fopen($file,"rb");
410         $out = fopen($tmp = tempnam(FindFile("uploads"),"cfg"),"wb");
411         if (isWindows())
412             $tmp = str_replace("/","\\",$tmp);
413         while ($s = fgets($in)) {
414             if (preg_match($match, $s)) {
415                 $s = $new . (isWindows() ? "\r\n" : "\n");
416                 $found = true;
417             }
418             fputs($out, $s);
419         }
420         fclose($in);
421         fclose($out);
422         if (!$found) {
423             echo " <b><font color=\"red\">",_("FAILED"),"</font></b>: ",
424                 sprintf(_("%s not found"), $match);
425             unlink($out);
426         } else {
427             @unlink("$file.bak");
428             @rename($file,"$file.bak");
429             if (rename($tmp, $file))
430                 echo " <b>",_("FIXED"),"</b>";
431             else {
432                 echo " <b>",_("FAILED"),"</b>: ";
433                 sprintf(_("couldn't move %s to %s"), $tmp, $file);
434                 return false;
435             }
436         }
437         return $found;
438     } else {
439         echo " <b><font color=\"red\">",_("FAILED"),"</font></b>: ",
440             sprintf(_("%s is not writable"), $file);
441         return false;
442     }
443 }
444
445 function CheckConfigUpdate(&$request) {
446     echo "<h3>",_("check for necessary config updates"),"</h3>\n";
447     echo _("check for old CACHE_CONTROL = NONE")," ... ";
448     if (defined('CACHE_CONTROL') and CACHE_CONTROL == '') {
449         echo "<br />&nbsp;&nbsp;",_("CACHE_CONTROL is set to 'NONE', and must be changed to 'NO_CACHE'")," ...";
450         fixConfigIni("/^\s*CACHE_CONTROL\s*=\s*NONE/","CACHE_CONTROL = NO_CACHE");
451     } else {
452         echo _("OK");
453     }
454     echo "<br />\n";
455 }
456
457 /**
458  * TODO:
459  *
460  * Upgrade: Base class for multipage worksteps
461  * identify, validate, display options, next step
462  */
463 class Upgrade {
464 }
465
466 class Upgrade_CheckPgsrc extends Upgrade {
467 }
468
469 class Upgrade_CheckDatabaseUpdate extends Upgrade {
470 }
471
472 // TODO: At which step are we? 
473 // validate and do it again or go on with next step.
474
475 /** entry function from lib/main.php
476  */
477 function DoUpgrade($request) {
478
479     if (!$request->_user->isAdmin()) {
480         $request->_notAuthorized(WIKIAUTH_ADMIN);
481         $request->finish(
482                          HTML::div(array('class' => 'disabled-plugin'),
483                                    fmt("Upgrade disabled: user != isAdmin")));
484         return;
485     }
486
487     StartLoadDump($request, _("Upgrading this PhpWiki"));
488     CheckActionPageUpdate($request);
489     CheckDatabaseUpdate($request);
490     CheckPgsrcUpdate($request);
491     //CheckThemeUpdate($request);
492     CheckConfigUpdate($request);
493     EndLoadDump($request);
494 }
495
496
497 /**
498  $Log: not supported by cvs2svn $
499  Revision 1.24  2004/07/05 13:56:22  rurban
500  sqlite autoincrement fix
501
502  Revision 1.23  2004/07/04 10:28:06  rurban
503  DBADMIN_USER fix
504
505  Revision 1.22  2004/07/03 17:21:28  rurban
506  updated docs: submitted new mysql bugreport (#1491 did not fix it)
507
508  Revision 1.21  2004/07/03 16:51:05  rurban
509  optional DBADMIN_USER:DBADMIN_PASSWD for action=upgrade (if no ALTER permission)
510  added atomic mysql REPLACE for PearDB as in ADODB
511  fixed _lock_tables typo links => link
512  fixes unserialize ADODB bug in line 180
513
514  Revision 1.20  2004/07/03 14:48:18  rurban
515  Tested new mysql 4.1.3-beta: binary search bug as fixed.
516  => fixed action=upgrade,
517  => version check in PearDB also (as in ADODB)
518
519  Revision 1.19  2004/06/19 12:19:09  rurban
520  slightly improved docs
521
522  Revision 1.18  2004/06/19 11:47:17  rurban
523  added CheckConfigUpdate: CACHE_CONTROL = NONE => NO_CACHE
524
525  Revision 1.17  2004/06/17 11:31:50  rurban
526  check necessary localized actionpages
527
528  Revision 1.16  2004/06/16 10:38:58  rurban
529  Disallow refernces in calls if the declaration is a reference
530  ("allow_call_time_pass_reference clean").
531    PhpWiki is now allow_call_time_pass_reference = Off clean,
532    but several external libraries may not.
533    In detail these libs look to be affected (not tested):
534    * Pear_DB odbc
535    * adodb oracle
536
537  Revision 1.15  2004/06/07 19:50:40  rurban
538  add owner field to mimified dump
539
540  Revision 1.14  2004/06/07 18:38:18  rurban
541  added mysql 4.1.x search fix
542
543  Revision 1.13  2004/06/04 20:32:53  rurban
544  Several locale related improvements suggested by Pierrick Meignen
545  LDAP fix by John Cole
546  reanable admin check without ENABLE_PAGEPERM in the admin plugins
547
548  Revision 1.12  2004/05/18 13:59:15  rurban
549  rename simpleQuery to genericSqlQuery
550
551  Revision 1.11  2004/05/15 13:06:17  rurban
552  skip the HomePage, at first upgrade the ActionPages, then the database, then the rest
553
554  Revision 1.10  2004/05/15 01:19:41  rurban
555  upgrade prefix fix by Kai Krakow
556
557  Revision 1.9  2004/05/14 11:33:03  rurban
558  version updated to 1.3.11pre
559  upgrade stability fix
560
561  Revision 1.8  2004/05/12 10:49:55  rurban
562  require_once fix for those libs which are loaded before FileFinder and
563    its automatic include_path fix, and where require_once doesn't grok
564    dirname(__FILE__) != './lib'
565  upgrade fix with PearDB
566  navbar.tmpl: remove spaces for IE &nbsp; button alignment
567
568  Revision 1.7  2004/05/06 17:30:38  rurban
569  CategoryGroup: oops, dos2unix eol
570  improved phpwiki_version:
571    pre -= .0001 (1.3.10pre: 1030.099)
572    -p1 += .001 (1.3.9-p1: 1030.091)
573  improved InstallTable for mysql and generic SQL versions and all newer tables so far.
574  abstracted more ADODB/PearDB methods for action=upgrade stuff:
575    backend->backendType(), backend->database(),
576    backend->listOfFields(),
577    backend->listOfTables(),
578
579  Revision 1.6  2004/05/03 15:05:36  rurban
580  + table messages
581
582  Revision 1.4  2004/05/02 21:26:38  rurban
583  limit user session data (HomePageHandle and auth_dbi have to invalidated anyway)
584    because they will not survive db sessions, if too large.
585  extended action=upgrade
586  some WikiTranslation button work
587  revert WIKIAUTH_UNOBTAINABLE (need it for main.php)
588  some temp. session debug statements
589
590  Revision 1.3  2004/04/29 22:33:30  rurban
591  fixed sf.net bug #943366 (Kai Krakow)
592    couldn't load localized url-undecoded pagenames
593
594  Revision 1.2  2004/03/12 15:48:07  rurban
595  fixed explodePageList: wrong sortby argument order in UnfoldSubpages
596  simplified lib/stdlib.php:explodePageList
597
598  */
599
600 // For emacs users
601 // Local Variables:
602 // mode: php
603 // tab-width: 8
604 // c-basic-offset: 4
605 // c-hanging-comment-ender-p: nil
606 // indent-tabs-mode: nil
607 // End:
608 ?>