Wordpress 2.0.2
[autoinstalls/wordpress.git] / wp-admin / upgrade-functions.php
1 <?php
2
3 require_once(ABSPATH . '/wp-admin/admin-functions.php');
4 require_once(ABSPATH . '/wp-admin/upgrade-schema.php');
5 // Functions to be called in install and upgrade scripts
6 function upgrade_all() {
7         global $wp_current_db_version, $wp_db_version, $wp_rewrite;
8         $wp_current_db_version = __get_option('db_version');
9
10         // We are up-to-date.  Nothing to do.
11         if ( $wp_db_version == $wp_current_db_version )
12                 return;
13
14         // If the version is not set in the DB, try to guess the version.
15         if ( empty($wp_current_db_version) ) {
16                 $wp_current_db_version = 0;
17
18                 // If the template option exists, we have 1.5.
19                 $template = __get_option('template');
20                 if ( !empty($template) )
21                         $wp_current_db_version = 2541;
22         }
23         
24         populate_options();
25
26         if ( $wp_current_db_version < 2541 ) {
27                 upgrade_100();
28                 upgrade_101();
29                 upgrade_110();
30                 upgrade_130();
31         }
32         
33         if ( $wp_current_db_version < 3308 )
34                 upgrade_160();
35
36         $wp_rewrite->flush_rules();
37         
38         update_option('db_version', $wp_db_version);
39 }
40
41 function upgrade_100() {
42         global $wpdb;
43
44         // Get the title and ID of every post, post_name to check if it already has a value
45         $posts = $wpdb->get_results("SELECT ID, post_title, post_name FROM $wpdb->posts WHERE post_name = ''");
46         if ($posts) {
47                 foreach($posts as $post) {
48                         if ('' == $post->post_name) { 
49                                 $newtitle = sanitize_title($post->post_title);
50                                 $wpdb->query("UPDATE $wpdb->posts SET post_name = '$newtitle' WHERE ID = '$post->ID'");
51                         }
52                 }
53         }
54         
55         $categories = $wpdb->get_results("SELECT cat_ID, cat_name, category_nicename FROM $wpdb->categories");
56         foreach ($categories as $category) {
57                 if ('' == $category->category_nicename) { 
58                         $newtitle = sanitize_title($category->cat_name);
59                         $wpdb->query("UPDATE $wpdb->categories SET category_nicename = '$newtitle' WHERE cat_ID = '$category->cat_ID'");
60                 }
61         }
62
63
64         $wpdb->query("UPDATE $wpdb->options SET option_value = REPLACE(option_value, 'wp-links/links-images/', 'wp-images/links/')
65         WHERE option_name LIKE 'links_rating_image%'
66         AND option_value LIKE 'wp-links/links-images/%'");
67
68         $done_ids = $wpdb->get_results("SELECT DISTINCT post_id FROM $wpdb->post2cat");
69         if ($done_ids) :
70                 foreach ($done_ids as $done_id) :
71                         $done_posts[] = $done_id->post_id;
72                 endforeach;
73                 $catwhere = ' AND ID NOT IN (' . implode(',', $done_posts) . ')';
74         else:
75                 $catwhere = '';
76         endif;
77         
78         $allposts = $wpdb->get_results("SELECT ID, post_category FROM $wpdb->posts WHERE post_category != '0' $catwhere");
79         if ($allposts) :
80                 foreach ($allposts as $post) {
81                         // Check to see if it's already been imported
82                         $cat = $wpdb->get_row("SELECT * FROM $wpdb->post2cat WHERE post_id = $post->ID AND category_id = $post->post_category");
83                         if (!$cat && 0 != $post->post_category) { // If there's no result
84                                 $wpdb->query("
85                                         INSERT INTO $wpdb->post2cat
86                                         (post_id, category_id)
87                                         VALUES
88                                         ('$post->ID', '$post->post_category')
89                                         ");
90                         }
91                 }
92         endif;
93 }
94
95 function upgrade_101() {
96         global $wpdb;
97
98         // Clean up indices, add a few
99         add_clean_index($wpdb->posts, 'post_name');
100         add_clean_index($wpdb->posts, 'post_status');
101         add_clean_index($wpdb->categories, 'category_nicename');
102         add_clean_index($wpdb->comments, 'comment_approved');
103         add_clean_index($wpdb->comments, 'comment_post_ID');
104         add_clean_index($wpdb->links , 'link_category');
105         add_clean_index($wpdb->links , 'link_visible');
106 }
107
108
109 function upgrade_110() {
110         global $wpdb;
111         
112     // Set user_nicename.
113         $users = $wpdb->get_results("SELECT ID, user_nickname, user_nicename FROM $wpdb->users");
114         foreach ($users as $user) {
115                 if ('' == $user->user_nicename) { 
116                         $newname = sanitize_title($user->user_nickname);
117                         $wpdb->query("UPDATE $wpdb->users SET user_nicename = '$newname' WHERE ID = '$user->ID'");
118                 }
119         }
120
121         $users = $wpdb->get_results("SELECT ID, user_pass from $wpdb->users");
122         foreach ($users as $row) {
123                 if (!preg_match('/^[A-Fa-f0-9]{32}$/', $row->user_pass)) {
124                            $wpdb->query('UPDATE '.$wpdb->users.' SET user_pass = MD5(\''.$row->user_pass.'\') WHERE ID = \''.$row->ID.'\'');
125                 }
126         }
127
128
129         // Get the GMT offset, we'll use that later on
130         $all_options = get_alloptions_110();
131
132         $time_difference = $all_options->time_difference;
133
134         $server_time = time()+date('Z');
135         $weblogger_time = $server_time + $time_difference*3600;
136         $gmt_time = time();
137
138         $diff_gmt_server = ($gmt_time - $server_time) / 3600;
139         $diff_weblogger_server = ($weblogger_time - $server_time) / 3600;
140         $diff_gmt_weblogger = $diff_gmt_server - $diff_weblogger_server;
141         $gmt_offset = -$diff_gmt_weblogger;
142
143         // Add a gmt_offset option, with value $gmt_offset
144         add_option('gmt_offset', $gmt_offset);
145
146         // Check if we already set the GMT fields (if we did, then
147         // MAX(post_date_gmt) can't be '0000-00-00 00:00:00'
148         // <michel_v> I just slapped myself silly for not thinking about it earlier
149         $got_gmt_fields = ($wpdb->get_var("SELECT MAX(post_date_gmt) FROM $wpdb->posts") == '0000-00-00 00:00:00') ? false : true;
150
151         if (!$got_gmt_fields) {
152
153                 // Add or substract time to all dates, to get GMT dates
154                 $add_hours = intval($diff_gmt_weblogger);
155                 $add_minutes = intval(60 * ($diff_gmt_weblogger - $add_hours));
156                 $wpdb->query("UPDATE $wpdb->posts SET post_date_gmt = DATE_ADD(post_date, INTERVAL '$add_hours:$add_minutes' HOUR_MINUTE)");
157                 $wpdb->query("UPDATE $wpdb->posts SET post_modified = post_date");
158                 $wpdb->query("UPDATE $wpdb->posts SET post_modified_gmt = DATE_ADD(post_modified, INTERVAL '$add_hours:$add_minutes' HOUR_MINUTE) WHERE post_modified != '0000-00-00 00:00:00'");
159                 $wpdb->query("UPDATE $wpdb->comments SET comment_date_gmt = DATE_ADD(comment_date, INTERVAL '$add_hours:$add_minutes' HOUR_MINUTE)");
160                 $wpdb->query("UPDATE $wpdb->users SET user_registered = DATE_ADD(user_registered, INTERVAL '$add_hours:$add_minutes' HOUR_MINUTE)");
161         }
162
163 }
164
165 function upgrade_130() {
166     global $wpdb, $table_prefix;
167
168     // Remove extraneous backslashes.
169         $posts = $wpdb->get_results("SELECT ID, post_title, post_content, post_excerpt, guid, post_date, post_name, post_status, post_author FROM $wpdb->posts");
170         if ($posts) {
171                 foreach($posts as $post) {
172             $post_content = addslashes(deslash($post->post_content));
173             $post_title = addslashes(deslash($post->post_title));
174             $post_excerpt = addslashes(deslash($post->post_excerpt));
175                         if ( empty($post->guid) )
176                                 $guid = get_permalink($post->ID);
177                         else
178                                 $guid = $post->guid;
179
180             $wpdb->query("UPDATE $wpdb->posts SET post_title = '$post_title', post_content = '$post_content', post_excerpt = '$post_excerpt', guid = '$guid' WHERE ID = '$post->ID'");
181                 }
182         }
183
184     // Remove extraneous backslashes.
185         $comments = $wpdb->get_results("SELECT comment_ID, comment_author, comment_content FROM $wpdb->comments");
186         if ($comments) {
187                 foreach($comments as $comment) {
188             $comment_content = addslashes(deslash($comment->comment_content));
189             $comment_author = addslashes(deslash($comment->comment_author));
190             $wpdb->query("UPDATE $wpdb->comments SET comment_content = '$comment_content', comment_author = '$comment_author' WHERE comment_ID = '$comment->comment_ID'");
191                 }
192         }
193
194     // Remove extraneous backslashes.
195         $links = $wpdb->get_results("SELECT link_id, link_name, link_description FROM $wpdb->links");
196         if ($links) {
197                 foreach($links as $link) {
198             $link_name = addslashes(deslash($link->link_name));
199             $link_description = addslashes(deslash($link->link_description));
200             $wpdb->query("UPDATE $wpdb->links SET link_name = '$link_name', link_description = '$link_description' WHERE link_id = '$link->link_id'");
201                 }
202         }
203
204     // The "paged" option for what_to_show is no more.
205     if ($wpdb->get_var("SELECT option_value FROM $wpdb->options WHERE option_name = 'what_to_show'") == 'paged') {
206         $wpdb->query("UPDATE $wpdb->options SET option_value = 'posts' WHERE option_name = 'what_to_show'");
207     }
208
209                 $active_plugins = __get_option('active_plugins');
210
211                 // If plugins are not stored in an array, they're stored in the old
212                 // newline separated format.  Convert to new format.
213                 if ( !is_array( $active_plugins ) ) {
214                         $active_plugins = explode("\n", trim($active_plugins));
215                         update_option('active_plugins', $active_plugins);
216                 }
217
218         // Obsolete tables
219         $wpdb->query('DROP TABLE IF EXISTS ' . $table_prefix . 'optionvalues');
220         $wpdb->query('DROP TABLE IF EXISTS ' . $table_prefix . 'optiontypes');
221         $wpdb->query('DROP TABLE IF EXISTS ' . $table_prefix . 'optiongroups');
222         $wpdb->query('DROP TABLE IF EXISTS ' . $table_prefix . 'optiongroup_options');
223
224         // Update comments table to use comment_type
225         $wpdb->query("UPDATE $wpdb->comments SET comment_type='trackback', comment_content = REPLACE(comment_content, '<trackback />', '') WHERE comment_content LIKE '<trackback />%'");
226         $wpdb->query("UPDATE $wpdb->comments SET comment_type='pingback', comment_content = REPLACE(comment_content, '<pingback />', '') WHERE comment_content LIKE '<pingback />%'");
227
228         // Some versions have multiple duplicate option_name rows with the same values
229         $options = $wpdb->get_results("SELECT option_name, COUNT(option_name) AS dupes FROM `$wpdb->options` GROUP BY option_name");
230         foreach ( $options as $option ) {
231                 if ( 1 != $option->dupes ) { // Could this be done in the query?
232                         $limit = $option->dupes - 1;
233                         $dupe_ids = $wpdb->get_col("SELECT option_id FROM $wpdb->options WHERE option_name = '$option->option_name' LIMIT $limit");
234                         $dupe_ids = join($dupe_ids, ',');
235                         $wpdb->query("DELETE FROM $wpdb->options WHERE option_id IN ($dupe_ids)");
236                 }
237         }
238
239         make_site_theme();
240 }
241
242 function upgrade_160() {
243         global $wpdb, $table_prefix, $wp_current_db_version;
244
245         populate_roles_160();
246
247         $users = $wpdb->get_results("SELECT * FROM $wpdb->users");
248         foreach ( $users as $user ) :
249                 if ( !empty( $user->user_firstname ) )
250                         update_usermeta( $user->ID, 'first_name', $wpdb->escape($user->user_firstname) );
251                 if ( !empty( $user->user_lastname ) )
252                         update_usermeta( $user->ID, 'last_name', $wpdb->escape($user->user_lastname) );
253                 if ( !empty( $user->user_nickname ) )
254                         update_usermeta( $user->ID, 'nickname', $wpdb->escape($user->user_nickname) );
255                 if ( !empty( $user->user_level ) )
256                         update_usermeta( $user->ID, $table_prefix . 'user_level', $user->user_level );
257                 if ( !empty( $user->user_icq ) )
258                         update_usermeta( $user->ID, 'icq', $wpdb->escape($user->user_icq) );
259                 if ( !empty( $user->user_aim ) )
260                         update_usermeta( $user->ID, 'aim', $wpdb->escape($user->user_aim) );
261                 if ( !empty( $user->user_msn ) )
262                         update_usermeta( $user->ID, 'msn', $wpdb->escape($user->user_msn) );
263                 if ( !empty( $user->user_yim ) )
264                         update_usermeta( $user->ID, 'yim', $wpdb->escape($user->user_icq) );
265                 if ( !empty( $user->user_description ) )
266                         update_usermeta( $user->ID, 'description', $wpdb->escape($user->user_description) );
267
268                 if ( isset( $user->user_idmode ) ):
269                         $idmode = $user->user_idmode;
270                         if ($idmode == 'nickname') $id = $user->user_nickname;
271                         if ($idmode == 'login') $id = $user->user_login;
272                         if ($idmode == 'firstname') $id = $user->user_firstname;
273                         if ($idmode == 'lastname') $id = $user->user_lastname;
274                         if ($idmode == 'namefl') $id = $user->user_firstname.' '.$user->user_lastname;
275                         if ($idmode == 'namelf') $id = $user->user_lastname.' '.$user->user_firstname;
276                         if (!$idmode) $id = $user->user_nickname;
277                         $id = $wpdb->escape( $id );
278                         $wpdb->query("UPDATE $wpdb->users SET display_name = '$id' WHERE ID = '$user->ID'");
279                 endif;
280                 
281                 // FIXME: RESET_CAPS is temporary code to reset roles and caps if flag is set.
282                 $caps = get_usermeta( $user->ID, $table_prefix . 'capabilities');
283                 if ( empty($caps) || defined('RESET_CAPS') ) {
284                         $level = get_usermeta($user->ID, $table_prefix . 'user_level');
285                         $role = translate_level_to_role($level);
286                         update_usermeta( $user->ID, $table_prefix . 'capabilities', array($role => true) );
287                 }
288                         
289         endforeach;
290         $old_user_fields = array( 'user_firstname', 'user_lastname', 'user_icq', 'user_aim', 'user_msn', 'user_yim', 'user_idmode', 'user_ip', 'user_domain', 'user_browser', 'user_description', 'user_nickname', 'user_level' );
291         $wpdb->hide_errors();
292         foreach ( $old_user_fields as $old )
293                 $wpdb->query("ALTER TABLE $wpdb->users DROP $old");
294         $wpdb->show_errors();
295         
296         if ( 0 == $wpdb->get_var("SELECT SUM(category_count) FROM $wpdb->categories") ) { // Create counts
297                 $categories = $wpdb->get_col("SELECT cat_ID FROM $wpdb->categories");
298                 foreach ( $categories as $cat_id ) {
299                         $count = $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->post2cat, $wpdb->posts WHERE $wpdb->posts.ID=$wpdb->post2cat.post_id AND post_status='publish' AND category_id = '$cat_id'");
300                         $wpdb->query("UPDATE $wpdb->categories SET category_count = '$count' WHERE cat_ID = '$cat_id'");
301                 }
302         }
303
304         // populate comment_count field of posts table
305         $comments = $wpdb->get_results( "SELECT comment_post_ID, COUNT(*) as c FROM $wpdb->comments WHERE comment_approved = '1' GROUP BY comment_post_ID" );
306         if( is_array( $comments ) ) {
307                 foreach ($comments as $comment) {
308                         $wpdb->query( "UPDATE $wpdb->posts SET comment_count = $comment->c WHERE ID = '$comment->comment_post_ID'" );
309                 }
310         }
311
312         // Some alpha versions used a post status of object instead of attachment and put
313         // the mime type in post_type instead of post_mime_type.
314         if ( $wp_current_db_version > 2541 && $wp_current_db_version <= 3091 ) {
315                 $objects = $wpdb->get_results("SELECT ID, post_type FROM $wpdb->posts WHERE post_status = 'object'");
316                 foreach ($objects as $object) {
317                         $wpdb->query("UPDATE $wpdb->posts SET post_status = 'attachment',
318                         post_mime_type = '$object->post_type',
319                         post_type = ''
320                         WHERE ID = $object->ID");
321                         
322                         $meta = get_post_meta($object->ID, 'imagedata', true);
323                         if ( ! empty($meta['file']) )
324                                 add_post_meta($object->ID, '_wp_attached_file', $meta['file']);
325                 }
326         }
327 }
328
329 // The functions we use to actually do stuff
330
331 // General
332 function maybe_create_table($table_name, $create_ddl) {
333     global $wpdb;
334     foreach ($wpdb->get_col("SHOW TABLES",0) as $table ) {
335         if ($table == $table_name) {
336             return true;
337         }
338     }
339     //didn't find it try to create it.
340     $q = $wpdb->query($create_ddl);
341     // we cannot directly tell that whether this succeeded!
342     foreach ($wpdb->get_col("SHOW TABLES",0) as $table ) {
343         if ($table == $table_name) {
344             return true;
345         }
346     }
347     return false;
348 }
349
350 function drop_index($table, $index) {
351         global $wpdb;
352         $wpdb->hide_errors();
353         $wpdb->query("ALTER TABLE `$table` DROP INDEX `$index`");
354         // Now we need to take out all the extra ones we may have created
355         for ($i = 0; $i < 25; $i++) {
356                 $wpdb->query("ALTER TABLE `$table` DROP INDEX `{$index}_$i`");
357         }
358         $wpdb->show_errors();
359         return true;
360 }
361
362 function add_clean_index($table, $index) {
363         global $wpdb;
364         drop_index($table, $index);
365         $wpdb->query("ALTER TABLE `$table` ADD INDEX ( `$index` )");
366         return true;
367 }
368
369 /**
370  ** maybe_add_column()
371  ** Add column to db table if it doesn't exist.
372  ** Returns:  true if already exists or on successful completion
373  **           false on error
374  */
375 function maybe_add_column($table_name, $column_name, $create_ddl) {
376     global $wpdb, $debug;
377     foreach ($wpdb->get_col("DESC $table_name", 0) as $column ) {
378         if ($debug) echo("checking $column == $column_name<br />");
379         if ($column == $column_name) {
380             return true;
381         }
382     }
383     //didn't find it try to create it.
384     $q = $wpdb->query($create_ddl);
385     // we cannot directly tell that whether this succeeded!
386     foreach ($wpdb->get_col("DESC $table_name", 0) as $column ) {
387         if ($column == $column_name) {
388             return true;
389         }
390     }
391     return false;
392 }
393
394
395 // get_alloptions as it was for 1.2.
396 function get_alloptions_110() {
397         global $wpdb;
398         if ($options = $wpdb->get_results("SELECT option_name, option_value FROM $wpdb->options")) {
399                 foreach ($options as $option) {
400                         // "When trying to design a foolproof system, 
401                         //  never underestimate the ingenuity of the fools :)" -- Dougal
402                         if ('siteurl' == $option->option_name) $option->option_value = preg_replace('|/+$|', '', $option->option_value);
403                         if ('home' == $option->option_name) $option->option_value = preg_replace('|/+$|', '', $option->option_value);
404                         if ('category_base' == $option->option_name) $option->option_value = preg_replace('|/+$|', '', $option->option_value);
405                         $all_options->{$option->option_name} = stripslashes($option->option_value);
406                 }
407         }
408         return $all_options;
409 }
410
411 // Version of get_option that is private to install/upgrade.
412 function __get_option($setting) {
413         global $wpdb;
414
415         $option = $wpdb->get_var("SELECT option_value FROM $wpdb->options WHERE option_name = '$setting'");
416
417         if ( 'home' == $setting && '' == $option )
418                 return __get_option('siteurl');
419
420         if ( 'siteurl' == $setting || 'home' == $setting || 'category_base' == $setting )
421                 $option = preg_replace('|/+$|', '', $option);
422
423         @ $kellogs = unserialize($option);
424         if ($kellogs !== FALSE)
425                 return $kellogs;
426         else
427                 return $option;
428 }
429
430 function deslash($content) {
431     // Note: \\\ inside a regex denotes a single backslash.
432
433     // Replace one or more backslashes followed by a single quote with
434     // a single quote.
435     $content = preg_replace("/\\\+'/", "'", $content);
436
437     // Replace one or more backslashes followed by a double quote with
438     // a double quote.
439     $content = preg_replace('/\\\+"/', '"', $content);
440
441     // Replace one or more backslashes with one backslash.
442     $content = preg_replace("/\\\+/", "\\", $content);
443
444     return $content;
445 }
446
447 function dbDelta($queries, $execute = true) {
448         global $wpdb;
449         
450         // Seperate individual queries into an array
451         if( !is_array($queries) ) {
452                 $queries = explode( ';', $queries );
453                 if('' == $queries[count($queries) - 1]) array_pop($queries);
454         }
455         
456         $cqueries = array(); // Creation Queries
457         $iqueries = array(); // Insertion Queries
458         $for_update = array();
459         
460         // Create a tablename index for an array ($cqueries) of queries
461         foreach($queries as $qry) {
462                 if(preg_match("|CREATE TABLE ([^ ]*)|", $qry, $matches)) {
463                         $cqueries[strtolower($matches[1])] = $qry;
464                         $for_update[$matches[1]] = 'Created table '.$matches[1];
465                 }
466                 else if(preg_match("|CREATE DATABASE ([^ ]*)|", $qry, $matches)) {
467                         array_unshift($cqueries, $qry);
468                 }
469                 else if(preg_match("|INSERT INTO ([^ ]*)|", $qry, $matches)) {
470                         $iqueries[] = $qry;
471                 }
472                 else if(preg_match("|UPDATE ([^ ]*)|", $qry, $matches)) {
473                         $iqueries[] = $qry;
474                 }
475                 else {
476                         // Unrecognized query type
477                 }
478         }       
479
480         // Check to see which tables and fields exist
481         if($tables = $wpdb->get_col('SHOW TABLES;')) {
482                 // For every table in the database
483                 foreach($tables as $table) {
484                         // If a table query exists for the database table...
485                         if( array_key_exists(strtolower($table), $cqueries) ) {
486                                 // Clear the field and index arrays
487                                 unset($cfields);
488                                 unset($indices);
489                                 // Get all of the field names in the query from between the parens
490                                 preg_match("|\((.*)\)|ms", $cqueries[strtolower($table)], $match2);
491                                 $qryline = trim($match2[1]);
492
493                                 // Separate field lines into an array
494                                 $flds = explode("\n", $qryline);
495
496                                 //echo "<hr/><pre>\n".print_r(strtolower($table), true).":\n".print_r($cqueries, true)."</pre><hr/>";
497                                 
498                                 // For every field line specified in the query
499                                 foreach($flds as $fld) {
500                                         // Extract the field name
501                                         preg_match("|^([^ ]*)|", trim($fld), $fvals);
502                                         $fieldname = $fvals[1];
503                                         
504                                         // Verify the found field name
505                                         $validfield = true;
506                                         switch(strtolower($fieldname))
507                                         {
508                                         case '':
509                                         case 'primary':
510                                         case 'index':
511                                         case 'fulltext':
512                                         case 'unique':
513                                         case 'key':
514                                                 $validfield = false;
515                                                 $indices[] = trim(trim($fld), ", \n");
516                                                 break;
517                                         }
518                                         $fld = trim($fld);
519                                         
520                                         // If it's a valid field, add it to the field array
521                                         if($validfield) {
522                                                 $cfields[strtolower($fieldname)] = trim($fld, ", \n");
523                                         }
524                                 }
525                                 
526                                 // Fetch the table column structure from the database
527                                 $tablefields = $wpdb->get_results("DESCRIBE {$table};");
528                                                                 
529                                 // For every field in the table
530                                 foreach($tablefields as $tablefield) {                          
531                                         // If the table field exists in the field array...
532                                         if(array_key_exists(strtolower($tablefield->Field), $cfields)) {
533                                                 // Get the field type from the query
534                                                 preg_match("|".$tablefield->Field." ([^ ]*( unsigned)?)|i", $cfields[strtolower($tablefield->Field)], $matches);
535                                                 $fieldtype = $matches[1];
536
537                                                 // Is actual field type different from the field type in query?
538                                                 if($tablefield->Type != $fieldtype) {
539                                                         // Add a query to change the column type
540                                                         $cqueries[] = "ALTER TABLE {$table} CHANGE COLUMN {$tablefield->Field} " . $cfields[strtolower($tablefield->Field)];
541                                                         $for_update[$table.'.'.$tablefield->Field] = "Changed type of {$table}.{$tablefield->Field} from {$tablefield->Type} to {$fieldtype}";
542                                                 }
543                                                 
544                                                 // Get the default value from the array
545                                                         //echo "{$cfields[strtolower($tablefield->Field)]}<br>";
546                                                 if(preg_match("| DEFAULT '(.*)'|i", $cfields[strtolower($tablefield->Field)], $matches)) {
547                                                         $default_value = $matches[1];
548                                                         if($tablefield->Default != $default_value)
549                                                         {
550                                                                 // Add a query to change the column's default value
551                                                                 $cqueries[] = "ALTER TABLE {$table} ALTER COLUMN {$tablefield->Field} SET DEFAULT '{$default_value}'";
552                                                                 $for_update[$table.'.'.$tablefield->Field] = "Changed default value of {$table}.{$tablefield->Field} from {$tablefield->Default} to {$default_value}";
553                                                         }
554                                                 }
555
556                                                 // Remove the field from the array (so it's not added)
557                                                 unset($cfields[strtolower($tablefield->Field)]);
558                                         }
559                                         else {
560                                                 // This field exists in the table, but not in the creation queries?
561                                         }
562                                 }
563
564                                 // For every remaining field specified for the table
565                                 foreach($cfields as $fieldname => $fielddef) {
566                                         // Push a query line into $cqueries that adds the field to that table
567                                         $cqueries[] = "ALTER TABLE {$table} ADD COLUMN $fielddef";
568                                         $for_update[$table.'.'.$fieldname] = 'Added column '.$table.'.'.$fieldname;
569                                 }
570                                 
571                                 // Index stuff goes here
572                                 // Fetch the table index structure from the database
573                                 $tableindices = $wpdb->get_results("SHOW INDEX FROM {$table};");
574                                 
575                                 if($tableindices) {
576                                         // Clear the index array
577                                         unset($index_ary);
578
579                                         // For every index in the table
580                                         foreach($tableindices as $tableindex) {
581                                                 // Add the index to the index data array
582                                                 $keyname = $tableindex->Key_name;
583                                                 $index_ary[$keyname]['columns'][] = array('fieldname' => $tableindex->Column_name, 'subpart' => $tableindex->Sub_part);
584                                                 $index_ary[$keyname]['unique'] = ($tableindex->Non_unique == 0)?true:false;
585                                         }
586
587                                         // For each actual index in the index array
588                                         foreach($index_ary as $index_name => $index_data) {
589                                                 // Build a create string to compare to the query
590                                                 $index_string = '';
591                                                 if($index_name == 'PRIMARY') {
592                                                         $index_string .= 'PRIMARY ';
593                                                 }
594                                                 else if($index_data['unique']) {
595                                                         $index_string .= 'UNIQUE ';
596                                                 }
597                                                 $index_string .= 'KEY ';
598                                                 if($index_name != 'PRIMARY') {
599                                                         $index_string .= $index_name;
600                                                 }
601                                                 $index_columns = '';
602                                                 // For each column in the index
603                                                 foreach($index_data['columns'] as $column_data) {                                       
604                                                         if($index_columns != '') $index_columns .= ',';
605                                                         // Add the field to the column list string
606                                                         $index_columns .= $column_data['fieldname'];
607                                                         if($column_data['subpart'] != '') {
608                                                                 $index_columns .= '('.$column_data['subpart'].')';
609                                                         }
610                                                 }
611                                                 // Add the column list to the index create string 
612                                                 $index_string .= ' ('.$index_columns.')';
613
614                                                 if(!(($aindex = array_search($index_string, $indices)) === false)) {
615                                                         unset($indices[$aindex]);
616                                                         //echo "<pre style=\"border:1px solid #ccc;margin-top:5px;\">{$table}:<br/>Found index:".$index_string."</pre>\n";
617                                                 }
618                                                 //else echo "<pre style=\"border:1px solid #ccc;margin-top:5px;\">{$table}:<br/><b>Did not find index:</b>".$index_string."<br/>".print_r($indices, true)."</pre>\n";
619                                         }
620                                 }
621
622                                 // For every remaining index specified for the table
623                                 foreach($indices as $index) {
624                                         // Push a query line into $cqueries that adds the index to that table
625                                         $cqueries[] = "ALTER TABLE {$table} ADD $index";
626                                         $for_update[$table.'.'.$fieldname] = 'Added index '.$table.' '.$index;
627                                 }
628
629                                 // Remove the original table creation query from processing
630                                 unset($cqueries[strtolower($table)]);
631                                 unset($for_update[strtolower($table)]);
632                         } else {
633                                 // This table exists in the database, but not in the creation queries?
634                         }
635                 }
636         }
637
638         $allqueries = array_merge($cqueries, $iqueries);
639         if($execute) {
640                 foreach($allqueries as $query) {
641                         //echo "<pre style=\"border:1px solid #ccc;margin-top:5px;\">".print_r($query, true)."</pre>\n";
642                         $wpdb->query($query);
643                 }
644         }
645
646         return $for_update;
647 }
648
649 function make_db_current() {
650         global $wp_queries;
651
652         $alterations = dbDelta($wp_queries);
653         echo "<ol>\n";
654         foreach($alterations as $alteration) echo "<li>$alteration</li>\n";
655         echo "</ol>\n";
656 }
657
658 function make_db_current_silent() {
659         global $wp_queries;
660
661         $alterations = dbDelta($wp_queries);
662 }
663
664 function make_site_theme_from_oldschool($theme_name, $template) {
665         $home_path = get_home_path();
666         $site_dir = ABSPATH . "wp-content/themes/$template";
667
668         if (! file_exists("$home_path/index.php"))
669                 return false;
670
671         // Copy files from the old locations to the site theme.
672         // TODO: This does not copy arbitarary include dependencies.  Only the
673         // standard WP files are copied.
674         $files = array('index.php' => 'index.php', 'wp-layout.css' => 'style.css', 'wp-comments.php' => 'comments.php', 'wp-comments-popup.php' => 'comments-popup.php');
675
676         foreach ($files as $oldfile => $newfile) {
677                 if ($oldfile == 'index.php')
678                         $oldpath = $home_path;
679                 else
680                         $oldpath = ABSPATH;
681
682                 if ($oldfile == 'index.php') { // Check to make sure it's not a new index
683                         $index = implode('', file("$oldpath/$oldfile"));
684                         if ( strstr( $index, 'WP_USE_THEMES' ) ) {
685                                 if (! @copy(ABSPATH . 'wp-content/themes/default/index.php', "$site_dir/$newfile"))
686                                         return false;
687                                 continue; // Don't copy anything
688                                 }
689                 }
690
691                 if (! @copy("$oldpath/$oldfile", "$site_dir/$newfile"))
692                         return false;
693
694                 chmod("$site_dir/$newfile", 0777);
695
696                 // Update the blog header include in each file.
697                 $lines = explode("\n", implode('', file("$site_dir/$newfile")));
698                 if ($lines) {
699                         $f = fopen("$site_dir/$newfile", 'w');
700
701                         foreach ($lines as $line) {
702                                 if (preg_match('/require.*wp-blog-header/', $line))
703                                         $line = '//' . $line;
704
705                                 // Update stylesheet references.
706                                 $line = str_replace("<?php echo __get_option('siteurl'); ?>/wp-layout.css", "<?php bloginfo('stylesheet_url'); ?>", $line);
707
708                                 // Update comments template inclusion.
709                                 $line = str_replace("<?php include(ABSPATH . 'wp-comments.php'); ?>", "<?php comments_template(); ?>", $line);
710
711                                 fwrite($f, "{$line}\n");
712                         }
713                         fclose($f);
714                 }
715         }
716
717         // Add a theme header.
718         $header = "/*\nTheme Name: $theme_name\nTheme URI: " . __get_option('siteurl') . "\nDescription: A theme automatically created by the upgrade.\nVersion: 1.0\nAuthor: Moi\n*/\n";
719
720         $stylelines = file_get_contents("$site_dir/style.css");
721         if ($stylelines) {
722                 $f = fopen("$site_dir/style.css", 'w');
723
724                 fwrite($f, $header);
725                 fwrite($f, $stylelines);
726                 fclose($f);
727         }
728
729         return true;
730 }
731
732 function make_site_theme_from_default($theme_name, $template) {
733         $site_dir = ABSPATH . "wp-content/themes/$template";
734         $default_dir = ABSPATH . 'wp-content/themes/default';
735
736         // Copy files from the default theme to the site theme.
737         //$files = array('index.php', 'comments.php', 'comments-popup.php', 'footer.php', 'header.php', 'sidebar.php', 'style.css');
738
739         $theme_dir = @ dir("$default_dir");
740         if ($theme_dir) {
741                 while(($theme_file = $theme_dir->read()) !== false) {
742                         if (is_dir("$default_dir/$theme_file"))
743                                 continue;
744                         if (! @copy("$default_dir/$theme_file", "$site_dir/$theme_file"))
745                                 return;
746                         chmod("$site_dir/$theme_file", 0777);
747                 }
748         }
749
750         // Rewrite the theme header.
751         $stylelines = explode("\n", implode('', file("$site_dir/style.css")));
752         if ($stylelines) {
753                 $f = fopen("$site_dir/style.css", 'w');
754
755                 foreach ($stylelines as $line) {
756                         if (strstr($line, "Theme Name:")) $line = "Theme Name: $theme_name";
757                         elseif (strstr($line, "Theme URI:")) $line = "Theme URI: " . __get_option('siteurl');
758                         elseif (strstr($line, "Description:")) $line = "Description: Your theme";
759                         elseif (strstr($line, "Version:")) $line = "Version: 1";
760                         elseif (strstr($line, "Author:")) $line = "Author: You";
761                         fwrite($f, "{$line}\n");
762                 }
763                 fclose($f);
764         }
765
766         // Copy the images.
767         umask(0);
768         if (! mkdir("$site_dir/images", 0777)) {
769                 return false;
770         }
771
772         $images_dir = @ dir("$default_dir/images");
773         if ($images_dir) {
774                 while(($image = $images_dir->read()) !== false) {
775                         if (is_dir("$default_dir/images/$image"))
776                                 continue;
777                         if (! @copy("$default_dir/images/$image", "$site_dir/images/$image"))
778                                 return;
779                         chmod("$site_dir/images/$image", 0777);
780                 }
781         }
782 }
783
784 // Create a site theme from the default theme.
785 function make_site_theme() {
786         // Name the theme after the blog.
787         $theme_name = __get_option('blogname');
788         $template = sanitize_title($theme_name);
789         $site_dir = ABSPATH . "wp-content/themes/$template";
790
791         // If the theme already exists, nothing to do.
792         if ( is_dir($site_dir)) {
793                 return false;
794         }
795
796         // We must be able to write to the themes dir.
797         if (! is_writable(ABSPATH . "wp-content/themes")) {
798                 return false;
799         }
800
801         umask(0);
802         if (! mkdir($site_dir, 0777)) {
803                 return false;
804         }
805
806         if (file_exists(ABSPATH . 'wp-layout.css')) {
807                 if (! make_site_theme_from_oldschool($theme_name, $template)) {
808                         // TODO:  rm -rf the site theme directory.
809                         return false;
810                 }
811         } else {
812                 if (! make_site_theme_from_default($theme_name, $template))
813                         // TODO:  rm -rf the site theme directory.
814                         return false;
815         }
816
817         // Make the new site theme active.
818         $current_template = __get_option('template');
819         if ($current_template == 'default') {
820                 update_option('template', $template);
821                 update_option('stylesheet', $template);
822         }
823         return $template;
824 }
825
826 function translate_level_to_role($level) {
827         switch ($level) {
828         case 10:
829         case 9:
830         case 8:
831                 return 'administrator';
832         case 7:
833         case 6:
834         case 5:
835                 return 'editor';
836         case 4:
837         case 3:
838         case 2:
839                 return 'author';
840         case 1:
841                 return 'contributor';
842         case 0:
843                 return 'subscriber';
844         }
845 }
846
847 ?>