]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/upgrade.php
version updated to 1.3.11pre
[SourceForge/phpwiki.git] / lib / upgrade.php
1 <?php //-*-php-*-
2 rcs_id('$Id: upgrade.php,v 1.9 2004-05-14 11:33:03 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  * Installation on an existing PhpWiki database needs some 
31  * additional worksteps. Each step will require multiple pages.
32  *
33  * This is the plan:
34  *  1. Check for new or changed database schema and update it 
35  *     according to some predefined upgrade tables. (medium)
36  *  2. Check for new or changed (localized) pgsrc/ pages and ask 
37  *     for upgrading these. Check timestamps, upgrade silently or 
38  *     show diffs if existing. Overwrite or merge (easy)
39  *  3. Check for new or changed or deprecated index.php settings
40  *     and help in upgrading these. (hard)
41  *  4. Check for changed plugin invocation arguments. (hard)
42  *  5. Check for changed theme variables. (hard)
43  *
44  * @author: Reini Urban
45  */
46 require_once("lib/loadsave.php");
47
48 // see loadsave.php for saving new pages.
49 function CheckPgsrcUpdate(&$request) {
50     echo "<h3>",_("check for necessary pgsrc updates"),"</h3>\n";
51     $dbi = $request->getDbh(); 
52     $path = FindLocalizedFile(WIKI_PGSRC);
53     $pgsrc = new fileSet($path);
54     // fixme: verification, ...
55     foreach ($pgsrc->getFiles() as $filename) {
56         if (substr($filename,-1,1) == '~') continue;
57         $pagename = urldecode($filename);
58         $page = $dbi->getPage($pagename);
59         if ($page->exists()) {
60             // check mtime: update automatically if pgsrc is newer
61             $rev = $page->getCurrentRevision();
62             $page_mtime = $rev->get('mtime');
63             $data  = implode("", file($path."/".$filename));
64             if (($parts = ParseMimeifiedPages($data))) {
65                 usort($parts, 'SortByPageVersion');
66                 reset($parts);
67                 $pageinfo = $parts[0];
68                 $stat  = stat($path."/".$filename);
69                 $new_mtime = @$pageinfo['versiondata']['mtime'];
70                 if (!$new_mtime)
71                     $new_mtime = @$pageinfo['versiondata']['lastmodified'];
72                 if (!$new_mtime)
73                     $new_mtime = @$pageinfo['pagedata']['date'];
74                 if (!$new_mtime)
75                     $new_mtime = $stat[9];
76                 if ($new_mtime > $page_mtime) {
77                     echo "$path/$pagename: newer than the existing page. replace ($new_mtime &gt; $page_mtime)<br />\n";
78                     LoadAny($request,$path."/".$filename);
79                     echo "<br />\n";
80                 } else {
81                     echo "$path/$pagename: older than the existing page. skipped.<br />\n";
82                 }
83             } else {
84                 echo "$path/$pagename: unknown format, skipped.<br />\n";
85             }
86         } else {
87             echo "$pagename does not exist<br />\n";
88             LoadAny($request,$path."/".$filename);
89             echo "<br />\n";
90         }
91     }
92     return;
93 }
94
95 /**
96  * TODO: Search table definition in appropriate schema
97  *       and create it.
98  * Supported: mysql and generic SQL, for ADODB and PearDB.
99  */
100 function installTable(&$dbh, $table, $backend_type) {
101     global $DBParams;
102     if (!in_array($DBParams['dbtype'],array('SQL','ADODB'))) return;
103     echo _("MISSING")," ... \n";
104     $backend = &$dbh->_backend->_dbh;
105     /*
106     $schema = findFile("schemas/${backend_type}.sql");
107     if (!$schema) {
108         echo "  ",_("FAILED"),": ",sprintf(_("no schema %s found"),"schemas/${backend_type}.sql")," ... <br />\n";
109         return false;
110     }
111     */
112     extract($dbh->_backend->_table_names);
113     $prefix = isset($DBParams['prefix']) ? $DBParams['prefix'] : '';
114     switch ($table) {
115     case 'session':
116         assert($session_tbl);
117         if ($backend_type == 'mysql') {
118             $dbh->simpleQuery("
119 CREATE TABLE $session_tbl (
120         sess_id         CHAR(32) NOT NULL DEFAULT '',
121         sess_data       BLOB NOT NULL,
122         sess_date       INT UNSIGNED NOT NULL,
123         sess_ip         CHAR(15) NOT NULL,
124         PRIMARY KEY (sess_id),
125         INDEX (sess_date)
126 )");
127         } else {
128             $dbh->simpleQuery("
129 CREATE TABLE $session_tbl (
130         sess_id         CHAR(32) NOT NULL DEFAULT '',
131         sess_data       ".($backend_type == 'pgsql'?'TEXT':'BLOB')." NOT NULL,
132         sess_date       INT,
133         sess_ip         CHAR(15) NOT NULL
134 )");
135             $dbh->simpleQuery("CREATE UNIQUE INDEX sess_id ON $session_tbl (sess_id)");
136         }
137         $dbh->simpleQuery("CREATE INDEX sess_date on session (sess_date)");
138         break;
139     case 'user':
140         $user_tbl = $prefix.'user';
141         if ($backend_type == 'mysql') {
142             $dbh->simpleQuery("
143 CREATE TABLE $user_tbl (
144         userid  CHAR(48) BINARY NOT NULL UNIQUE,
145         passwd  CHAR(48) BINARY DEFAULT '',
146         PRIMARY KEY (userid)
147 )");
148         } else {
149             $dbh->simpleQuery("
150 CREATE TABLE $user_tbl (
151         userid  CHAR(48) NOT NULL,
152         passwd  CHAR(48) DEFAULT ''
153 )");
154             $dbh->simpleQuery("CREATE UNIQUE INDEX userid ON $user_tbl (userid)");
155         }
156         break;
157     case 'pref':
158         $pref_tbl = $prefix.'pref';
159         if ($backend_type == 'mysql') {
160             $dbh->simpleQuery("
161 CREATE TABLE $pref_tbl (
162         userid  CHAR(48) BINARY NOT NULL UNIQUE,
163         prefs   TEXT NULL DEFAULT '',
164         PRIMARY KEY (userid)
165 )");
166         } else {
167             $dbh->simpleQuery("
168 CREATE TABLE $pref_tbl (
169         userid  CHAR(48) NOT NULL,
170         prefs   TEXT NULL DEFAULT '',
171 )");
172             $dbh->simpleQuery("CREATE UNIQUE INDEX userid ON $pref_tbl (userid)");
173         }
174         break;
175     case 'member':
176         $member_tbl = $prefix.'member';
177         if ($backend_type == 'mysql') {
178             $dbh->simpleQuery("
179 CREATE TABLE $member_tbl (
180         userid    CHAR(48) BINARY NOT NULL,
181         groupname CHAR(48) BINARY NOT NULL DEFAULT 'users',
182         INDEX (userid),
183         INDEX (groupname)
184 )");
185         } else {
186             $dbh->simpleQuery("
187 CREATE TABLE $member_tbl (
188         userid    CHAR(48) NOT NULL,
189         groupname CHAR(48) NOT NULL DEFAULT 'users',
190 )");
191             $dbh->simpleQuery("CREATE INDEX userid ON $member_tbl (userid)");
192             $dbh->simpleQuery("CREATE INDEX groupname ON $member_tbl (groupname)");
193         }
194         break;
195     case 'rating':
196         $rating_tbl = $prefix.'rating';
197         if ($backend_type == 'mysql') {
198             $dbh->simpleQuery("
199 CREATE TABLE $rating_tbl (
200         dimension INT(4) NOT NULL,
201         raterpage INT(11) NOT NULL,
202         rateepage INT(11) NOT NULL,
203         ratingvalue FLOAT NOT NULL,
204         rateeversion INT(11) NOT NULL,
205         tstamp TIMESTAMP(14) NOT NULL,
206         PRIMARY KEY (dimension, raterpage, rateepage)
207 )");
208         } else {
209             $dbh->simpleQuery("
210 CREATE TABLE $rating_tbl (
211         dimension INT(4) NOT NULL,
212         raterpage INT(11) NOT NULL,
213         rateepage INT(11) NOT NULL,
214         ratingvalue FLOAT NOT NULL,
215         rateeversion INT(11) NOT NULL,
216         tstamp TIMESTAMP(14) NOT NULL,
217 )");
218             $dbh->simpleQuery("CREATE UNIQUE INDEX rating ON $rating_tbl (dimension, raterpage, rateepage)");
219         }
220         break;
221     }
222     echo "  ",_("CREATED"),"<br />\n";
223 }
224
225 /**
226  * currently update only session, user, pref and member
227  * jeffs-hacks database api (around 1.3.2) later
228  *   people should export/import their pages if using that old versions.
229  */
230 function CheckDatabaseUpdate($request) {
231     global $DBParams, $DBAuthParams;
232     if (!in_array($DBParams['dbtype'],array('SQL','ADODB'))) return;
233     echo "<h3>",_("check for necessary database updates"),"</h3>\n";
234     $dbh = &$request->_dbi;
235     $tables = $dbh->_backend->listOfTables();
236     $backend_type = $dbh->_backend->backendType();
237     $prefix = isset($DBParams['prefix']) ? $DBParams['prefix'] : '';
238     extract($dbh->_backend->_table_names);
239     foreach (explode(':','session:user:pref:member') as $table) {
240         echo _("check for table $table")," ...";        
241         if (!in_array($table,$tables)) {
242             installTable(&$dbh, $table, $backend_type);
243         } else {
244             echo "OK <br />\n";
245         }
246     }
247     $backend = &$dbh->_backend->_dbh;
248     // 1.3.8 added session.sess_ip
249     if (phpwiki_version() >= 1030.08 and USE_DB_SESSION and isset($request->_dbsession)) {
250         echo _("check for new session.sess_ip column")," ... ";
251         $database = $dbh->_backend->database();
252         assert(!empty($DBParams['db_session_table']));
253         $session_tbl = $prefix . $DBParams['db_session_table'];
254         $sess_fields = $dbh->_backend->listOfFields($database,$session_tbl);
255         //FIXME: adodb seem to uppercase the fields
256         if (!strstr(strtolower(join(':',$sess_fields)),"sess_ip")) {
257             echo "<b>",_("ADDING"),"</b>"," ... ";              
258             $dbh->simpleQuery("ALTER TABLE $session_tbl ADD sess_ip CHAR(15) NOT NULL");
259         } else {
260             echo _("OK");
261         }
262         echo "<br />\n";
263     }
264     // 1.3.10 mysql requires page.id auto_increment
265     // mysql, mysqli or mysqlt
266     if (phpwiki_version() >= 1030.099 and substr($backend_type,0,5) == 'mysql') {
267         echo _("check for page.id auto_increment flag")," ...";
268         assert(!empty($page_tbl));
269         $database = $dbh->_backend->database();
270         $fields = mysql_list_fields($database,$page_tbl,$dbh->_backend->connection());
271         $columns = mysql_num_fields($fields); 
272         for ($i = 0; $i < $columns; $i++) {
273             if (mysql_field_name($fields, $i) == 'id') {
274                 $flags = mysql_field_flags($fields, $i);
275                 //FIXME: something wrong with ADODB here!
276                 if (!strstr(strtolower($flags),"auto_increment")) {
277                     echo "<b>",_("ADDING"),"</b>"," ... ";              
278                     // MODIFY col_def valid since mysql 3.22.16,
279                     // older mysql's need CHANGE old_col col_def
280                     $dbh->simpleQuery("ALTER TABLE $page_tbl CHANGE id id INT NOT NULL AUTO_INCREMENT");
281                     $fields = mysql_list_fields($database,$page_tbl);
282                     if (!strstr(strtolower(mysql_field_flags($fields, $i)),"auto_increment"))
283                         echo " <b><font color=\"red\">",_("FAILED"),"</font></b><br />\n";              
284                     else     
285                         echo _("OK"),"<br />\n";                        
286                 } else {
287                     echo _("OK"),"<br />\n";                            
288                 }
289                 break;
290             }
291         }
292         mysql_free_result($fields);
293     }
294     return;
295 }
296
297 /**
298  * Upgrade: Base class for multipage worksteps
299  * identify, validate, display options, next step
300  */
301 class Upgrade {
302 }
303
304 class Upgrade_CheckPgsrc extends Upgrade {
305 }
306
307 class Upgrade_CheckDatabaseUpdate extends Upgrade {
308 }
309
310 // TODO: At which step are we? 
311 // validate and do it again or go on with next step.
312
313 /** entry function from lib/main.php
314  */
315 function DoUpgrade($request) {
316
317     if (!$request->_user->isAdmin()) {
318         $request->_notAuthorized(WIKIAUTH_ADMIN);
319         $request->finish(
320                          HTML::div(array('class' => 'disabled-plugin'),
321                                    fmt("Upgrade disabled: user != isAdmin")));
322         return;
323     }
324
325     StartLoadDump($request, _("Upgrading this PhpWiki"));
326     CheckDatabaseUpdate($request);
327     CheckPgsrcUpdate($request);
328     //CheckThemeUpdate($request);
329     EndLoadDump($request);
330 }
331
332
333 /**
334  $Log: not supported by cvs2svn $
335  Revision 1.8  2004/05/12 10:49:55  rurban
336  require_once fix for those libs which are loaded before FileFinder and
337    its automatic include_path fix, and where require_once doesn't grok
338    dirname(__FILE__) != './lib'
339  upgrade fix with PearDB
340  navbar.tmpl: remove spaces for IE &nbsp; button alignment
341
342  Revision 1.7  2004/05/06 17:30:38  rurban
343  CategoryGroup: oops, dos2unix eol
344  improved phpwiki_version:
345    pre -= .0001 (1.3.10pre: 1030.099)
346    -p1 += .001 (1.3.9-p1: 1030.091)
347  improved InstallTable for mysql and generic SQL versions and all newer tables so far.
348  abstracted more ADODB/PearDB methods for action=upgrade stuff:
349    backend->backendType(), backend->database(),
350    backend->listOfFields(),
351    backend->listOfTables(),
352
353  Revision 1.6  2004/05/03 15:05:36  rurban
354  + table messages
355
356  Revision 1.4  2004/05/02 21:26:38  rurban
357  limit user session data (HomePageHandle and auth_dbi have to invalidated anyway)
358    because they will not survive db sessions, if too large.
359  extended action=upgrade
360  some WikiTranslation button work
361  revert WIKIAUTH_UNOBTAINABLE (need it for main.php)
362  some temp. session debug statements
363
364  Revision 1.3  2004/04/29 22:33:30  rurban
365  fixed sf.net bug #943366 (Kai Krakow)
366    couldn't load localized url-undecoded pagenames
367
368  Revision 1.2  2004/03/12 15:48:07  rurban
369  fixed explodePageList: wrong sortby argument order in UnfoldSubpages
370  simplified lib/stdlib.php:explodePageList
371
372  */
373
374 // For emacs users
375 // Local Variables:
376 // mode: php
377 // tab-width: 8
378 // c-basic-offset: 4
379 // c-hanging-comment-ender-p: nil
380 // indent-tabs-mode: nil
381 // End:
382 ?>