PageRenderTime 49ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/wp-admin/includes/export.php

https://bitbucket.org/julianelve/vendor-wordpress
PHP | 436 lines | 291 code | 46 blank | 99 comment | 51 complexity | 079b8649ca0c0c54ae0b55bfc6a29e9d MD5 | raw file
Possible License(s): AGPL-1.0, LGPL-2.1, GPL-2.0
  1. <?php
  2. /**
  3. * WordPress Export Administration API
  4. *
  5. * @package WordPress
  6. * @subpackage Administration
  7. */
  8. /**
  9. * Version number for the export format.
  10. *
  11. * Bump this when something changes that might affect compatibility.
  12. *
  13. * @since 2.5.0
  14. */
  15. define( 'WXR_VERSION', '1.2' );
  16. /**
  17. * Generates the WXR export file for download
  18. *
  19. * @since 2.1.0
  20. *
  21. * @param array $args Filters defining what should be included in the export
  22. */
  23. function export_wp( $args = array() ) {
  24. global $wpdb, $post;
  25. $defaults = array( 'content' => 'all', 'author' => false, 'category' => false,
  26. 'start_date' => false, 'end_date' => false, 'status' => false,
  27. );
  28. $args = wp_parse_args( $args, $defaults );
  29. do_action( 'export_wp' );
  30. $sitename = sanitize_key( get_bloginfo( 'name' ) );
  31. if ( ! empty($sitename) ) $sitename .= '.';
  32. $filename = $sitename . 'wordpress.' . date( 'Y-m-d' ) . '.xml';
  33. header( 'Content-Description: File Transfer' );
  34. header( 'Content-Disposition: attachment; filename=' . $filename );
  35. header( 'Content-Type: text/xml; charset=' . get_option( 'blog_charset' ), true );
  36. if ( 'all' != $args['content'] && post_type_exists( $args['content'] ) ) {
  37. $ptype = get_post_type_object( $args['content'] );
  38. if ( ! $ptype->can_export )
  39. $args['content'] = 'post';
  40. $where = $wpdb->prepare( "{$wpdb->posts}.post_type = %s", $args['content'] );
  41. } else {
  42. $post_types = get_post_types( array( 'can_export' => true ) );
  43. $esses = array_fill( 0, count($post_types), '%s' );
  44. $where = $wpdb->prepare( "{$wpdb->posts}.post_type IN (" . implode( ',', $esses ) . ')', $post_types );
  45. }
  46. if ( $args['status'] && ( 'post' == $args['content'] || 'page' == $args['content'] ) )
  47. $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_status = %s", $args['status'] );
  48. else
  49. $where .= " AND {$wpdb->posts}.post_status != 'auto-draft'";
  50. $join = '';
  51. if ( $args['category'] && 'post' == $args['content'] ) {
  52. if ( $term = term_exists( $args['category'], 'category' ) ) {
  53. $join = "INNER JOIN {$wpdb->term_relationships} ON ({$wpdb->posts}.ID = {$wpdb->term_relationships}.object_id)";
  54. $where .= $wpdb->prepare( " AND {$wpdb->term_relationships}.term_taxonomy_id = %d", $term['term_taxonomy_id'] );
  55. }
  56. }
  57. if ( 'post' == $args['content'] || 'page' == $args['content'] ) {
  58. if ( $args['author'] )
  59. $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_author = %d", $args['author'] );
  60. if ( $args['start_date'] )
  61. $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_date >= %s", date( 'Y-m-d', strtotime($args['start_date']) ) );
  62. if ( $args['end_date'] )
  63. $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_date < %s", date( 'Y-m-d', strtotime('+1 month', strtotime($args['end_date'])) ) );
  64. }
  65. // grab a snapshot of post IDs, just in case it changes during the export
  66. $post_ids = $wpdb->get_col( "SELECT ID FROM {$wpdb->posts} $join WHERE $where" );
  67. // get the requested terms ready, empty unless posts filtered by category or all content
  68. $cats = $tags = $terms = array();
  69. if ( isset( $term ) && $term ) {
  70. $cat = get_term( $term['term_id'], 'category' );
  71. $cats = array( $cat->term_id => $cat );
  72. unset( $term, $cat );
  73. } else if ( 'all' == $args['content'] ) {
  74. $categories = (array) get_categories( array( 'get' => 'all' ) );
  75. $tags = (array) get_tags( array( 'get' => 'all' ) );
  76. $custom_taxonomies = get_taxonomies( array( '_builtin' => false ) );
  77. $custom_terms = (array) get_terms( $custom_taxonomies, array( 'get' => 'all' ) );
  78. // put categories in order with no child going before its parent
  79. while ( $cat = array_shift( $categories ) ) {
  80. if ( $cat->parent == 0 || isset( $cats[$cat->parent] ) )
  81. $cats[$cat->term_id] = $cat;
  82. else
  83. $categories[] = $cat;
  84. }
  85. // put terms in order with no child going before its parent
  86. while ( $t = array_shift( $custom_terms ) ) {
  87. if ( $t->parent == 0 || isset( $terms[$t->parent] ) )
  88. $terms[$t->term_id] = $t;
  89. else
  90. $custom_terms[] = $t;
  91. }
  92. unset( $categories, $custom_taxonomies, $custom_terms );
  93. }
  94. /**
  95. * Wrap given string in XML CDATA tag.
  96. *
  97. * @since 2.1.0
  98. *
  99. * @param string $str String to wrap in XML CDATA tag.
  100. * @return string
  101. */
  102. function wxr_cdata( $str ) {
  103. if ( seems_utf8( $str ) == false )
  104. $str = utf8_encode( $str );
  105. // $str = ent2ncr(esc_html($str));
  106. $str = '<![CDATA[' . str_replace( ']]>', ']]]]><![CDATA[>', $str ) . ']]>';
  107. return $str;
  108. }
  109. /**
  110. * Return the URL of the site
  111. *
  112. * @since 2.5.0
  113. *
  114. * @return string Site URL.
  115. */
  116. function wxr_site_url() {
  117. // ms: the base url
  118. if ( is_multisite() )
  119. return network_home_url();
  120. // wp: the blog url
  121. else
  122. return get_bloginfo_rss( 'url' );
  123. }
  124. /**
  125. * Output a cat_name XML tag from a given category object
  126. *
  127. * @since 2.1.0
  128. *
  129. * @param object $category Category Object
  130. */
  131. function wxr_cat_name( $category ) {
  132. if ( empty( $category->name ) )
  133. return;
  134. echo '<wp:cat_name>' . wxr_cdata( $category->name ) . '</wp:cat_name>';
  135. }
  136. /**
  137. * Output a category_description XML tag from a given category object
  138. *
  139. * @since 2.1.0
  140. *
  141. * @param object $category Category Object
  142. */
  143. function wxr_category_description( $category ) {
  144. if ( empty( $category->description ) )
  145. return;
  146. echo '<wp:category_description>' . wxr_cdata( $category->description ) . '</wp:category_description>';
  147. }
  148. /**
  149. * Output a tag_name XML tag from a given tag object
  150. *
  151. * @since 2.3.0
  152. *
  153. * @param object $tag Tag Object
  154. */
  155. function wxr_tag_name( $tag ) {
  156. if ( empty( $tag->name ) )
  157. return;
  158. echo '<wp:tag_name>' . wxr_cdata( $tag->name ) . '</wp:tag_name>';
  159. }
  160. /**
  161. * Output a tag_description XML tag from a given tag object
  162. *
  163. * @since 2.3.0
  164. *
  165. * @param object $tag Tag Object
  166. */
  167. function wxr_tag_description( $tag ) {
  168. if ( empty( $tag->description ) )
  169. return;
  170. echo '<wp:tag_description>' . wxr_cdata( $tag->description ) . '</wp:tag_description>';
  171. }
  172. /**
  173. * Output a term_name XML tag from a given term object
  174. *
  175. * @since 2.9.0
  176. *
  177. * @param object $term Term Object
  178. */
  179. function wxr_term_name( $term ) {
  180. if ( empty( $term->name ) )
  181. return;
  182. echo '<wp:term_name>' . wxr_cdata( $term->name ) . '</wp:term_name>';
  183. }
  184. /**
  185. * Output a term_description XML tag from a given term object
  186. *
  187. * @since 2.9.0
  188. *
  189. * @param object $term Term Object
  190. */
  191. function wxr_term_description( $term ) {
  192. if ( empty( $term->description ) )
  193. return;
  194. echo '<wp:term_description>' . wxr_cdata( $term->description ) . '</wp:term_description>';
  195. }
  196. /**
  197. * Output list of authors with posts
  198. *
  199. * @since 3.1.0
  200. */
  201. function wxr_authors_list() {
  202. global $wpdb;
  203. $authors = array();
  204. $results = $wpdb->get_results( "SELECT DISTINCT post_author FROM $wpdb->posts WHERE post_status != 'auto-draft'" );
  205. foreach ( (array) $results as $result )
  206. $authors[] = get_userdata( $result->post_author );
  207. $authors = array_filter( $authors );
  208. foreach ( $authors as $author ) {
  209. echo "\t<wp:author>";
  210. echo '<wp:author_id>' . $author->ID . '</wp:author_id>';
  211. echo '<wp:author_login>' . $author->user_login . '</wp:author_login>';
  212. echo '<wp:author_email>' . $author->user_email . '</wp:author_email>';
  213. echo '<wp:author_display_name>' . wxr_cdata( $author->display_name ) . '</wp:author_display_name>';
  214. echo '<wp:author_first_name>' . wxr_cdata( $author->user_firstname ) . '</wp:author_first_name>';
  215. echo '<wp:author_last_name>' . wxr_cdata( $author->user_lastname ) . '</wp:author_last_name>';
  216. echo "</wp:author>\n";
  217. }
  218. }
  219. /**
  220. * Ouput all navigation menu terms
  221. *
  222. * @since 3.1.0
  223. */
  224. function wxr_nav_menu_terms() {
  225. $nav_menus = wp_get_nav_menus();
  226. if ( empty( $nav_menus ) || ! is_array( $nav_menus ) )
  227. return;
  228. foreach ( $nav_menus as $menu ) {
  229. echo "\t<wp:term><wp:term_id>{$menu->term_id}</wp:term_id><wp:term_taxonomy>nav_menu</wp:term_taxonomy><wp:term_slug>{$menu->slug}</wp:term_slug>";
  230. wxr_term_name( $menu );
  231. echo "</wp:term>\n";
  232. }
  233. }
  234. /**
  235. * Output list of taxonomy terms, in XML tag format, associated with a post
  236. *
  237. * @since 2.3.0
  238. */
  239. function wxr_post_taxonomy() {
  240. $post = get_post();
  241. $taxonomies = get_object_taxonomies( $post->post_type );
  242. if ( empty( $taxonomies ) )
  243. return;
  244. $terms = wp_get_object_terms( $post->ID, $taxonomies );
  245. foreach ( (array) $terms as $term ) {
  246. echo "\t\t<category domain=\"{$term->taxonomy}\" nicename=\"{$term->slug}\">" . wxr_cdata( $term->name ) . "</category>\n";
  247. }
  248. }
  249. function wxr_filter_postmeta( $return_me, $meta_key ) {
  250. if ( '_edit_lock' == $meta_key )
  251. $return_me = true;
  252. return $return_me;
  253. }
  254. add_filter( 'wxr_export_skip_postmeta', 'wxr_filter_postmeta', 10, 2 );
  255. echo '<?xml version="1.0" encoding="' . get_bloginfo('charset') . "\" ?>\n";
  256. ?>
  257. <!-- This is a WordPress eXtended RSS file generated by WordPress as an export of your site. -->
  258. <!-- It contains information about your site's posts, pages, comments, categories, and other content. -->
  259. <!-- You may use this file to transfer that content from one site to another. -->
  260. <!-- This file is not intended to serve as a complete backup of your site. -->
  261. <!-- To import this information into a WordPress site follow these steps: -->
  262. <!-- 1. Log in to that site as an administrator. -->
  263. <!-- 2. Go to Tools: Import in the WordPress admin panel. -->
  264. <!-- 3. Install the "WordPress" importer from the list. -->
  265. <!-- 4. Activate & Run Importer. -->
  266. <!-- 5. Upload this file using the form provided on that page. -->
  267. <!-- 6. You will first be asked to map the authors in this export file to users -->
  268. <!-- on the site. For each author, you may choose to map to an -->
  269. <!-- existing user on the site or to create a new user. -->
  270. <!-- 7. WordPress will then import each of the posts, pages, comments, categories, etc. -->
  271. <!-- contained in this file into your site. -->
  272. <?php the_generator( 'export' ); ?>
  273. <rss version="2.0"
  274. xmlns:excerpt="http://wordpress.org/export/<?php echo WXR_VERSION; ?>/excerpt/"
  275. xmlns:content="http://purl.org/rss/1.0/modules/content/"
  276. xmlns:wfw="http://wellformedweb.org/CommentAPI/"
  277. xmlns:dc="http://purl.org/dc/elements/1.1/"
  278. xmlns:wp="http://wordpress.org/export/<?php echo WXR_VERSION; ?>/"
  279. >
  280. <channel>
  281. <title><?php bloginfo_rss( 'name' ); ?></title>
  282. <link><?php bloginfo_rss( 'url' ); ?></link>
  283. <description><?php bloginfo_rss( 'description' ); ?></description>
  284. <pubDate><?php echo date( 'D, d M Y H:i:s +0000' ); ?></pubDate>
  285. <language><?php bloginfo_rss( 'language' ); ?></language>
  286. <wp:wxr_version><?php echo WXR_VERSION; ?></wp:wxr_version>
  287. <wp:base_site_url><?php echo wxr_site_url(); ?></wp:base_site_url>
  288. <wp:base_blog_url><?php bloginfo_rss( 'url' ); ?></wp:base_blog_url>
  289. <?php wxr_authors_list(); ?>
  290. <?php foreach ( $cats as $c ) : ?>
  291. <wp:category><wp:term_id><?php echo $c->term_id ?></wp:term_id><wp:category_nicename><?php echo $c->slug; ?></wp:category_nicename><wp:category_parent><?php echo $c->parent ? $cats[$c->parent]->slug : ''; ?></wp:category_parent><?php wxr_cat_name( $c ); ?><?php wxr_category_description( $c ); ?></wp:category>
  292. <?php endforeach; ?>
  293. <?php foreach ( $tags as $t ) : ?>
  294. <wp:tag><wp:term_id><?php echo $t->term_id ?></wp:term_id><wp:tag_slug><?php echo $t->slug; ?></wp:tag_slug><?php wxr_tag_name( $t ); ?><?php wxr_tag_description( $t ); ?></wp:tag>
  295. <?php endforeach; ?>
  296. <?php foreach ( $terms as $t ) : ?>
  297. <wp:term><wp:term_id><?php echo $t->term_id ?></wp:term_id><wp:term_taxonomy><?php echo $t->taxonomy; ?></wp:term_taxonomy><wp:term_slug><?php echo $t->slug; ?></wp:term_slug><wp:term_parent><?php echo $t->parent ? $terms[$t->parent]->slug : ''; ?></wp:term_parent><?php wxr_term_name( $t ); ?><?php wxr_term_description( $t ); ?></wp:term>
  298. <?php endforeach; ?>
  299. <?php if ( 'all' == $args['content'] ) wxr_nav_menu_terms(); ?>
  300. <?php do_action( 'rss2_head' ); ?>
  301. <?php if ( $post_ids ) {
  302. global $wp_query;
  303. $wp_query->in_the_loop = true; // Fake being in the loop.
  304. // fetch 20 posts at a time rather than loading the entire table into memory
  305. while ( $next_posts = array_splice( $post_ids, 0, 20 ) ) {
  306. $where = 'WHERE ID IN (' . join( ',', $next_posts ) . ')';
  307. $posts = $wpdb->get_results( "SELECT * FROM {$wpdb->posts} $where" );
  308. // Begin Loop
  309. foreach ( $posts as $post ) {
  310. setup_postdata( $post );
  311. $is_sticky = is_sticky( $post->ID ) ? 1 : 0;
  312. ?>
  313. <item>
  314. <title><?php echo apply_filters( 'the_title_rss', $post->post_title ); ?></title>
  315. <link><?php the_permalink_rss() ?></link>
  316. <pubDate><?php echo mysql2date( 'D, d M Y H:i:s +0000', get_post_time( 'Y-m-d H:i:s', true ), false ); ?></pubDate>
  317. <dc:creator><?php echo get_the_author_meta( 'login' ); ?></dc:creator>
  318. <guid isPermaLink="false"><?php esc_url( the_guid() ); ?></guid>
  319. <description></description>
  320. <content:encoded><?php echo wxr_cdata( apply_filters( 'the_content_export', $post->post_content ) ); ?></content:encoded>
  321. <excerpt:encoded><?php echo wxr_cdata( apply_filters( 'the_excerpt_export', $post->post_excerpt ) ); ?></excerpt:encoded>
  322. <wp:post_id><?php echo $post->ID; ?></wp:post_id>
  323. <wp:post_date><?php echo $post->post_date; ?></wp:post_date>
  324. <wp:post_date_gmt><?php echo $post->post_date_gmt; ?></wp:post_date_gmt>
  325. <wp:comment_status><?php echo $post->comment_status; ?></wp:comment_status>
  326. <wp:ping_status><?php echo $post->ping_status; ?></wp:ping_status>
  327. <wp:post_name><?php echo $post->post_name; ?></wp:post_name>
  328. <wp:status><?php echo $post->post_status; ?></wp:status>
  329. <wp:post_parent><?php echo $post->post_parent; ?></wp:post_parent>
  330. <wp:menu_order><?php echo $post->menu_order; ?></wp:menu_order>
  331. <wp:post_type><?php echo $post->post_type; ?></wp:post_type>
  332. <wp:post_password><?php echo $post->post_password; ?></wp:post_password>
  333. <wp:is_sticky><?php echo $is_sticky; ?></wp:is_sticky>
  334. <?php if ( $post->post_type == 'attachment' ) : ?>
  335. <wp:attachment_url><?php echo wp_get_attachment_url( $post->ID ); ?></wp:attachment_url>
  336. <?php endif; ?>
  337. <?php wxr_post_taxonomy(); ?>
  338. <?php $postmeta = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->postmeta WHERE post_id = %d", $post->ID ) );
  339. foreach ( $postmeta as $meta ) :
  340. if ( apply_filters( 'wxr_export_skip_postmeta', false, $meta->meta_key, $meta ) )
  341. continue;
  342. ?>
  343. <wp:postmeta>
  344. <wp:meta_key><?php echo $meta->meta_key; ?></wp:meta_key>
  345. <wp:meta_value><?php echo wxr_cdata( $meta->meta_value ); ?></wp:meta_value>
  346. </wp:postmeta>
  347. <?php endforeach; ?>
  348. <?php $comments = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->comments WHERE comment_post_ID = %d AND comment_approved <> 'spam'", $post->ID ) );
  349. foreach ( $comments as $c ) : ?>
  350. <wp:comment>
  351. <wp:comment_id><?php echo $c->comment_ID; ?></wp:comment_id>
  352. <wp:comment_author><?php echo wxr_cdata( $c->comment_author ); ?></wp:comment_author>
  353. <wp:comment_author_email><?php echo $c->comment_author_email; ?></wp:comment_author_email>
  354. <wp:comment_author_url><?php echo esc_url_raw( $c->comment_author_url ); ?></wp:comment_author_url>
  355. <wp:comment_author_IP><?php echo $c->comment_author_IP; ?></wp:comment_author_IP>
  356. <wp:comment_date><?php echo $c->comment_date; ?></wp:comment_date>
  357. <wp:comment_date_gmt><?php echo $c->comment_date_gmt; ?></wp:comment_date_gmt>
  358. <wp:comment_content><?php echo wxr_cdata( $c->comment_content ) ?></wp:comment_content>
  359. <wp:comment_approved><?php echo $c->comment_approved; ?></wp:comment_approved>
  360. <wp:comment_type><?php echo $c->comment_type; ?></wp:comment_type>
  361. <wp:comment_parent><?php echo $c->comment_parent; ?></wp:comment_parent>
  362. <wp:comment_user_id><?php echo $c->user_id; ?></wp:comment_user_id>
  363. <?php $c_meta = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->commentmeta WHERE comment_id = %d", $c->comment_ID ) );
  364. foreach ( $c_meta as $meta ) : ?>
  365. <wp:commentmeta>
  366. <wp:meta_key><?php echo $meta->meta_key; ?></wp:meta_key>
  367. <wp:meta_value><?php echo wxr_cdata( $meta->meta_value ); ?></wp:meta_value>
  368. </wp:commentmeta>
  369. <?php endforeach; ?>
  370. </wp:comment>
  371. <?php endforeach; ?>
  372. </item>
  373. <?php
  374. }
  375. }
  376. } ?>
  377. </channel>
  378. </rss>
  379. <?php
  380. }