WordPress与Uchome数据转移要点

网站程序的数据转移原来就进行过一次,是将原来Java版学习日记开源项目网站的数据转移到Wordpress数据库中,见:WordPress数据库基本结构及导入原学习日记数据库相关SQL语句。而Ucenter Home比原来的程序复杂了不少,下面记录一些转移数据的要点和一些关键的转移数据代码。包括从 WordPress 2.8.1 转移到 Uchome 2.0 及 Uchome 2.0 转移到 WordPress 2.8.1。

1、需要的资料

WordPress2.8、Ucenter1.5、Ucenter Home2.0的数据库数据字典,这是在网上找的,其中Wordpress只找到2.7版的数据字典:Ucenter Home2.0的数据字典是基于2.0Beta的,我把它们打包在这里供大家参考: WordPress2.8、Ucenter1.5、Ucenter Home2.0Beta的数据库数据字典
2、从 WordPress 2.8 转移到 UCenter Home 2.0 的主要步骤
1)、用户迁移到UCenter1.5中
包括BLOG作者迁移,Blog评论作者迁移
Wordpress2.8用户相关表:wp_users(用户表)
UCenter 用户数据相关表:uc_memberfields (用户黑名单)、uc_members (用户表)
转移要点:
(1)、因为在Ucenter Home中,必须是注册用户才能发表评论,而在Wordpress中,游客可以发表评论。所以为了把Wordpress的评论和评论者的数据导入Ucenter Home中,必须先在Wordpress中把评论用户转为Wordpress的注册用户;
(2)、Wordpress到Ucenter用户密码的转换,参见:Ucenter密码$salt加密今天研究得出的算法 。不过,由于Wordpress2.8的md5加密在用户登录一次就改变了,不再是密码的md5加密字符串值,所以,对于这种密码的转换我是没有找到方法的。只有让用户在转换后的Ucenter Home中重置密码。
转换代码: cpwpusers2ucenter.php

<?php

//wordpress 数据库连接
$old_link=mysql_connect("localhost","root","123") or die("connect old db fail");

//UCenter 数据库连接
$new_link=mysql_connect("localhost","root","123") or die("connect new db fail");

//用户数据表
$old_uc_dbname="wp_users";
$new_uc_dbname="uc_members";

//选择wordpress的用户数据列表
$old_sql="select * from $old_uc_dbname";
echo "$old_sql<br>";
mysql_select_db("wordpressdb", $old_link) or die("select old db fail");
mysql_query("SET NAMES 'utf8'",$old_link);
$old_result=mysql_query($old_sql);
echo"$old_result<br>";
while($old_row=mysql_fetch_array($old_result)){
$uid=$old_row["ID"];
$username= $old_row["user_login"];
$salt = substr(uniqid(rand()), -6);
$password = md5($old_row["user_pass"].$salt);
$email=$old_row["user_email"];
$regdate=$old_row["user_registered"];
date_default_timezone_set("Asia/Shanghai");
$rdate=strtotime($regdate);
$sql="insert into $new_uc_dbname(uid,username,password,email,regdate,salt) values('$uid','$username','$password','$email','$rdate','$salt')";
echo "$sql<br>";
mysql_select_db("ucenterdb", $new_link) or die("select new db fail");
mysql_query("SET NAMES 'utf8'",$new_link);
mysql_query($sql);
echo "$uid with name: ${username}插入成功<br>";
}

mysql_close($new_link);
mysql_close($old_link);
?>

2)、将Ucenter 1.5的用户数据写入到Ucenter Home 2.0,并开启用户的个人空间
UCenter 用户数据相关表:uc_members (用户表)
UCenter Home 相关表:uchome_member、uchome_space、uchome_spacefield、uchome_feed
其中,uchome_feed是动态,这里只生成每个用户开通了空间的动态,开通的时间设为用户注册的时间

3)、将Wordpress中的日志分类转换到Ucenter Home中
Wordpress 2.8 相关表:wp_posts、wp_term_relationships、wp_term_taxonomy、wp_terms
UCenter Home 2.0 相关表:uchome_class
Wordpress 2.8相关表之间的关系:
wp_posts->wp_term_relationships->wp_term_taxonomy->wp_terms
wp_posts.ID = wp_term_relationships.object_id
wp_term_relationships.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id
wp_term_taxonomy.term_id = wp_terms.term_id

wp_posts.post_status 是表示公开或私有或草稿之类
wp_posts.post_type 是表示是正式提交与分支版本
wp_posts.post_parent  用在日志的分支版本的parent是其下载提交的版本

