2 rcs_id('$Id: upgrade.php,v 1.59 2007-06-09 18:57:44 rurban Exp $');
4 Copyright 2004,2005,2006,2007 $ThePhpWikiProgrammingTeam
6 This file is part of PhpWiki.
8 PhpWiki is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 PhpWiki is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with PhpWiki; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 * Upgrade existing WikiDB and config settings after installing a new PhpWiki sofwtare version.
25 * Status: almost no queries for verification.
26 * simple merge conflict resolution, or Overwrite All.
28 * Installation on an existing PhpWiki database needs some
29 * additional worksteps. Each step will require multiple pages.
32 * 1. Check for new or changed database schema and update it
33 * according to some predefined upgrade tables. (medium, complete)
34 * 2. Check for new or changed (localized) pgsrc/ pages and ask
35 * for upgrading these. Check timestamps, upgrade silently or
36 * show diffs if existing. Overwrite or merge (easy, complete)
37 * 3. Check for new or changed or deprecated index.php/config.ini settings
38 * and help in upgrading these. (for newer changes since 1.3.11, not yet)
39 * 3a. Convert old-style index.php into config/config.ini. (easy, not yet)
40 * 4. Check for changed plugin invocation arguments. (medium, done)
41 * 5. Check for changed theme variables. (hard, not yet)
42 * 6. Convert the single-request upgrade to a class-based multi-page
45 * Done: overwrite=1 link on edit conflicts at first occurence "Overwrite all".
47 * @author: Reini Urban
49 require_once("lib/loadsave.php");
53 function Upgrade (&$request) {
54 $this->request =& $request;
55 $this->dbi =& $request->_dbi; // no reference for dbadmin ?
56 $this->phpwiki_version = $this->current_db_version = phpwiki_version();
57 //$this->current_db_version = 1030.13; // should be stored in the db. should be phpwiki_version
59 $this->db_version = $this->dbi->get_db_version();
60 $this->isSQL = $this->dbi->_backend->isSQL();
64 * TODO: check for the pgsrc_version number, not the revision mtime only
66 function doPgsrcUpdate($pagename, $path, $filename) {
67 $page = $this->dbi->getPage($pagename);
68 if ($page->exists()) {
69 // check mtime: update automatically if pgsrc is newer
70 $rev = $page->getCurrentRevision();
71 $page_mtime = $rev->get('mtime');
72 $data = implode("", file($path."/".$filename));
73 if (($parts = ParseMimeifiedPages($data))) {
74 usort($parts, 'SortByPageVersion');
76 $pageinfo = $parts[0];
77 $stat = stat($path."/".$filename);
78 $new_mtime = @$pageinfo['versiondata']['mtime'];
80 $new_mtime = @$pageinfo['versiondata']['lastmodified'];
82 $new_mtime = @$pageinfo['pagedata']['date'];
84 $new_mtime = $stat[9];
85 if ($new_mtime > $page_mtime) {
86 echo "$path/$pagename: ",_("newer than the existing page."),
87 _(" replace "),"($new_mtime > $page_mtime)","<br />\n";
88 LoadAny($this->request, $path."/".$filename);
91 echo "$path/$pagename: ",_("older than the existing page."),
92 _(" skipped"),".<br />\n";
95 echo "$path/$pagename: ",("unknown format."),
96 _(" skipped"),".<br />\n";
99 echo sprintf(_("%s does not exist"),$pagename),"<br />\n";
100 LoadAny($this->request, $path."/".$filename);
106 * If a matching pgsrc => pluginname exists
107 * Need the english filename (required precondition: urlencode == urldecode).
108 * Returns the plugin name.
110 function isActionPage($filename) {
111 static $special = array("DebugInfo" => "_BackendInfo",
112 "PhpWikiRecentChanges" => "RssFeed",
113 "ProjectSummary" => "RssFeed",
114 "RecentReleases" => "RssFeed",
115 "InterWikiMap" => "InterWikiMap",
117 $base = preg_replace("/\..{1,4}$/","",basename($filename));
118 if (isset($special[$base])) return $special[$base];
119 if (FindFile("lib/plugin/".$base.".php",true)) return $base;
123 function CheckActionPageUpdate() {
124 echo "<h3>",sprintf(_("check for necessary %s updates"),
125 _("ActionPage")),"</h3>\n";
126 // 1.3.13 before we pull in all missing pages, we rename existing ones
127 $this->_rename_page_helper(_("_AuthInfo"), _("DebugAuthInfo"));
128 // this is in some templates. so we keep the old name
129 //$this->_rename_page_helper($this->dbi, _("DebugInfo"), _("DebugBackendInfo"));
130 $this->_rename_page_helper(_("_GroupInfo"), _("GroupAuthInfo")); //never officially existed
131 $this->_rename_page_helper("InterWikiKarte", "InterWikiListe"); // german only
133 $path = FindFile('pgsrc');
134 $pgsrc = new fileSet($path);
135 // most actionpages have the same name as the plugin
136 $loc_path = FindLocalizedFile('pgsrc');
137 foreach ($pgsrc->getFiles() as $filename) {
138 if (substr($filename,-1,1) == '~') continue;
139 if (substr($filename,-5,5) == '.orig') continue;
140 $pagename = urldecode($filename);
141 if ($this->isActionPage($filename)) {
142 $translation = gettext($pagename);
143 if ($translation == $pagename)
144 $this->doPgsrcUpdate($pagename, $path, $filename);
145 elseif (FindLocalizedFile('pgsrc/'.urlencode($translation),1))
146 $this->doPgsrcUpdate($translation, $loc_path, urlencode($translation));
148 $this->doPgsrcUpdate($pagename, $path, $filename);
153 // see loadsave.php for saving new pages.
154 function CheckPgsrcUpdate() {
155 echo "<h3>",sprintf(_("check for necessary %s updates"),
157 if ($this->db_version < 1030.12200612) {
158 echo "<h4>",_("rename to Help: pages"),"</h4>\n";
160 $path = FindLocalizedFile(WIKI_PGSRC);
161 $pgsrc = new fileSet($path);
162 // fixme: verification, ...
164 foreach ($pgsrc->getFiles() as $filename) {
165 if (substr($filename,-1,1) == '~') continue;
166 if (substr($filename,-5,5) == '.orig') continue;
167 $pagename = urldecode($filename);
168 // don't ever update the HomePage
169 if (defined(HOME_PAGE))
170 if ($pagename == HOME_PAGE) $isHomePage = true;
172 if ($pagename == _("HomePage")) $isHomePage = true;
173 if ($pagename == "HomePage") $isHomePage = true;
175 echo "$path/$pagename: ",_("always skip the HomePage."),
176 _(" skipped"),".<br />\n";
180 if (!$this->isActionPage($filename)) {
181 // There're a lot of now unneeded pages around.
182 // At first rename the BlaPlugin pages to Help/<pagename> and then to the update.
183 if ($this->db_version < 1030.12200612) {
184 $this->_rename_to_help_page($pagename);
186 $this->doPgsrcUpdate($pagename,$path,$filename);
190 // Now check some theme specific pgsrc files (blog, wikilens, custom).
191 // WARNING: Also override the HomePage here.
193 $path = $WikiTheme->file("pgsrc");
194 $pgsrc = new fileSet($path);
195 if ($pgsrc->getFiles()) {
196 echo "<h3>",sprintf(_("check for additional theme %s updates"),
198 foreach ($pgsrc->getFiles() as $filename) {
199 if (substr($filename,-1,1) == '~') continue;
200 if (substr($filename,-5,5) == '.orig') continue;
201 $pagename = urldecode($filename);
202 $this->doPgsrcUpdate($pagename,$path,$filename);
208 function _rename_page_helper($oldname, $pagename) {
209 echo sprintf(_("rename %s to %s"), $oldname, $pagename)," ...";
210 if ($this->dbi->isWikiPage($oldname) and !$this->dbi->isWikiPage($pagename)) {
211 if ($this->dbi->_backend->rename_page($oldname, $pagename))
212 echo _("OK")," <br />\n";
214 echo " <b><font color=\"red\">", _("FAILED"), "</font></b>",
217 echo _(" skipped")," <br />\n";
221 function _rename_to_help_page($pagename) {
222 $newprefix = _("Help") . "/";
223 if (substr($pagename,0,strlen($newprefix)) != $newprefix) return;
224 $oldname = substr($pagename,strlen($newprefix));
225 $this->_rename_page_helper($oldname, $pagename);
229 * TODO: Search table definition in appropriate schema
231 * Supported: mysql and generic SQL, for ADODB and PearDB.
233 function installTable($table, $backend_type) {
235 if (!$this->isSQL) return;
236 echo _("MISSING")," ... \n";
237 $backend = &$this->dbi->_backend->_dbh;
239 $schema = findFile("schemas/${backend_type}.sql");
241 echo " ",_("FAILED"),": ",sprintf(_("no schema %s found"),
242 "schemas/${backend_type}.sql")," ... <br />\n";
246 extract($this->dbi->_backend->_table_names);
247 $prefix = isset($DBParams['prefix']) ? $DBParams['prefix'] : '';
250 assert($session_tbl);
251 if ($backend_type == 'mysql') {
252 $this->dbi->genericSqlQuery("
253 CREATE TABLE $session_tbl (
254 sess_id CHAR(32) NOT NULL DEFAULT '',
255 sess_data BLOB NOT NULL,
256 sess_date INT UNSIGNED NOT NULL,
257 sess_ip CHAR(15) NOT NULL,
258 PRIMARY KEY (sess_id),
262 $this->dbi->genericSqlQuery("
263 CREATE TABLE $session_tbl (
264 sess_id CHAR(32) NOT NULL DEFAULT '',
265 sess_data ".($backend_type == 'pgsql'?'TEXT':'BLOB')." NOT NULL,
267 sess_ip CHAR(15) NOT NULL
269 $this->dbi->genericSqlQuery("CREATE UNIQUE INDEX sess_id ON $session_tbl (sess_id)");
271 $this->dbi->genericSqlQuery("CREATE INDEX sess_date on session (sess_date)");
272 echo " ",_("CREATED");
275 $pref_tbl = $prefix.'pref';
276 if ($backend_type == 'mysql') {
277 $this->dbi->genericSqlQuery("
278 CREATE TABLE $pref_tbl (
279 userid CHAR(48) BINARY NOT NULL UNIQUE,
280 prefs TEXT NULL DEFAULT '',
284 $this->dbi->genericSqlQuery("
285 CREATE TABLE $pref_tbl (
286 userid CHAR(48) NOT NULL,
287 prefs TEXT NULL DEFAULT ''
289 $this->dbi->genericSqlQuery("CREATE UNIQUE INDEX userid ON $pref_tbl (userid)");
291 echo " ",_("CREATED");
294 $member_tbl = $prefix.'member';
295 if ($backend_type == 'mysql') {
296 $this->dbi->genericSqlQuery("
297 CREATE TABLE $member_tbl (
298 userid CHAR(48) BINARY NOT NULL,
299 groupname CHAR(48) BINARY NOT NULL DEFAULT 'users',
304 $this->dbi->genericSqlQuery("
305 CREATE TABLE $member_tbl (
306 userid CHAR(48) NOT NULL,
307 groupname CHAR(48) NOT NULL DEFAULT 'users'
309 $this->dbi->genericSqlQuery("CREATE INDEX userid ON $member_tbl (userid)");
310 $this->dbi->genericSqlQuery("CREATE INDEX groupname ON $member_tbl (groupname)");
312 echo " ",_("CREATED");
315 $rating_tbl = $prefix.'rating';
316 if ($backend_type == 'mysql') {
317 $this->dbi->genericSqlQuery("
318 CREATE TABLE $rating_tbl (
319 dimension INT(4) NOT NULL,
320 raterpage INT(11) NOT NULL,
321 rateepage INT(11) NOT NULL,
322 ratingvalue FLOAT NOT NULL,
323 rateeversion INT(11) NOT NULL,
324 tstamp TIMESTAMP(14) NOT NULL,
325 PRIMARY KEY (dimension, raterpage, rateepage)
328 $this->dbi->genericSqlQuery("
329 CREATE TABLE $rating_tbl (
330 dimension INT(4) NOT NULL,
331 raterpage INT(11) NOT NULL,
332 rateepage INT(11) NOT NULL,
333 ratingvalue FLOAT NOT NULL,
334 rateeversion INT(11) NOT NULL,
335 tstamp TIMESTAMP(14) NOT NULL
337 $this->dbi->genericSqlQuery("CREATE UNIQUE INDEX rating"
338 ." ON $rating_tbl (dimension, raterpage, rateepage)");
340 echo " ",_("CREATED");
343 $log_tbl = $prefix.'accesslog';
344 // fields according to http://www.outoforder.cc/projects/apache/mod_log_sql/docs-2.0/#id2756178
346 A User Agent agent varchar(255) Mozilla/4.0 (compat; MSIE 6.0; Windows)
347 a CGi request arguments request_args varchar(255) user=Smith&cart=1231&item=532
348 b Bytes transfered bytes_sent int unsigned 32561
349 c??? Text of cookie cookie varchar(255) Apache=sdyn.fooonline.net 1300102700823
350 f Local filename requested request_file varchar(255) /var/www/html/books-cycroad.html
351 H HTTP request_protocol request_protocol varchar(10) HTTP/1.1
352 h Name of remote host remote_host varchar(50) blah.foobar.com
353 I Request ID (from modd_unique_id) id char(19) POlFcUBRH30AAALdBG8
354 l Ident user info remote_logname varcgar(50) bobby
355 M Machine ID??? machine_id varchar(25) web01
356 m HTTP request method request_method varchar(10) GET
357 P httpd cchild PID child_pid smallint unsigned 3215
358 p http port server_port smallint unsigned 80
359 R Referer referer varchar(255) http://www.biglinks4u.com/linkpage.html
360 r Request in full form request_line varchar(255) GET /books-cycroad.html HTTP/1.1
361 S Time of request in UNIX time_t format time_stamp int unsigned 1005598029
362 T Seconds to service request request_duration smallint unsigned 2
363 t Time of request in human format request_time char(28) [02/Dec/2001:15:01:26 -0800]
364 U Request in simple form request_uri varchar(255) /books-cycroad.html
365 u User info from HTTP auth remote_user varchar(50) bobby
366 v Virtual host servicing the request virtual_host varchar(255)
368 $this->dbi->genericSqlQuery("
369 CREATE TABLE $log_tbl (
370 time_stamp int unsigned,
371 remote_host varchar(100),
372 remote_user varchar(50),
373 request_method varchar(10),
374 request_line varchar(255),
375 request_args varchar(255),
376 request_uri varchar(255),
377 request_time char(28),
378 status smallint unsigned,
379 bytes_sent smallint unsigned,
380 referer varchar(255),
382 request_duration float
384 $this->dbi->genericSqlQuery("CREATE INDEX log_time ON $log_tbl (time_stamp)");
385 $this->dbi->genericSqlQuery("CREATE INDEX log_host ON $log_tbl (remote_host)");
386 echo " ",_("CREATED");
393 * Update from ~1.3.4 to current.
394 * tables: Only session, user, pref and member
395 * jeffs-hacks database api (around 1.3.2) later:
396 * people should export/import their pages if using that old versions.
398 function CheckDatabaseUpdate() {
399 global $DBAuthParams;
401 echo "<h3>",sprintf(_("check for necessary %s updates"),
403 " - ", DATABASE_TYPE,"</h3>\n";
404 $dbadmin = $this->request->getArg('dbadmin');
407 if (isset($dbadmin['cancel'])) {
408 echo _("CANCEL")," <br />\n";
412 echo "db version: we want ", $this->current_db_version, "\n<br>";
413 echo "db version: we have ", $this->db_version, "\n<br>";
414 if ($this->db_version >= $this->current_db_version) {
415 echo _("OK"), "<br />\n";
420 $backend_type = $this->dbi->_backend->backendType();
421 echo "<h4>",_("Backend type: "),$backend_type,"</h4>\n";
422 $prefix = isset($DBParams['prefix']) ? $DBParams['prefix'] : '';
423 $tables = $this->dbi->_backend->listOfTables();
424 foreach (explode(':','session:pref:member') as $table) {
425 echo sprintf(_("check for table %s"), $table)," ...";
426 if (!in_array($prefix.$table, $tables)) {
427 $this->installTable($table, $backend_type);
429 echo _("OK")," <br />\n";
434 if ($this->phpwiki_version >= 1030.12200612 and $this->db_version < 1030.13) {
435 if ($this->isSQL and preg_match("/(pgsql|postgres)/", $backend_type)) {
436 trigger_error("You need to upgrade to schema/psql-initialize.sql manually!",
438 // $this->_upgrade_psql_tsearch2();
440 $this->_upgrade_relation_links();
443 if (ACCESS_LOG_SQL and $this->isSQL) {
444 $table = "accesslog";
445 echo sprintf(_("check for table %s"), $table)," ...";
446 if (!in_array($prefix.$table, $tables)) {
447 $this->installTable($table, $backend_type);
449 echo _("OK")," <br />\n";
452 if ($this->isSQL and (class_exists("RatingsUserFactory") or $this->dbi->isWikiPage(_("RateIt")))) {
454 echo sprintf(_("check for table %s"), $table)," ...";
455 if (!in_array($prefix.$table, $tables)) {
456 $this->installTable($table, $backend_type);
458 echo _("OK")," <br />\n";
461 $backend = &$this->dbi->_backend->_dbh;
463 extract($this->dbi->_backend->_table_names);
465 // 1.3.8 added session.sess_ip
466 if ($this->isSQL and $this->phpwiki_version >= 1030.08 and USE_DB_SESSION
467 and isset($this->request->_dbsession))
469 echo _("check for new session.sess_ip column")," ... ";
470 $database = $this->dbi->_backend->database();
471 assert(!empty($DBParams['db_session_table']));
472 $session_tbl = $prefix . $DBParams['db_session_table'];
473 $sess_fields = $this->dbi->_backend->listOfFields($database, $session_tbl);
476 } elseif (!strstr(strtolower(join(':', $sess_fields)), "sess_ip")) {
477 // TODO: postgres test (should be able to add columns at the end, but not in between)
478 echo "<b>",_("ADDING"),"</b>"," ... ";
479 $this->dbi->genericSqlQuery("ALTER TABLE $session_tbl ADD sess_ip CHAR(15) NOT NULL");
480 $this->dbi->genericSqlQuery("CREATE INDEX sess_date ON $session_tbl (sess_date)");
485 if (substr($backend_type,0,5) == 'mysql') {
486 // upgrade to 4.1.8 destroyed my session table:
487 // sess_id => varchar(10), sess_data => varchar(5). For others obviously also.
488 echo _("check for mysql session.sess_id sanity")," ... ";
489 $result = $this->dbi->genericSqlQuery("DESCRIBE $session_tbl");
490 if (DATABASE_TYPE == 'SQL') {
491 $iter = new WikiDB_backend_PearDB_generic_iter($backend, $result);
492 } elseif (DATABASE_TYPE == 'ADODB') {
493 $iter = new WikiDB_backend_ADODB_generic_iter($backend, $result,
494 array("Field", "Type", "Null", "Key", "Default", "Extra"));
495 } elseif (DATABASE_TYPE == 'PDO') {
496 $iter = new WikiDB_backend_PDO_generic_iter($backend, $result);
498 while ($col = $iter->next()) {
499 if ($col["Field"] == 'sess_id' and !strstr(strtolower($col["Type"]), 'char(32)')) {
500 $this->dbi->genericSqlQuery("ALTER TABLE $session_tbl CHANGE sess_id"
501 ." sess_id CHAR(32) NOT NULL");
502 echo "sess_id ", $col["Type"], " ", _("fixed"), " => CHAR(32) ";
504 if ($col["Field"] == 'sess_ip' and !strstr(strtolower($col["Type"]), 'char(15)')) {
505 $this->dbi->genericSqlQuery("ALTER TABLE $session_tbl CHANGE sess_ip"
506 ." sess_ip CHAR(15) NOT NULL");
507 echo "sess_ip ", $col["Type"], " ", _("fixed"), " => CHAR(15) ";
510 echo _("OK"), "<br />\n";
515 ALTER TABLE link ADD relation INT DEFAULT 0;
516 CREATE INDEX linkrelation ON link (relation);
519 // mysql >= 4.0.4 requires LOCK TABLE privileges
520 if (substr($backend_type,0,5) == 'mysql') {
521 echo _("check for mysql LOCK TABLE privilege")," ...";
522 $mysql_version = $this->dbi->_backend->_serverinfo['version'];
523 if ($mysql_version > 400.40) {
524 if (!empty($this->dbi->_backend->_parsedDSN))
525 $parseDSN = $this->dbi->_backend->_parsedDSN;
526 elseif (function_exists('parseDSN')) // ADODB or PDO
527 $parseDSN = parseDSN($DBParams['dsn']);
529 $parseDSN = DB::parseDSN($DBParams['dsn']);
530 $username = $this->dbi->_backend->qstr($parseDSN['username']);
532 $query = "SELECT lock_tables_priv FROM mysql.db WHERE user='$username'";
533 //mysql_select_db("mysql", $this->dbi->_backend->connection());
534 $db_fields = $this->dbi->_backend->listOfFields("mysql", "db");
535 if (!strstr(strtolower(join(':', $db_fields)), "lock_tables_priv")) {
536 echo join(':', $db_fields);
537 die("lock_tables_priv missing. The DB Admin must run mysql_fix_privilege_tables");
539 $row = $this->dbi->_backend->getRow($query);
540 if (isset($row[0]) and $row[0] == 'N') {
541 $this->dbi->genericSqlQuery("UPDATE mysql.db SET lock_tables_priv='Y'"
542 ." WHERE mysql.user='$username'");
543 $this->dbi->genericSqlQuery("FLUSH PRIVILEGES");
544 echo "mysql.db user='$username'", _("fixed"), "<br />\n";
547 $query = "SELECT lock_tables_priv FROM mysql.user WHERE user='$username'";
548 $row = $this->dbi->_backend->getRow($query);
549 if ($row and $row[0] == 'N') {
550 $this->dbi->genericSqlQuery("UPDATE mysql.user SET lock_tables_priv='Y'"
551 ." WHERE mysql.user='$username'");
552 $this->dbi->genericSqlQuery("FLUSH PRIVILEGES");
553 echo "mysql.user user='$username'", _("fixed"), "<br />\n";
555 echo " <b><font color=\"red\">", _("FAILED"), "</font></b>: ",
556 "Neither mysql.db nor mysql.user has a user='$username'"
557 ." or the lock_tables_priv field",
560 echo _("OK"), "<br />\n";
563 echo _("OK"), "<br />\n";
565 //mysql_select_db($this->dbi->_backend->database(), $this->dbi->_backend->connection());
567 echo sprintf(_("version <em>%s</em> not affected"), $mysql_version),"<br />\n";
571 // 1.3.10 mysql requires page.id auto_increment
572 // mysql, mysqli or mysqlt
573 if ($this->phpwiki_version >= 1030.099 and substr($backend_type,0,5) == 'mysql'
574 and DATABASE_TYPE != 'PDO')
576 echo _("check for mysql page.id auto_increment flag")," ...";
577 assert(!empty($page_tbl));
578 $database = $this->dbi->_backend->database();
579 $fields = mysql_list_fields($database, $page_tbl, $this->dbi->_backend->connection());
580 $columns = mysql_num_fields($fields);
581 for ($i = 0; $i < $columns; $i++) {
582 if (mysql_field_name($fields, $i) == 'id') {
583 $flags = mysql_field_flags($fields, $i);
584 //DONE: something was wrong with ADODB here.
585 if (!strstr(strtolower($flags), "auto_increment")) {
586 echo "<b>",_("ADDING"),"</b>"," ... ";
587 // MODIFY col_def valid since mysql 3.22.16,
588 // older mysql's need CHANGE old_col col_def
589 $this->dbi->genericSqlQuery("ALTER TABLE $page_tbl CHANGE id"
590 ." id INT NOT NULL AUTO_INCREMENT");
591 $fields = mysql_list_fields($database, $page_tbl);
592 if (!strstr(strtolower(mysql_field_flags($fields, $i)), "auto_increment"))
593 echo " <b><font color=\"red\">", _("FAILED"), "</font></b><br />\n";
595 echo _("OK"), "<br />\n";
597 echo _("OK"), "<br />\n";
602 mysql_free_result($fields);
605 // Check for mysql 4.1.x/5.0.0a binary search problem.
606 // http://bugs.mysql.com/bug.php?id=4398
607 // "select * from page where LOWER(pagename) like '%search%'" does not apply LOWER!
608 // Confirmed for 4.1.0alpha,4.1.3-beta,5.0.0a; not yet tested for 4.1.2alpha,
609 // On windows only, though utf8 would be useful elsewhere also.
610 // Illegal mix of collations (latin1_bin,IMPLICIT) and
611 // (utf8_general_ci, COERCIBLE) for operation '='])
612 if (isWindows() and substr($backend_type,0,5) == 'mysql') {
613 echo _("check for mysql 4.1.x/5.0.0 binary search on windows problem")," ...";
614 $mysql_version = $this->dbi->_backend->_serverinfo['version'];
615 if ($mysql_version < 401.0) {
616 echo sprintf(_("version <em>%s</em>"), $mysql_version)," ",
617 _("not affected"),"<br />\n";
618 } elseif ($mysql_version >= 401.6) { // FIXME: since which version?
619 $row = $this->dbi->_backend->getRow("SHOW CREATE TABLE $page_tbl");
620 $result = join(" ", $row);
621 if (strstr(strtolower($result), "character set")
622 and strstr(strtolower($result), "collate"))
624 echo _("OK"), "<br />\n";
626 //SET CHARACTER SET latin1
628 if ($charset == 'iso-8859-1') $charset = 'latin1';
629 $this->dbi->genericSqlQuery("ALTER TABLE $page_tbl CHANGE pagename "
630 ."pagename VARCHAR(100) "
631 ."CHARACTER SET '$charset' COLLATE '$charset"."_bin' NOT NULL");
632 echo sprintf(_("version <em>%s</em>"), $mysql_version),
633 " <b>",_("FIXED"),"</b>",
636 } elseif (DATABASE_TYPE != 'PDO') {
637 // check if already fixed
638 extract($this->dbi->_backend->_table_names);
639 assert(!empty($page_tbl));
640 $database = $this->dbi->_backend->database();
641 $fields = mysql_list_fields($database, $page_tbl, $this->dbi->_backend->connection());
642 $columns = mysql_num_fields($fields);
643 for ($i = 0; $i < $columns; $i++) {
644 if (mysql_field_name($fields, $i) == 'pagename') {
645 $flags = mysql_field_flags($fields, $i);
646 // I think it was fixed with 4.1.6, but I tested it only with 4.1.8
647 if ($mysql_version > 401.0 and $mysql_version < 401.6) {
648 // remove the binary flag
649 if (strstr(strtolower($flags), "binary")) {
650 // FIXME: on duplicate pagenames this will fail!
651 $this->dbi->genericSqlQuery("ALTER TABLE $page_tbl CHANGE pagename"
652 ." pagename VARCHAR(100) NOT NULL");
653 echo sprintf(_("version <em>%s</em>"), $mysql_version),
654 "<b>",_("FIXED"),"</b>"
663 if ($this->isSQL and ACCESS_LOG_SQL & 2) {
664 echo _("check for ACCESS_LOG_SQL passwords in POST requests")," ...";
665 // Don't display passwords in POST requests (up to 2005-02-04 12:03:20)
666 $res = $this->dbi->genericSqlIter("SELECT time_stamp, remote_host, " .
667 "request_args FROM ${prefix}accesslog WHERE request_args LIKE " .
668 "'%s:6:\"passwd\"%' AND request_args NOT LIKE '%s:6:\"passwd\";" .
669 "s:15:\"<not displayed>\"%'");
671 while ($row = $res->next()) {
672 $args = preg_replace("/(s:6:\"passwd\";s:15:\").*(\")/",
673 "$1<not displayed>$2", $row["request_args"]);
674 $ts = $row["time_stamp"];
675 $rh = $row["remote_host"];
676 $this->dbi->genericSqlQuery("UPDATE ${prefix}accesslog SET " .
677 "request_args='$args' WHERE time_stamp=$ts AND " .
678 "remote_host='$rh'");
682 echo "<b>",_("FIXED"),"</b>", "<br />\n";
684 echo _("OK"),"<br />\n";
686 if ($this->phpwiki_version >= 1030.13) {
687 echo _("check for ACCESS_LOG_SQL remote_host varchar(50)")," ...";
688 $database = $this->dbi->_backend->database();
689 $accesslog_tbl = $prefix . 'accesslog';
690 $fields = $this->dbi->_backend->listOfFields($database, $accesslog_tbl);
693 } elseif (strstr(strtolower(join(':', $sess_fields)), "remote_host")) {
694 // TODO: how to check size, already done?
695 echo "<b>",_("FIXING"),"remote_host</b>"," ... ";
696 $this->dbi->genericSqlQuery("ALTER TABLE $accesslog_tbl CHANGE remote_host VARCHAR(100)");
703 $this->_upgrade_cached_html();
705 if ($this->db_version < $this->current_db_version) {
706 $this->dbi->set_db_version($this->current_db_version);
707 $this->db_version = $this->dbi->get_db_version();
708 echo "db version: we have now ", $this->db_version," ";
709 echo _("OK"), "<br />\n";
717 * Filter SQL missing permissions errors.
719 * A wrong DBADMIN user will not be able to connect
720 * @see _is_false_error, ErrorManager
723 function _dbpermission_filter($err) {
724 if ( $err->isWarning() ) {
725 global $ErrorManager;
726 $this->error_caught = 1;
727 $ErrorManager->_postponed_errors[] = $err;
733 function _try_dbadmin_user ($user, $passwd) {
734 global $DBParams, $DBAuthParams;
735 $AdminParams = $DBParams;
736 if (DATABASE_TYPE == 'SQL')
737 $dsn = DB::parseDSN($AdminParams['dsn']);
739 $dsn = parseDSN($AdminParams['dsn']);
741 $AdminParams['dsn'] = sprintf("%s://%s:%s@%s/%s",
747 $AdminParams['_tryroot_from_upgrade'] = 1;
748 // add error handler to warn about missing permissions for DBADMIN_USER
749 global $ErrorManager;
750 $ErrorManager->pushErrorHandler(new WikiMethodCb($this, '_dbpermission_filter'));
751 $this->error_caught = 0;
752 $this->dbi = WikiDB::open($AdminParams);
753 if (!$this->error_caught) return true;
754 // FAILED: redo our connection with the wikiuser
755 $this->dbi = WikiDB::open($DBParams);
756 $ErrorManager->flushPostponedErrors();
757 $ErrorManager->popErrorHandler();
761 function _db_init () {
762 if (!$this->isSQL) return;
764 /* SQLite never needs admin params */
765 $backend_type = $this->dbi->_backend->backendType();
766 if (substr($backend_type,0,6)=="sqlite") {
769 $dbadmin_user = 'root';
770 if ($dbadmin = $this->request->getArg('dbadmin')) {
771 $dbadmin_user = $dbadmin['user'];
772 if (isset($dbadmin['cancel'])) {
774 } elseif (!empty($dbadmin_user)) {
775 if ($this->_try_dbadmin_user($dbadmin['user'], $dbadmin['passwd']))
778 } elseif (DBADMIN_USER) {
779 if ($this->_try_dbadmin_user(DBADMIN_USER, DBADMIN_PASSWD))
782 // Check if the privileges are enough. Need CREATE and ALTER perms.
783 // And on windows: SELECT FROM mysql, possibly: UPDATE mysql.
784 $form = HTML::form(array("method" => "post",
785 "action" => $this->request->getPostURL(),
786 "accept-charset"=>$GLOBALS['charset']),
787 HTML::p(_("Upgrade requires database privileges to CREATE and ALTER the phpwiki database."),
789 _("And on windows at least the privilege to SELECT FROM mysql, and possibly UPDATE mysql")),
790 HiddenInputs(array('action' => 'upgrade',
791 'overwrite' => $this->request->getArg('overwrite'))),
792 HTML::table(array("cellspacing"=>4),
793 HTML::tr(HTML::td(array('align'=>'right'),
794 _("DB admin user:")),
795 HTML::td(HTML::input(array('name'=>"dbadmin[user]",
798 'value'=>$dbadmin_user)))),
799 HTML::tr(HTML::td(array('align'=>'right'),
800 _("DB admin password:")),
801 HTML::td(HTML::input(array('name'=>"dbadmin[passwd]",
804 'maxlength'=>256)))),
805 HTML::tr(HTML::td(array('align'=>'center', 'colspan' => 2),
806 Button("submit:", _("Submit"), 'wikiaction'),
808 Button("submit:dbadmin[cancel]", _("Cancel"),
811 echo "</div><!-- content -->\n";
812 echo asXML(Template("bottom"));
813 echo "</body></html>\n";
814 $this->request->finish();
819 * if page.cached_html does not exists:
820 * put _cached_html from pagedata into a new seperate blob,
821 * not into the huge serialized string.
823 * It is only rarelely needed: for current page only, if-not-modified,
824 * but was extracetd for every simple page iteration.
826 function _upgrade_cached_html ( $verbose=true ) {
828 if (!$this->isSQL) return;
830 if ($this->phpwiki_version >= 1030.10) {
832 echo _("check for extra page.cached_html column")," ... ";
833 $database = $this->dbi->_backend->database();
834 extract($this->dbi->_backend->_table_names);
835 $fields = $this->dbi->_backend->listOfFields($database, $page_tbl);
837 echo _("SKIP"), "<br />\n";
840 if (!strstr(strtolower(join(':', $fields)), "cached_html")) {
842 echo "<b>",_("ADDING"),"</b>"," ... ";
843 $backend_type = $this->dbi->_backend->backendType();
844 if (substr($backend_type,0,5) == 'mysql')
845 $this->dbi->genericSqlQuery("ALTER TABLE $page_tbl ADD cached_html MEDIUMBLOB");
847 $this->dbi->genericSqlQuery("ALTER TABLE $page_tbl ADD cached_html BLOB");
849 echo "<b>",_("CONVERTING"),"</b>"," ... ";
850 $count = _convert_cached_html();
852 echo $count, " ", _("OK"), "<br />\n";
855 echo _("OK"), "<br />\n";
862 * move _cached_html for all pages from pagedata into a new seperate blob.
863 * decoupled from action=upgrade, so that it can be used by a WikiAdminUtils button also.
865 function _convert_cached_html () {
867 if (!$this->isSQL) return;
868 //if (!in_array(DATABASE_TYPE, array('SQL','ADODB'))) return;
870 $pages = $this->dbi->getAllPages();
871 $cache =& $this->dbi->_cache;
873 extract($this->dbi->_backend->_table_names);
874 while ($page = $pages->next()) {
875 $pagename = $page->getName();
876 $data = $this->dbi->_backend->get_pagedata($pagename);
877 if (!empty($data['_cached_html'])) {
878 $cached_html = $data['_cached_html'];
879 $data['_cached_html'] = '';
880 $cache->update_pagedata($pagename, $data);
881 // store as blob, not serialized
882 $this->dbi->genericSqlQuery("UPDATE $page_tbl SET cached_html=? WHERE pagename=?",
883 array($cached_html, $pagename));
891 * upgrade to 1.3.13 link structure.
893 function _upgrade_relation_links ( $verbose=true ) {
894 if ($this->phpwiki_version >= 1030.12200610) {
895 echo _("Rebuild entire database to upgrade relation links")," ... ";
896 if (DATABASE_TYPE == 'dba') {
897 echo "<b>",_("CONVERTING")," dba linktable</b>","(~2 min, max 4 min) ... ";
900 $this->dbi->_backend->_linkdb->rebuild();
904 $this->dbi->_backend->rebuild();
906 echo _("OK"), "<br />\n";
910 function CheckPluginUpdate() {
913 echo "<h3>",sprintf(_("check for necessary %s updates"),
914 _("plugin argument")),"</h3>\n";
916 $this->_configUpdates = array();
917 $this->_configUpdates[] = new UpgradePluginEntry
918 ($this, array('key' => 'plugin_randompage_numpages',
919 'fixed_with' => 1012.0,
920 //'header' => _("change RandomPage pages => numpages"),
921 //'notice' =>_("found RandomPage plugin"),
922 'check_args' => array("plugin RandomPage pages",
923 "/(<\?\s*plugin\s+ RandomPage\s+)pages/",
925 $this->_configUpdates[] = new UpgradePluginEntry
926 ($this, array('key' => 'plugin_createtoc_position',
927 'fixed_with' => 1013.0,
928 //'header' => _("change CreateToc align => position"),
929 //'notice' =>_("found CreateToc plugin"),
930 'check_args' => array("plugin CreateToc align",
931 "/(<\?\s*plugin\s+ CreateToc[^\?]+)align/",
934 if (empty($this->_configUpdates)) return;
935 foreach ($this->_configUpdates as $update) {
936 $pages = $this->dbi->fullSearch($this->check_args[0]);
937 while ($page = $allpages->next()) {
938 $current = $page->getCurrentRevision();
939 $pagetext = $current->getPackedContent();
940 $update->check($this->check_args[1], $this->check_args[2], $pagetext, $page, $current);
950 * preg_replace over local file.
951 * Only line-orientated matches possible.
953 function fixLocalFile($match, $replace, $filename) {
954 $o_filename = $filename;
955 if (!file_exists($filename))
956 $filename = FindFile($filename);
957 if (!file_exists($filename))
958 return array(false, sprintf(_("file %s not found"), $o_filename));
960 if (is_writable($filename)) {
961 $in = fopen($filename, "rb");
962 $out = fopen($tmp = tempnam(getUploadFilePath(),"cfg"), "wb");
964 $tmp = str_replace("/","\\",$tmp);
965 // Detect the existing linesep at first line. fgets strips it even if 'rb'.
966 // Before we simply assumed \r\n on windows local files.
967 $s = fread($in, 1024);
969 $linesep = (substr_count($s, "\r\n") > substr_count($s, "\n")) ? "\r\n" : "\n";
970 //$linesep = isWindows() ? "\r\n" : "\n";
971 while ($s = fgets($in)) {
972 // =>php-5.0.1 can fill count
973 //$new = preg_replace($match, $replace, $s, -1, $count);
974 $new = preg_replace($match, $replace, $s);
976 $s = $new . $linesep;
985 $reason = sprintf(_("%s not found in %s"), $match, $filename);
987 return array($found, $reason);
989 @unlink("$file.bak");
990 @rename($file,"$file.bak");
991 if (!rename($tmp, $file))
992 return array(false, sprintf(_("couldn't move %s to %s"), $tmp, $filename));
996 return array(false, sprintf(_("file %s is not writable"), $filename));
1000 function CheckConfigUpdate () {
1001 echo "<h3>",sprintf(_("check for necessary %s updates"),
1002 "config.ini"),"</h3>\n";
1003 $entry = new UpgradeConfigEntry
1004 ($this, array('key' => 'cache_control_none',
1005 'fixed_with' => 1012.0,
1006 'header' => sprintf(_("check for %s"),"CACHE_CONTROL = NONE"),
1007 'applicable_args' => 'CACHE_CONTROL',
1008 'notice' => _("CACHE_CONTROL is set to 'NONE', and must be changed to 'NO_CACHE'"),
1009 'check_args' => array("/^\s*CACHE_CONTROL\s*=\s*NONE/", "CACHE_CONTROL = NO_CACHE")));
1010 $entry->setApplicableCb(new WikiMethodCb($entry, '_applicable_defined_and_empty'));
1011 $this->_configUpdates[] = $entry;
1013 $entry = new UpgradeConfigEntry
1014 ($this, array('key' => 'group_method_none',
1015 'fixed_with' => 1012.0,
1016 'header' => sprintf(_("check for %s"), "GROUP_METHOD = NONE"),
1017 'applicable_args' => 'GROUP_METHOD',
1018 'notice' =>_("GROUP_METHOD is set to NONE, and must be changed to \"NONE\""),
1019 'check_args' => array("/^\s*GROUP_METHOD\s*=\s*NONE/", "GROUP_METHOD = \"NONE\"")));
1020 $entry->setApplicableCb(new WikiMethodCb($entry, '_applicable_defined_and_empty'));
1021 $this->_configUpdates[] = $entry;
1023 $entry = new UpgradeConfigEntry
1024 ($this, array('key' => 'blog_empty_default_prefix',
1025 'fixed_with' => 1013.0,
1026 'header' => sprintf(_("check for %s"), "BLOG_EMPTY_DEFAULT_PREFIX"),
1027 'applicable_args' => 'BLOG_EMPTY_DEFAULT_PREFIX',
1028 'notice' =>_("fix BLOG_EMPTY_DEFAULT_PREFIX into BLOG_DEFAULT_EMPTY_PREFIX"),
1029 'check_args' => array("/BLOG_EMPTY_DEFAULT_PREFIX\s*=/","BLOG_DEFAULT_EMPTY_PREFIX =")));
1030 $entry->setApplicableCb(new WikiMethodCb($entry, '_applicable_defined'));
1031 $this->_configUpdates[] = $entry;
1033 // TODO: find extra file updates
1034 if (empty($this->_configUpdates)) return;
1035 foreach ($this->_configUpdates as $update) {
1045 * Add an upgrade item to be checked.
1047 * @param $parent object The parent Upgrade class to inherit the version properties
1048 * @param $key string A short unique key to store success in the WikiDB
1049 * @param $fixed_with double @see phpwiki_version() number
1050 * @param $header string Optional header to be printed always even if not applicable
1051 * @param $applicable WikiCallback Optional callback boolean applicable()
1052 * @param $notice string Description of the check
1053 * @param $method WikiCallback Optional callback array method(array)
1054 * //param All other args are passed to $method
1056 function UpgradeEntry(&$parent, $params) {
1057 $this->parent =& $parent; // get the properties db_version
1058 foreach (array('key' => 'required',
1059 // the wikidb stores the version when we actually fixed that.
1060 'fixed_with' => 'required',
1061 'header' => '', // always printed
1062 'applicable_cb' => null, // method to check if applicable
1063 'applicable_args' => array(), // might be the config name
1065 'check_cb' => null, // method to apply
1066 'check_args' => array())
1069 if (!isset($params[$k])) { // default
1070 if ($v == 'required') trigger_error("Required arg $k missing", E_USER_ERROR);
1071 else $this->{$k} = $v;
1073 $this->{$k} = $params[$k];
1076 if (!is_array($this->applicable_args)) // single arg convenience shortcut
1077 $this->applicable_args = array($this->applicable_args);
1078 if (!is_array($this->check_args)) // single arg convenience shortcut
1079 $this->check_args = array($this->check_args);
1080 if ($this->notice === '' and count($this->applicable_args) > 0)
1081 $this->notice = 'Check for '.join(', ', $this->applicable_args);
1082 $this->_db_key = "_upgrade";
1083 $this->upgrade = $this->parent->dbi->get($this->_db_key);
1086 function setApplicableCb($object) {
1087 $this->applicable_cb =& $object;
1089 function _check_if_already_fixed() {
1091 if (!isset($this->upgrade['name'])) return false;
1092 // override with force?
1093 if ($this->parent->request->getArg('force')) return false;
1094 // already fixed and with an ok version
1095 if ($this->upgrade['name'] >= $this->fixed_with) return $this->upgrade['name'];
1096 // already fixed but with an older version. do it again.
1100 // store in db no to fix again
1101 $this->upgrade['name'] = $this->parent->phpwiki_version;
1102 $this->parent->dbi->set($this->_db_key, $this->upgrade);
1103 echo "<b>",_("FIXED"),"</b>";
1104 if (isset($this->reason))
1105 echo ": ", $this->reason;
1111 echo " <b><font color=\"red\">", _("FAILED"), "</font></b>";
1112 if (isset($this->reason))
1113 echo ": ", $this->reason;
1118 function skip() { // not applicable
1119 if (isset($this->silent_skip)) return true;
1120 echo _(" skipped"),".<br />\n";
1124 function check($args = null) {
1125 if ($this->header) echo $this->header, ' ... ';
1126 if ($when = $this->_check_if_already_fixed()) {
1127 // be totally silent if no header is defined.
1128 if ($this->header) echo _("fixed with")," ",$when,"<br />\n";
1132 if (is_object($this->applicable_cb)) {
1133 if (!$this->applicable_cb->call_array($this->applicable_args))
1134 return $this->skip();
1136 if ($this->notice) {
1139 echo $this->notice," ";
1142 if (!is_null($args)) $this->check_args =& $args;
1143 if (is_object($this->check_cb))
1144 $do = $this->method_cb->call_array($this->check_args);
1146 $do = $this->default_method($this->check_args);
1147 if (is_array($do)) {
1148 $this->reason = $do[1];
1151 return $do ? $this->pass() : $this->fail();
1153 } // class UpgradeEntry
1155 class UpgradeConfigEntry extends UpgradeEntry {
1156 function _applicable_defined() {
1157 return (boolean)defined($this->applicable_args[0]);
1159 function _applicable_defined_and_empty() {
1160 $const = $this->applicable_args[0];
1161 return (boolean)(defined($const) and !constant($const));
1163 function default_method ($args) {
1165 $replace = $args[1];
1166 return $this->parent->fixLocalFile($match, $replace, "config/config.ini");
1168 } // class UpdateConfigEntry
1170 /* This is different */
1171 class UpgradePluginEntry extends UpgradeEntry {
1174 * check all pages for a plugin match
1176 var $silent_skip = 1;
1178 function default_method (&$args) {
1180 $replace = $args[1];
1181 $pagetext =& $args[2];
1183 $current =& $args[4];
1184 if (preg_match($match, $pagetext)) {
1185 echo $page->getName()," ",$this->notice," ... ";
1186 if ($newtext = preg_replace($match, $replace, $pagetext)) {
1187 $meta = $current->_data;
1188 $meta['summary'] = "upgrade: ".$this->header;
1189 $page->save($newtext, $current->getVersion() + 1, $meta);
1196 } // class UpdatePluginEntry
1199 * fix custom themes which are not in our distribution
1200 * this should be optional
1202 class UpgradeThemeEntry extends UpgradeEntry {
1204 function default_method (&$args) {
1206 $replace = $args[1];
1207 $template = $args[2];
1210 function fixThemeTemplate($match, $new, $template) {
1211 // for all custom themes
1212 $ourthemes = explode(":","blog:Crao:default:Hawaiian:MacOSX:MonoBook:Portland:shamino_com:SpaceWiki:wikilens:Wordpress");
1213 $themedir = NormalizeLocalFileName("themes");
1214 $dh = opendir($themedir);
1215 while ($r = readdir($dh)) {
1216 if (filetype($r) == 'dir' and $r[0] != '.' and !is_array($r, $ourthemes))
1217 $customthemes[] = $r;
1221 foreach ($customthemes as $customtheme) {
1222 $template = FindFile("themes/$customtheme/templates/$template");
1223 $do = $this->parent->fixLocalFile($match, $new, template);
1226 $errors .= $do[1]." ";
1230 return array($success, $errors);
1237 * Upgrade: Base class for multipage worksteps
1238 * identify, validate, display options, next step
1243 // TODO: At which step are we?
1244 // validate and do it again or go on with next step.
1246 /** entry function from lib/main.php
1248 function DoUpgrade(&$request) {
1250 if (!$request->_user->isAdmin()) {
1251 $request->_notAuthorized(WIKIAUTH_ADMIN);
1253 HTML::div(array('class' => 'disabled-plugin'),
1254 fmt("Upgrade disabled: user != isAdmin")));
1257 // TODO: StartLoadDump should turn on implicit_flush.
1258 @ini_set("implicit_flush", true);
1259 StartLoadDump($request, _("Upgrading this PhpWiki"));
1260 $upgrade = new Upgrade($request);
1261 //if (!$request->getArg('noindex'))
1262 // CheckOldIndexUpdate($request); // index.php => config.ini to upgrade from < 1.3.10
1263 if (!$request->getArg('nodb'))
1264 $upgrade->CheckDatabaseUpdate($request); // first check cached_html and friends
1265 if (!$request->getArg('nopgsrc')) {
1266 $upgrade->CheckActionPageUpdate($request);
1267 $upgrade->CheckPgsrcUpdate($request);
1269 if (!$request->getArg('noplugin'))
1270 $upgrade->CheckPluginUpdate($request);
1271 if (!$request->getArg('noconfig'))
1272 $upgrade->CheckConfigUpdate($request);
1273 // This is optional and should be linked. In EndLoadDump or PhpWikiAdministration?
1274 //if ($request->getArg('theme'))
1275 // $upgrade->CheckThemeUpdate($request);
1276 EndLoadDump($request);
1281 $Log: not supported by cvs2svn $
1282 Revision 1.58 2007/01/28 22:54:18 rurban
1283 more objectification. store last db update.
1285 Revision 1.57 2007/01/04 16:43:09 rurban
1286 Changed to class Upgrade: Do not pollute our namespace with global functions. Less arguments needed. Fix missing permissions on wrong DBADMIN_USER. Let user input override the wrong constant.
1288 Revision 1.56 2007/01/03 21:25:34 rurban
1289 rename InterWikiKarte to InterWikiListe. Support nosql, nopgsrc, noplugin, noconfig args.
1291 Revision 1.55 2007/01/02 13:24:01 rurban
1292 1.3.13 support: _rename_page_helper, _rename_to_help_page, _upgrade_relation_links, check for ACCESS_LOG_SQL remote_host varchar(50), _upgrade_psql_tsearch2
1294 Revision 1.54 2006/12/03 17:07:29 rurban
1295 #1535843 by matt brown: Upgrade Wizard Password fixes are not portable
1297 Revision 1.53 2006/12/03 17:03:18 rurban
1298 #1535851 by matt brown
1300 Revision 1.52 2006/12/03 17:01:18 rurban
1301 #1535839 by matt brown
1303 Revision 1.51 2006/08/07 21:05:30 rurban
1304 patch #1535837 (debian)
1306 Revision 1.50 2006/06/18 11:04:09 rurban
1309 Revision 1.49 2006/05/18 06:03:39 rurban
1310 use $dbh->_backend->isSQL
1312 Revision 1.48 2005/11/14 22:32:38 rurban
1313 remove user, SKIP on !session
1315 Revision 1.47 2005/02/27 19:13:27 rurban
1318 Revision 1.46 2005/02/12 17:22:18 rurban
1319 locale update: missing . : fixed. unified strings
1322 Revision 1.45 2005/02/10 19:01:19 rurban
1325 Revision 1.44 2005/02/07 15:40:42 rurban
1326 use defined CHARSET for db. more comment
1327 Revision 1.43 2005/02/04 11:44:07 rurban
1328 check passwd in access_log
1330 Revision 1.42 2005/02/02 19:38:13 rurban
1331 prefer utf8 pagenames for collate issues
1333 Revision 1.41 2005/01/31 12:15:29 rurban
1336 Revision 1.40 2005/01/30 23:22:17 rurban
1339 Revision 1.39 2005/01/30 23:09:17 rurban
1340 sanify session fields
1342 Revision 1.38 2005/01/25 07:57:02 rurban
1343 add dbadmin form, add mysql LOCK TABLES check, add plugin args updater (not yet activated)
1345 Revision 1.37 2005/01/20 10:19:08 rurban
1346 add InterWikiMap to special pages
1348 Revision 1.36 2004/12/20 12:56:11 rurban
1349 patch #1088128 by Kai Krakow. avoid chicken & egg problem
1351 Revision 1.35 2004/12/13 14:35:41 rurban
1354 Revision 1.34 2004/12/11 09:39:28 rurban
1357 Revision 1.33 2004/12/10 22:33:39 rurban
1358 add WikiAdminUtils method for convert-cached-html
1361 Revision 1.32 2004/12/10 22:15:00 rurban
1362 fix $page->get('_cached_html)
1363 refactor upgrade db helper _convert_cached_html() to be able to call them from WikiAdminUtils also.
1364 support 2nd genericSqlQuery param (bind huge arg)
1366 Revision 1.31 2004/12/10 02:45:26 rurban
1368 put _cached_html from pagedata into a new seperate blob, not huge serialized string.
1369 it is only rarelely needed: for current page only, if-not-modified
1370 but was extracted for every simple page iteration.
1372 Revision 1.30 2004/11/29 17:58:57 rurban
1375 Revision 1.29 2004/11/29 16:08:31 rurban
1378 Revision 1.28 2004/11/16 16:25:14 rurban
1379 fix accesslog tablename, print CREATED only if really done
1381 Revision 1.27 2004/11/07 16:02:52 rurban
1382 new sql access log (for spam prevention), and restructured access log class
1383 dbh->quote (generic)
1384 pear_db: mysql specific parts seperated (using replace)
1386 Revision 1.26 2004/10/14 19:19:34 rurban
1387 loadsave: check if the dumped file will be accessible from outside.
1388 and some other minor fixes. (cvsclient native not yet ready)
1390 Revision 1.25 2004/09/06 08:28:00 rurban
1391 rename genericQuery to genericSqlQuery
1393 Revision 1.24 2004/07/05 13:56:22 rurban
1394 sqlite autoincrement fix
1396 Revision 1.23 2004/07/04 10:28:06 rurban
1399 Revision 1.22 2004/07/03 17:21:28 rurban
1400 updated docs: submitted new mysql bugreport (#1491 did not fix it)
1402 Revision 1.21 2004/07/03 16:51:05 rurban
1403 optional DBADMIN_USER:DBADMIN_PASSWD for action=upgrade (if no ALTER permission)
1404 added atomic mysql REPLACE for PearDB as in ADODB
1405 fixed _lock_tables typo links => link
1406 fixes unserialize ADODB bug in line 180
1408 Revision 1.20 2004/07/03 14:48:18 rurban
1409 Tested new mysql 4.1.3-beta: binary search bug as fixed.
1410 => fixed action=upgrade,
1411 => version check in PearDB also (as in ADODB)
1413 Revision 1.19 2004/06/19 12:19:09 rurban
1414 slightly improved docs
1416 Revision 1.18 2004/06/19 11:47:17 rurban
1417 added CheckConfigUpdate: CACHE_CONTROL = NONE => NO_CACHE
1419 Revision 1.17 2004/06/17 11:31:50 rurban
1420 check necessary localized actionpages
1422 Revision 1.16 2004/06/16 10:38:58 rurban
1423 Disallow refernces in calls if the declaration is a reference
1424 ("allow_call_time_pass_reference clean").
1425 PhpWiki is now allow_call_time_pass_reference = Off clean,
1426 but several external libraries may not.
1427 In detail these libs look to be affected (not tested):
1431 Revision 1.15 2004/06/07 19:50:40 rurban
1432 add owner field to mimified dump
1434 Revision 1.14 2004/06/07 18:38:18 rurban
1435 added mysql 4.1.x search fix
1437 Revision 1.13 2004/06/04 20:32:53 rurban
1438 Several locale related improvements suggested by Pierrick Meignen
1439 LDAP fix by John Cole
1440 reanable admin check without ENABLE_PAGEPERM in the admin plugins
1442 Revision 1.12 2004/05/18 13:59:15 rurban
1443 rename simpleQuery to genericSqlQuery
1445 Revision 1.11 2004/05/15 13:06:17 rurban
1446 skip the HomePage, at first upgrade the ActionPages, then the database, then the rest
1448 Revision 1.10 2004/05/15 01:19:41 rurban
1449 upgrade prefix fix by Kai Krakow
1451 Revision 1.9 2004/05/14 11:33:03 rurban
1452 version updated to 1.3.11pre
1453 upgrade stability fix
1455 Revision 1.8 2004/05/12 10:49:55 rurban
1456 require_once fix for those libs which are loaded before FileFinder and
1457 its automatic include_path fix, and where require_once doesn't grok
1458 dirname(__FILE__) != './lib'
1459 upgrade fix with PearDB
1460 navbar.tmpl: remove spaces for IE button alignment
1462 Revision 1.7 2004/05/06 17:30:38 rurban
1463 CategoryGroup: oops, dos2unix eol
1464 improved phpwiki_version:
1465 pre -= .0001 (1.3.10pre: 1030.099)
1466 -p1 += .001 (1.3.9-p1: 1030.091)
1467 improved InstallTable for mysql and generic SQL versions and all newer tables so far.
1468 abstracted more ADODB/PearDB methods for action=upgrade stuff:
1469 backend->backendType(), backend->database(),
1470 backend->listOfFields(),
1471 backend->listOfTables(),
1473 Revision 1.6 2004/05/03 15:05:36 rurban
1476 Revision 1.4 2004/05/02 21:26:38 rurban
1477 limit user session data (HomePageHandle and auth_dbi have to invalidated anyway)
1478 because they will not survive db sessions, if too large.
1479 extended action=upgrade
1480 some WikiTranslation button work
1481 revert WIKIAUTH_UNOBTAINABLE (need it for main.php)
1482 some temp. session debug statements
1484 Revision 1.3 2004/04/29 22:33:30 rurban
1485 fixed sf.net bug #943366 (Kai Krakow)
1486 couldn't load localized url-undecoded pagenames
1488 Revision 1.2 2004/03/12 15:48:07 rurban
1489 fixed explodePageList: wrong sortby argument order in UnfoldSubpages
1490 simplified lib/stdlib.php:explodePageList
1498 // c-basic-offset: 4
1499 // c-hanging-comment-ender-p: nil
1500 // indent-tabs-mode: nil