PageRenderTime 27ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/index.php

https://bitbucket.org/lyonnat/wp2op
PHP | 355 lines | 308 code | 41 blank | 6 comment | 59 complexity | bc9e85ef4662f38e358e0518075e83b8 MD5 | raw file
  1. <?php
  2. if(file_exists('wxr.xml')) {
  3. unlink('wxr.xml');
  4. }
  5. if(file_exists('md')) {
  6. deldir('md');
  7. }
  8. if(file_exists('md.zip')) {
  9. unlink('md.zip');
  10. }
  11. if ($_SERVER['REQUEST_METHOD'] == 'GET') {
  12. ?>
  13. <!doctype html>
  14. <html>
  15. <head>
  16. <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
  17. <title>WXR Markdown</title>
  18. </head>
  19. <body>
  20. <form action="<?=$_SERVER['PHP_SELF']?>" enctype="multipart/form-data" method="POST">
  21. <input type="file" name="wxr"><br />
  22. <input type="submit" value="上传 XML" />
  23. </form>
  24. </body>
  25. </html>
  26. <?php }
  27. elseif ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_FILES['wxr'])) {
  28. if ($_FILES['wxr']['size'] == 0) {
  29. header('Location: '.$_SERVER['PHP_SELF']);
  30. }
  31. class WXR_Parser_SimpleXML {
  32. function parse( $file ) {
  33. $authors = $posts = $categories = $tags = $terms = array();
  34. $internal_errors = libxml_use_internal_errors(true);
  35. $dom = new DOMDocument;
  36. $old_value = null;
  37. if ( function_exists( 'libxml_disable_entity_loader' ) ) {
  38. $old_value = libxml_disable_entity_loader( true );
  39. }
  40. $success = $dom->loadXML( file_get_contents( $file ) );
  41. if ( ! is_null( $old_value ) ) {
  42. libxml_disable_entity_loader( $old_value );
  43. }
  44. if ( ! $success || isset( $dom->doctype ) ) {
  45. return false;
  46. }
  47. $xml = simplexml_import_dom( $dom );
  48. unset( $dom );
  49. // halt if loading produces an error
  50. if ( ! $xml )
  51. return false;
  52. $wxr_version = $xml->xpath('/rss/channel/wp:wxr_version');
  53. if ( ! $wxr_version )
  54. return false;
  55. $wxr_version = (string) trim( $wxr_version[0] );
  56. // confirm that we are dealing with the correct file format
  57. if ( ! preg_match( '/^\d+\.\d+$/', $wxr_version ) )
  58. return false;
  59. $base_url = $xml->xpath('/rss/channel/wp:base_site_url');
  60. $base_url = (string) trim( $base_url[0] );
  61. $namespaces = $xml->getDocNamespaces();
  62. if ( ! isset( $namespaces['wp'] ) )
  63. $namespaces['wp'] = 'http://wordpress.org/export/1.1/';
  64. if ( ! isset( $namespaces['excerpt'] ) )
  65. $namespaces['excerpt'] = 'http://wordpress.org/export/1.1/excerpt/';
  66. // grab authors
  67. foreach ( $xml->xpath('/rss/channel/wp:author') as $author_arr ) {
  68. $a = $author_arr->children( $namespaces['wp'] );
  69. $login = (string) $a->author_login;
  70. $authors[$login] = array(
  71. 'author_id' => (int) $a->author_id,
  72. 'author_login' => $login,
  73. 'author_email' => (string) $a->author_email,
  74. 'author_display_name' => (string) $a->author_display_name,
  75. 'author_first_name' => (string) $a->author_first_name,
  76. 'author_last_name' => (string) $a->author_last_name
  77. );
  78. }
  79. // grab cats, tags and terms
  80. foreach ( $xml->xpath('/rss/channel/wp:category') as $term_arr ) {
  81. $t = $term_arr->children( $namespaces['wp'] );
  82. $categories[] = array(
  83. 'term_id' => (int) $t->term_id,
  84. 'category_nicename' => (string) $t->category_nicename,
  85. 'category_parent' => (string) $t->category_parent,
  86. 'cat_name' => (string) $t->cat_name,
  87. 'category_description' => (string) $t->category_description
  88. );
  89. }
  90. foreach ( $xml->xpath('/rss/channel/wp:tag') as $term_arr ) {
  91. $t = $term_arr->children( $namespaces['wp'] );
  92. $tags[] = array(
  93. 'term_id' => (int) $t->term_id,
  94. 'tag_slug' => (string) $t->tag_slug,
  95. 'tag_name' => (string) $t->tag_name,
  96. 'tag_description' => (string) $t->tag_description
  97. );
  98. }
  99. foreach ( $xml->xpath('/rss/channel/wp:term') as $term_arr ) {
  100. $t = $term_arr->children( $namespaces['wp'] );
  101. $terms[] = array(
  102. 'term_id' => (int) $t->term_id,
  103. 'term_taxonomy' => (string) $t->term_taxonomy,
  104. 'slug' => (string) $t->term_slug,
  105. 'term_parent' => (string) $t->term_parent,
  106. 'term_name' => (string) $t->term_name,
  107. 'term_description' => (string) $t->term_description
  108. );
  109. }
  110. // grab posts
  111. foreach ( $xml->channel->item as $item ) {
  112. $post = array(
  113. 'post_title' => (string) $item->title,
  114. 'guid' => (string) $item->guid,
  115. );
  116. $dc = $item->children( 'http://purl.org/dc/elements/1.1/' );
  117. $post['post_author'] = (string) $dc->creator;
  118. $content = $item->children( 'http://purl.org/rss/1.0/modules/content/' );
  119. $excerpt = $item->children( $namespaces['excerpt'] );
  120. $post['post_content'] = (string) $content->encoded;
  121. $post['post_excerpt'] = (string) $excerpt->encoded;
  122. $wp = $item->children( $namespaces['wp'] );
  123. $post['post_id'] = (int) $wp->post_id;
  124. $post['post_date'] = (string) $wp->post_date;
  125. $post['post_date_gmt'] = (string) $wp->post_date_gmt;
  126. $post['comment_status'] = (string) $wp->comment_status;
  127. $post['ping_status'] = (string) $wp->ping_status;
  128. $post['post_name'] = (string) $wp->post_name;
  129. $post['status'] = (string) $wp->status;
  130. $post['post_parent'] = (int) $wp->post_parent;
  131. $post['menu_order'] = (int) $wp->menu_order;
  132. $post['post_type'] = (string) $wp->post_type;
  133. $post['post_password'] = (string) $wp->post_password;
  134. $post['is_sticky'] = (int) $wp->is_sticky;
  135. if ( isset($wp->attachment_url) )
  136. $post['attachment_url'] = (string) $wp->attachment_url;
  137. foreach ( $item->category as $c ) {
  138. $att = $c->attributes();
  139. if ( isset( $att['nicename'] ) )
  140. $post['terms'][] = array(
  141. 'name' => (string) $c,
  142. 'slug' => (string) $att['nicename'],
  143. 'domain' => (string) $att['domain']
  144. );
  145. }
  146. foreach ( $wp->postmeta as $meta ) {
  147. $post['postmeta'][] = array(
  148. 'key' => (string) $meta->meta_key,
  149. 'value' => (string) $meta->meta_value
  150. );
  151. }
  152. foreach ( $wp->comment as $comment ) {
  153. $meta = array();
  154. if ( isset( $comment->commentmeta ) ) {
  155. foreach ( $comment->commentmeta as $m ) {
  156. $meta[] = array(
  157. 'key' => (string) $m->meta_key,
  158. 'value' => (string) $m->meta_value
  159. );
  160. }
  161. }
  162. $post['comments'][] = array(
  163. 'comment_id' => (int) $comment->comment_id,
  164. 'comment_author' => (string) $comment->comment_author,
  165. 'comment_author_email' => (string) $comment->comment_author_email,
  166. 'comment_author_IP' => (string) $comment->comment_author_IP,
  167. 'comment_author_url' => (string) $comment->comment_author_url,
  168. 'comment_date' => (string) $comment->comment_date,
  169. 'comment_date_gmt' => (string) $comment->comment_date_gmt,
  170. 'comment_content' => (string) $comment->comment_content,
  171. 'comment_approved' => (string) $comment->comment_approved,
  172. 'comment_type' => (string) $comment->comment_type,
  173. 'comment_parent' => (string) $comment->comment_parent,
  174. 'comment_user_id' => (int) $comment->comment_user_id,
  175. 'commentmeta' => $meta,
  176. );
  177. }
  178. $posts[] = $post;
  179. }
  180. return array(
  181. 'authors' => $authors,
  182. 'posts' => $posts,
  183. 'categories' => $categories,
  184. 'tags' => $tags,
  185. 'terms' => $terms,
  186. 'base_url' => $base_url,
  187. 'version' => $wxr_version
  188. );
  189. }
  190. }
  191. function zip($source, $destination = null) {
  192. if (!extension_loaded('zip') || !file_exists($source)) {
  193. return false;
  194. }
  195. if (empty($destination)) {
  196. $destination = basename($source).'.zip';
  197. }
  198. $zip = new ZipArchive();
  199. if (!$zip->open($destination, ZIPARCHIVE::CREATE)) {
  200. return false;
  201. }
  202. $source = str_replace('\\', '/', realpath($source));
  203. if (is_dir($source) === true) {
  204. $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST);
  205. foreach ($files as $file) {
  206. $file = str_replace('\\', '/', $file);
  207. // Ignore "." and ".." folders
  208. if( in_array(substr($file, strrpos($file, '/')+1), array('.', '..')) ) {
  209. continue;
  210. }
  211. $file = realpath($file);
  212. $file = str_replace("\\","/",$file);
  213. if (is_dir($file) === true) {
  214. $zip->addEmptyDir(str_replace($source . '/', '', $file . '/'));
  215. }
  216. else if (is_file($file) === true) {
  217. $contextFilePath = substr(str_replace($source, '', $file),1);
  218. $zip->addFromString($contextFilePath, file_get_contents($file));
  219. }
  220. }
  221. }
  222. else if (is_file($source) === true) {
  223. $zip->addFromString(basename($source), file_get_contents($source));
  224. }
  225. return $zip->close();
  226. }
  227. function deldir($dirPath) {
  228. if (! is_dir($dirPath)) {
  229. return 0;
  230. }
  231. if (substr($dirPath, strlen($dirPath) - 1, 1) != '/') {
  232. $dirPath .= '/';
  233. }
  234. $files = glob($dirPath . '*', GLOB_MARK);
  235. foreach ($files as $file) {
  236. if (is_dir($file)) {
  237. deldir($file);
  238. } else {
  239. unlink($file);
  240. }
  241. }
  242. rmdir($dirPath);
  243. }
  244. function generate($layout, $name, $title, $author, $date, $content, $comments, $tags = '') {
  245. if($comments == 'open') {
  246. $comments = 'true';
  247. }
  248. else {
  249. $comments = 'false';
  250. }
  251. if($layout == 'post') {
  252. $content = trim(preg_replace('/<!--more-->/', '', $content));
  253. $file = "---\nlayout: post\ntitle: \"{$title}\"\nauthor: \"{$author}\"\ndate: ".date('Y-m-d H:i', $date)."\ncomments: {$comments}\ncategories: {$tags}\n---\n{$content}";
  254. $name = date('Y-m-d', $date).'-'.$name.'.markdown';
  255. if (!file_exists('md/_posts')) {
  256. mkdir('md/_posts');
  257. }
  258. if (!file_exists('md/_posts/'.$name)) {
  259. file_put_contents('md/_posts/'.$name, $file);
  260. }
  261. }
  262. elseif($layout == 'page') {
  263. $file = "---\nlayout: page\ntitle: \"{$title}\"\ndate: ".date('Y-m-d H:i', $date)."\ncomments: {$comments}\nfooter: true\n---\n{$content}";
  264. if (!file_exists('md/'.$name)) {
  265. mkdir('md/'.$name);
  266. }
  267. if (!file_exists('md/'.$name.'/index.markdown')) {
  268. file_put_contents('md/'.$name.'/index.markdown', $file);
  269. }
  270. }
  271. }
  272. move_uploaded_file($_FILES['wxr']['tmp_name'], './wxr.xml');
  273. $xmlparse = new WXR_Parser_SimpleXML();
  274. $xml = $xmlparse->parse('wxr.xml');
  275. unset($xmlparse);
  276. if (!isset($xml) || $xml == false) {
  277. if(file_exists('wxr.xml')) {
  278. unlink('wxr.xml');
  279. }
  280. exit('非法文件!');
  281. }
  282. mkdir('md');
  283. $count = count($xml['posts']);
  284. for($i=0; $i<$count; $i++) {
  285. if(isset($xml['posts'][$i]['terms'])) {
  286. $termscount = count($xml['posts'][$i]['terms']);
  287. $tags = '';
  288. for($j=0; $j<$termscount; $j++) {
  289. if($xml['posts'][$i]['terms'][$j]['domain'] == 'post_tag') {
  290. if($tags!='') {
  291. $tags .=', ';
  292. }
  293. $tags .= $xml['posts'][$i]['terms'][$j]['name'];
  294. }
  295. }
  296. $tags = "[{$tags}]";
  297. }
  298. else {
  299. $tags = '';
  300. }
  301. generate($xml['posts'][$i]['post_type'], $xml['posts'][$i]['post_name'], $xml['posts'][$i]['post_title'], $xml['authors'][$xml['posts'][$i]['post_author']]['author_display_name'], strtotime($xml['posts'][$i]['post_date']), $xml['posts'][$i]['post_content'], $xml['posts'][$i]['comment_status'], $tags);
  302. }
  303. zip('md');
  304. header('Location: md.zip');
  305. if(file_exists('md')) {
  306. deldir('md');
  307. }
  308. if(file_exists('wxr.xml')) {
  309. unlink('wxr.xml');
  310. }
  311. }
  312. ?>