要点:
(1)、在Wordpress中分类是所有用户公用的,而在Ucenter Home中分类是每个用户独立的,相同的分类可以出现在每个用户中,所以应该检索每个用户的日志,再检索日志的分类,统统把分类写入;
(2)、Ucenter Home 2.0 日志的分类是单分类形式,而wordpress一篇日志可以有多个分类,所以,我的作法删除多余的分类。把多余的分类转换为后面的标签也是一种方法,不过因为增加复杂性,没有这样作;
(3)、为了保持每个用户的日志和原分类的关系,在Ucenter Home中分类的ID为日志的用户ID*20+Wordpress原公用分类ID。分类创建日期为Wordpress的相应分类第一篇日志的日期;
(4)、把Wordpress中的时间转换为Ucenter Home中的时间,在SQL语句中这样转换: UNIX_TIMESTAMP( '2004-10-01 08:08:23' ),php 函数是strtotime()。

另外,转换的时候用到了 UCenter Home 里面的一些函数,如,把日志的标签序列化要用到:get_tags_serial_str($blogid, $tagstr),要在 php 代码中引用一些 Uchome 里的文件,如:common.php, ./source/function_cp.php, ./source/function_magic.php, ./source/function_blog.php 等;另,密码的生成是先把密码 md5 加密,把生成的密码联接一个6个随机字符的 salt 码,再把加密后的密码串联接这个 salt 码再一次 md5 加密得到最终的数据库密码存储字段,保证即使用户密码一样,存储在数据库中的密码字段也不同。

3、把 Uchome 2 中的数据转到 WordPress 2.8 的要点

1)、转移的基本步骤是:用户帐号、日记、分类、标签、评论

2)、统计每篇日记的评论数

SELECT `comment_post_ID` , COUNT( * )
FROM wp_comments
GROUP BY `comment_post_ID`
ORDER BY `comment_post_ID`

3)、从已有日记的标题(post_title)重新生成别名(post_name)最保险的方法是用 WordPress 里面的 wp_insert_post( ) 函数,我用的代码,需保存在 wp-admin 目录下面,并把 w_posts 复制成 wp_posts6,并清空 wp_posts 执行(但是不知什么原因,一次执行不能遍历全部的日记,我两次才把全部的别名重新生成完毕,不知是不是有关内存方面的设置问题):

<?php
require_once('admin.php');

$link=mysql_connect("localhost","dbuser","dbpassword") or die("connect old db fail");
mysql_select_db("dbname", $link) or die("select old db fail");
mysql_query("SET NAMES 'utf8'",$link);

$sql1="SELECT wp_posts6.ID,wp_posts6.post_title FROM wp_posts6 ORDER BY wp_posts6.ID";
$result1=mysql_query($sql1);

while($row1=mysql_fetch_array($result1)){
$ID = $row1["ID"];
$post_title = $row1["post_title"];
echo "$ID"." is: "."$post_title"."<br>";
$my_post = array(
'post_title' => $post_title,
'post_content' => 'This is my post.',
'post_status' => 'publish',
'post_author' => 1,
'post_category' => 0

);
$new_post_id = wp_insert_post( $my_post );

echo "The old ID is: ".$ID." and the new ID is: ".$new_post_id."<br>";
$sql2="INSERT INTO tt SET oid=$ID, nid=$new_post_id";
mysql_select_db("dbname", $link) or die("select old db fail");
mysql_query("SET NAMES 'utf8'",$link);
$result2=mysql_query($sql2);
}
mysql_close($link);
?>

另外,在二者间数据转换的过程中,有时要建一些临时的数据表。还有数据转换完成后,为了保持搜索引擎和用户访问的连续性,还需要做一些 301 重定向的工作。重定向可以在 .htaccess 文件中完成,如:RewriteRule ^space-1-do-blog-id-3826\.html http://www.learndiary\.com/2010/12/blfs-\%e5\%ad\%a6\%e4\%b9\%a0\%e6\%97\%a5\%e8\%ae\%b0\%ef\%bc\%88\%e6\%b5\%8f\%e8\%a7\%88-blfs\%e7\%ac\%ac\%e5\%8d\%81\%e7\%ab\%a0\%e4\%b8\%80\%e8\%88\%ac\%e5\%b7\%a5\%e5\%85\%b7\%e8\%87\%b3\%e7\%bb\%93\%e6\%9d\%9f-\%ef\%bc\%89/ [R=301,L] ,要注意%前必须加上\转义;在 .htaccess 文件中定义 404 页面: ErrorDocument 404 /index.php 。有时也要在 index.php 中进行 301 重定向,如:

<?php
/** 将首页301重定向到http://www.learndiary.com/  */
header("HTTP/1.1 301 Moved Permanently");
header("Location: http://www.learndiary.com/");
exit();
?>

另外,手工的数据转换是个枯燥繁琐的工作,有时由于二者的数据ID不一致,还要手工调整ID,所以还要加点耐心和细心,一步一步的来。