前言
OSChina的API开放至今都没用它做过什么事,如今建了个本站,正打算把文章内容备份到OSChina,官方提供了个导入工具(move.oschina.net),但是无法兼容目前新版的WP,它使用的是wp导出的xml文件。既然如此,何不自己使用API做一个导入工具呢?!
于是,wp2osc诞生了…
wp2osc概述
WP2OSC是一个可以把Wordpress博客的文章有选择的导入OSChina的博客中。
WP2OSC使用纯php代码,结合Wordpress自身的函数来读取文章列表、分类信息,准确率高,速度快,对Wordpress熟悉的同学还可以重新定制下页面显示方式。
wp2osc的导入方式
- 先登录OSCChina,拿到access_token后,回到index.php,token等信息使用session保存;
- 按照Wordpress的分类结构显示文章列表,然后在这个分类上,可以选择OSChina博客的系统分类和用户分类;
- 通过checkbox的方式,选择需要导入的文章。点击开始导入按钮后,程序自动组合当前勾选的文章的ID和对应的分类ID,拼接成json字符串,post给wp2osc.php文件;
- wp2osc.php文件根据文章ID,查询文章的各种信息,然后组合成最终的请求链接,post给OSChina Open API指定的URL上。
使用方法
访问我的git仓库,下载源码:https://git.oschina.net/lijialong1314/WP2OSC
- 下载文件后,把app目录放到wordpress站点的根目录;
- 打开app/wp2osc/index.php文件,修改第61行(您自己的oschina用户ID);
- 打开app/wp2osc/wp2osc.php文件,修改第9行(您自己的oschina用户ID);
- 打开app/wp2osc/token.php文件,修改第8,9,10行(您自己的APPkey,Secret,回调url需要设置为token.php文件在线上访问的完整路径);
- 访问 http://您的域名/app/wp2osc。
效果预览:http://devonios.com/app/wp2osc
存在的问题
由于OSChina的OpenAPI在处理content参数时,过滤了img标签,所以导入的文章无法显示图片。。。 详见:使用OpenApi导入Wordpress的博客内容时,图片地址如何处理?
目前只能手动复制图片源地址,然后粘贴到oschina的博客编辑器中,保存时,oschina会自动下载图片保存到自己的服务器上。
代码(1)获取Token
OSChina的API同样基于OAuth2(真是腻了…),需要先GET Code,然后用Code去Get Token。
我的做法是:在一个叫token.php的文件中,检测是否有code参数,如果没有就跳转到oschina的验证页面,登录成功后,oschina会跳回token.php页面,此时有了code参数,那就可以用它去请求获取token了,拿到token后,就可以把它保存在session中,然后再跳到程序的首页(index.php)。
<?php session_start(); require("../lib/common.php"); $dataType = "json"; $response_type = "code"; $grant_type = "authorization_code"; $client_id = "您的app key"; $client_secret = "您的app secret"; //回调地址,需要设置为当前token.php文件在线上访问的完整路径 $redirect_uri = "http://devonios.com/app/wp2osc/token.php"; $codeurl = "https://www.oschina.net/action/oauth2/authorize"; $tokenurl = "https://www.oschina.net/action/openapi/token?"; $userurl = "https://www.oschina.net/action/openapi/user"; $cateurl = "https://www.oschina.net/action/openapi/blog_catalog_list"; $code = $_GET["code"]; if ($code != "") { //获取token数据 } else { header("Location: ".$codeurl."?response_type=".$response_type."&client_id=".$client_id."&redirect_uri=".$redirect_uri); }
获取token数据部分代码:
//请求的参数数组 $fields = [ "grant_type" => urlencode($grant_type), "client_id" => urlencode($client_id), "redirect_uri" => urlencode($redirect_uri), "code" => urlencode($code), "state" => urlencode($state), "client_secret" => urlencode($client_secret), "dataType" => urlencode($dataType) ]; //转换成字符串 $fields_string = ""; foreach($fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } rtrim($fields_string, '&'); //发送请求获取json数据 //拿到数据后,保存到session中 $_SESSION["osctoken"] = $token; $_SESSION["oscusername"] = $username; $_SESSION["oscuserid"] = $userid; $_SESSION["syscate"] = $blog_sys_catalog_listArray; $_SESSION["usercate"] = $blog_user_catalog_listArray; //然后回到首页 header("Location: index.php");
代码(2)读取Wordpress的分类和文章
当回到index.php后,需要在页面显示文章列表,这里是用分类结构来显示的,即先读分类,然后用分类ID去读该分类下的所有文章。循环用列表方式(li)显示。
global $wpdb; $request = "SELECT $wpdb->terms.term_id, name FROM $wpdb->terms "; $request .= " LEFT JOIN $wpdb->term_taxonomy ON $wpdb->term_taxonomy.term_id = $wpdb->terms.term_id "; $request .= " WHERE $wpdb->term_taxonomy.taxonomy = 'category' "; $request .= " ORDER BY term_id asc"; $categorys = $wpdb->get_results($request); //循环每个分类 foreach ($categorys as $category) { $catname = $category->name; $catid = $category->term_id; //这里显示html代码 //通过分类id,查询分类下的所有文章 $catposts = new WP_Query(); $catposts->query('cat='.$catid); while ($catposts->have_posts()) : $catposts->the_post(); //这里显示html代码 endwhile; }
代码(3)根据文章ID获取文章详细信息(内容、标题、标签等)
在我们准备提交数据时,需要先通过选择的文章id获取文章的相关信息。
foreach($postidsobj as $postid) { //一篇文章对象,使用wp提供的get_post函数 $_post = get_post($postid); //内容 $content = $_post->post_content; //将内容中的代码pre标签的class转换为oschina支持的 $content = convert_pre_to_oscpre($content); //文章内容底部插入一些固定信息 $content = insert_footinfo_content($content,$_post->post_name); //标题 $title = $_post->post_title; //摘要,截取200字符 $length = apply_filters('excerpt_length',200); $abstracts= apply_filters('the_excerpt',wp_trim_words($content,$length)); //标签,用wp提供的wp_get_post_tags函数,转换成逗号分割的字符串 $tags = wp_get_post_tags($postid); $_tags = ""; foreach($tags as $tag){ $_tags .= ($tag->name.","); } rtrim($_tags, ','); $postdata["catalog"] = $usercateid; $postdata["classification"] = $syscateid; $postdata["content"] = $content; $postdata["title"] = $title; $postdata["abstracts"]= preg_replace("/<(.*?)>/","",$abstracts);//摘要内容去掉html代码,oschina博客的摘要是纯文本形式 $postdata["tags"] = $_tags; $resultJson = send_post($posturl,$postdata); $resultJsonObj = json_decode($resultJson,true); //结果保存下来 $allresult[] = "文章ID:".$postid.",文章标题:".$title.",状态:".$resultJsonObj["error_description"]; }
代码(4)转换pre代码标签
由于两边的代码高亮用的不是同一个插件,所以需要修改pre标签,这个需要根据您所用的编辑器,所用的代码高亮插件来调整。
我的代码如下:
function convert_pre_to_oscpre($content){ $repArray = [ 'class="prettyprint"' => 'class="brush:cpp;"', 'class="prettyprint lang-php"' => 'class="brush:php;"', 'class="prettyprint lang-cpp"' => 'class="brush:cpp;"', 'class="prettyprint lang-bsh"' => 'class="brush:shell;"', 'class="prettyprint lang-js"' => 'class="brush:js;"', 'class="prettyprint lang-css"' => 'class="brush:css;"', 'class="prettyprint lang-html"' => 'class="brush:html;"' ]; foreach($repArray as $key=>$value){ $content = str_replace($key,$value,$content); } return $content; }
代码(5)php发送get和post请求
很简单,使用curl即可。
function send_get($urlstring) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $urlstring); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $result = curl_exec($ch); curl_close($ch); return $result; } function send_post($urlstring,$data) { $ch = curl_init(); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_URL, $urlstring); curl_setopt($ch, CURLOPT_POSTFIELDS, $data); $result = curl_exec($ch); curl_close($ch); return $result; }
界面效果图
导入结束,显示结果: