wp/wp-admin/includes/export.php
changeset 21 48c4eec2b7e6
parent 18 be944660c56a
equal deleted inserted replaced
20:7b1b88e27a20 21:48c4eec2b7e6
    29  * @global WP_Post $post Global post object.
    29  * @global WP_Post $post Global post object.
    30  *
    30  *
    31  * @param array $args {
    31  * @param array $args {
    32  *     Optional. Arguments for generating the WXR export file for download. Default empty array.
    32  *     Optional. Arguments for generating the WXR export file for download. Default empty array.
    33  *
    33  *
    34  *     @type string $content        Type of content to export. If set, only the post content of this post type
    34  *     @type string $content    Type of content to export. If set, only the post content of this post type
    35  *                                  will be exported. Accepts 'all', 'post', 'page', 'attachment', or a defined
    35  *                              will be exported. Accepts 'all', 'post', 'page', 'attachment', or a defined
    36  *                                  custom post. If an invalid custom post type is supplied, every post type for
    36  *                              custom post. If an invalid custom post type is supplied, every post type for
    37  *                                  which `can_export` is enabled will be exported instead. If a valid custom post
    37  *                              which `can_export` is enabled will be exported instead. If a valid custom post
    38  *                                  type is supplied but `can_export` is disabled, then 'posts' will be exported
    38  *                              type is supplied but `can_export` is disabled, then 'posts' will be exported
    39  *                                  instead. When 'all' is supplied, only post types with `can_export` enabled will
    39  *                              instead. When 'all' is supplied, only post types with `can_export` enabled will
    40  *                                  be exported. Default 'all'.
    40  *                              be exported. Default 'all'.
    41  *     @type string $author         Author to export content for. Only used when `$content` is 'post', 'page', or
    41  *     @type string $author     Author to export content for. Only used when `$content` is 'post', 'page', or
    42  *                                  'attachment'. Accepts false (all) or a specific author ID. Default false (all).
    42  *                              'attachment'. Accepts false (all) or a specific author ID. Default false (all).
    43  *     @type string $category       Category (slug) to export content for. Used only when `$content` is 'post'. If
    43  *     @type string $category   Category (slug) to export content for. Used only when `$content` is 'post'. If
    44  *                                  set, only post content assigned to `$category` will be exported. Accepts false
    44  *                              set, only post content assigned to `$category` will be exported. Accepts false
    45  *                                  or a specific category slug. Default is false (all categories).
    45  *                              or a specific category slug. Default is false (all categories).
    46  *     @type string $start_date     Start date to export content from. Expected date format is 'Y-m-d'. Used only
    46  *     @type string $start_date Start date to export content from. Expected date format is 'Y-m-d'. Used only
    47  *                                  when `$content` is 'post', 'page' or 'attachment'. Default false (since the
    47  *                              when `$content` is 'post', 'page' or 'attachment'. Default false (since the
    48  *                                  beginning of time).
    48  *                              beginning of time).
    49  *     @type string $end_date       End date to export content to. Expected date format is 'Y-m-d'. Used only when
    49  *     @type string $end_date   End date to export content to. Expected date format is 'Y-m-d'. Used only when
    50  *                                  `$content` is 'post', 'page' or 'attachment'. Default false (latest publish date).
    50  *                              `$content` is 'post', 'page' or 'attachment'. Default false (latest publish date).
    51  *     @type string $status         Post status to export posts for. Used only when `$content` is 'post' or 'page'.
    51  *     @type string $status     Post status to export posts for. Used only when `$content` is 'post' or 'page'.
    52  *                                  Accepts false (all statuses except 'auto-draft'), or a specific status, i.e.
    52  *                              Accepts false (all statuses except 'auto-draft'), or a specific status, i.e.
    53  *                                  'publish', 'pending', 'draft', 'auto-draft', 'future', 'private', 'inherit', or
    53  *                              'publish', 'pending', 'draft', 'auto-draft', 'future', 'private', 'inherit', or
    54  *                                  'trash'. Default false (all statuses except 'auto-draft').
    54  *                              'trash'. Default false (all statuses except 'auto-draft').
    55  * }
    55  * }
    56  */
    56  */
    57 function export_wp( $args = array() ) {
    57 function export_wp( $args = array() ) {
    58 	global $wpdb, $post;
    58 	global $wpdb, $post;
    59 
    59 
   141 		}
   141 		}
   142 	}
   142 	}
   143 
   143 
   144 	// Grab a snapshot of post IDs, just in case it changes during the export.
   144 	// Grab a snapshot of post IDs, just in case it changes during the export.
   145 	$post_ids = $wpdb->get_col( "SELECT ID FROM {$wpdb->posts} $join WHERE $where" );
   145 	$post_ids = $wpdb->get_col( "SELECT ID FROM {$wpdb->posts} $join WHERE $where" );
       
   146 
       
   147 	// Get IDs for the attachments of each post, unless all content is already being exported.
       
   148 	if ( ! in_array( $args['content'], array( 'all', 'attachment' ), true ) ) {
       
   149 		// Array to hold all additional IDs (attachments and thumbnails).
       
   150 		$additional_ids = array();
       
   151 
       
   152 		// Create a copy of the post IDs array to avoid modifying the original array.
       
   153 		$processing_ids = $post_ids;
       
   154 
       
   155 		while ( $next_posts = array_splice( $processing_ids, 0, 20 ) ) {
       
   156 			$posts_in     = array_map( 'absint', $next_posts );
       
   157 			$placeholders = array_fill( 0, count( $posts_in ), '%d' );
       
   158 
       
   159 			// Create a string for the placeholders.
       
   160 			$in_placeholder = implode( ',', $placeholders );
       
   161 
       
   162 			// Prepare the SQL statement for attachment ids.
       
   163 			$attachment_ids = $wpdb->get_col(
       
   164 				$wpdb->prepare(
       
   165 					"
       
   166 				SELECT ID
       
   167 				FROM $wpdb->posts
       
   168 				WHERE post_parent IN ($in_placeholder) AND post_type = 'attachment'
       
   169 					",
       
   170 					$posts_in
       
   171 				)
       
   172 			);
       
   173 
       
   174 			$thumbnails_ids = $wpdb->get_col(
       
   175 				$wpdb->prepare(
       
   176 					"
       
   177 				SELECT meta_value
       
   178 				FROM $wpdb->postmeta
       
   179 				WHERE $wpdb->postmeta.post_id IN ($in_placeholder)
       
   180 				AND $wpdb->postmeta.meta_key = '_thumbnail_id'
       
   181 					",
       
   182 					$posts_in
       
   183 				)
       
   184 			);
       
   185 
       
   186 			$additional_ids = array_merge( $additional_ids, $attachment_ids, $thumbnails_ids );
       
   187 		}
       
   188 
       
   189 		// Merge the additional IDs back with the original post IDs after processing all posts
       
   190 		$post_ids = array_unique( array_merge( $post_ids, $additional_ids ) );
       
   191 	}
   146 
   192 
   147 	/*
   193 	/*
   148 	 * Get the requested terms ready, empty unless posts filtered by category
   194 	 * Get the requested terms ready, empty unless posts filtered by category
   149 	 * or all content.
   195 	 * or all content.
   150 	 */
   196 	 */
   187 
   233 
   188 		unset( $categories, $custom_taxonomies, $custom_terms );
   234 		unset( $categories, $custom_taxonomies, $custom_terms );
   189 	}
   235 	}
   190 
   236 
   191 	/**
   237 	/**
   192 	 * Wrap given string in XML CDATA tag.
   238 	 * Wraps given string in XML CDATA tag.
   193 	 *
   239 	 *
   194 	 * @since 2.1.0
   240 	 * @since 2.1.0
   195 	 *
   241 	 *
   196 	 * @param string $str String to wrap in XML CDATA tag.
   242 	 * @param string $str String to wrap in XML CDATA tag.
   197 	 * @return string
   243 	 * @return string
   205 
   251 
   206 		return $str;
   252 		return $str;
   207 	}
   253 	}
   208 
   254 
   209 	/**
   255 	/**
   210 	 * Return the URL of the site
   256 	 * Returns the URL of the site.
   211 	 *
   257 	 *
   212 	 * @since 2.5.0
   258 	 * @since 2.5.0
   213 	 *
   259 	 *
   214 	 * @return string Site URL.
   260 	 * @return string Site URL.
   215 	 */
   261 	 */
   216 	function wxr_site_url() {
   262 	function wxr_site_url() {
   217 		if ( is_multisite() ) {
   263 		if ( is_multisite() ) {
   218 			// Multisite: the base URL.
   264 			// Multisite: the base URL.
   219 			return network_home_url();
   265 			return network_home_url();
   220 		} else {
   266 		} else {
   221 			// WordPress (single site): the blog URL.
   267 			// WordPress (single site): the site URL.
   222 			return get_bloginfo_rss( 'url' );
   268 			return get_bloginfo_rss( 'url' );
   223 		}
   269 		}
   224 	}
   270 	}
   225 
   271 
   226 	/**
   272 	/**
   227 	 * Output a cat_name XML tag from a given category object
   273 	 * Outputs a cat_name XML tag from a given category object.
   228 	 *
   274 	 *
   229 	 * @since 2.1.0
   275 	 * @since 2.1.0
   230 	 *
   276 	 *
   231 	 * @param WP_Term $category Category Object
   277 	 * @param WP_Term $category Category Object.
   232 	 */
   278 	 */
   233 	function wxr_cat_name( $category ) {
   279 	function wxr_cat_name( $category ) {
   234 		if ( empty( $category->name ) ) {
   280 		if ( empty( $category->name ) ) {
   235 			return;
   281 			return;
   236 		}
   282 		}
   237 
   283 
   238 		echo '<wp:cat_name>' . wxr_cdata( $category->name ) . "</wp:cat_name>\n";
   284 		echo '<wp:cat_name>' . wxr_cdata( $category->name ) . "</wp:cat_name>\n";
   239 	}
   285 	}
   240 
   286 
   241 	/**
   287 	/**
   242 	 * Output a category_description XML tag from a given category object
   288 	 * Outputs a category_description XML tag from a given category object.
   243 	 *
   289 	 *
   244 	 * @since 2.1.0
   290 	 * @since 2.1.0
   245 	 *
   291 	 *
   246 	 * @param WP_Term $category Category Object
   292 	 * @param WP_Term $category Category Object.
   247 	 */
   293 	 */
   248 	function wxr_category_description( $category ) {
   294 	function wxr_category_description( $category ) {
   249 		if ( empty( $category->description ) ) {
   295 		if ( empty( $category->description ) ) {
   250 			return;
   296 			return;
   251 		}
   297 		}
   252 
   298 
   253 		echo '<wp:category_description>' . wxr_cdata( $category->description ) . "</wp:category_description>\n";
   299 		echo '<wp:category_description>' . wxr_cdata( $category->description ) . "</wp:category_description>\n";
   254 	}
   300 	}
   255 
   301 
   256 	/**
   302 	/**
   257 	 * Output a tag_name XML tag from a given tag object
   303 	 * Outputs a tag_name XML tag from a given tag object.
   258 	 *
   304 	 *
   259 	 * @since 2.3.0
   305 	 * @since 2.3.0
   260 	 *
   306 	 *
   261 	 * @param WP_Term $tag Tag Object
   307 	 * @param WP_Term $tag Tag Object.
   262 	 */
   308 	 */
   263 	function wxr_tag_name( $tag ) {
   309 	function wxr_tag_name( $tag ) {
   264 		if ( empty( $tag->name ) ) {
   310 		if ( empty( $tag->name ) ) {
   265 			return;
   311 			return;
   266 		}
   312 		}
   267 
   313 
   268 		echo '<wp:tag_name>' . wxr_cdata( $tag->name ) . "</wp:tag_name>\n";
   314 		echo '<wp:tag_name>' . wxr_cdata( $tag->name ) . "</wp:tag_name>\n";
   269 	}
   315 	}
   270 
   316 
   271 	/**
   317 	/**
   272 	 * Output a tag_description XML tag from a given tag object
   318 	 * Outputs a tag_description XML tag from a given tag object.
   273 	 *
   319 	 *
   274 	 * @since 2.3.0
   320 	 * @since 2.3.0
   275 	 *
   321 	 *
   276 	 * @param WP_Term $tag Tag Object
   322 	 * @param WP_Term $tag Tag Object.
   277 	 */
   323 	 */
   278 	function wxr_tag_description( $tag ) {
   324 	function wxr_tag_description( $tag ) {
   279 		if ( empty( $tag->description ) ) {
   325 		if ( empty( $tag->description ) ) {
   280 			return;
   326 			return;
   281 		}
   327 		}
   282 
   328 
   283 		echo '<wp:tag_description>' . wxr_cdata( $tag->description ) . "</wp:tag_description>\n";
   329 		echo '<wp:tag_description>' . wxr_cdata( $tag->description ) . "</wp:tag_description>\n";
   284 	}
   330 	}
   285 
   331 
   286 	/**
   332 	/**
   287 	 * Output a term_name XML tag from a given term object
   333 	 * Outputs a term_name XML tag from a given term object.
   288 	 *
   334 	 *
   289 	 * @since 2.9.0
   335 	 * @since 2.9.0
   290 	 *
   336 	 *
   291 	 * @param WP_Term $term Term Object
   337 	 * @param WP_Term $term Term Object.
   292 	 */
   338 	 */
   293 	function wxr_term_name( $term ) {
   339 	function wxr_term_name( $term ) {
   294 		if ( empty( $term->name ) ) {
   340 		if ( empty( $term->name ) ) {
   295 			return;
   341 			return;
   296 		}
   342 		}
   297 
   343 
   298 		echo '<wp:term_name>' . wxr_cdata( $term->name ) . "</wp:term_name>\n";
   344 		echo '<wp:term_name>' . wxr_cdata( $term->name ) . "</wp:term_name>\n";
   299 	}
   345 	}
   300 
   346 
   301 	/**
   347 	/**
   302 	 * Output a term_description XML tag from a given term object
   348 	 * Outputs a term_description XML tag from a given term object.
   303 	 *
   349 	 *
   304 	 * @since 2.9.0
   350 	 * @since 2.9.0
   305 	 *
   351 	 *
   306 	 * @param WP_Term $term Term Object
   352 	 * @param WP_Term $term Term Object.
   307 	 */
   353 	 */
   308 	function wxr_term_description( $term ) {
   354 	function wxr_term_description( $term ) {
   309 		if ( empty( $term->description ) ) {
   355 		if ( empty( $term->description ) ) {
   310 			return;
   356 			return;
   311 		}
   357 		}
   312 
   358 
   313 		echo "\t\t<wp:term_description>" . wxr_cdata( $term->description ) . "</wp:term_description>\n";
   359 		echo "\t\t<wp:term_description>" . wxr_cdata( $term->description ) . "</wp:term_description>\n";
   314 	}
   360 	}
   315 
   361 
   316 	/**
   362 	/**
   317 	 * Output term meta XML tags for a given term object.
   363 	 * Outputs term meta XML tags for a given term object.
   318 	 *
   364 	 *
   319 	 * @since 4.6.0
   365 	 * @since 4.6.0
       
   366 	 *
       
   367 	 * @global wpdb $wpdb WordPress database abstraction object.
   320 	 *
   368 	 *
   321 	 * @param WP_Term $term Term object.
   369 	 * @param WP_Term $term Term object.
   322 	 */
   370 	 */
   323 	function wxr_term_meta( $term ) {
   371 	function wxr_term_meta( $term ) {
   324 		global $wpdb;
   372 		global $wpdb;
   343 			}
   391 			}
   344 		}
   392 		}
   345 	}
   393 	}
   346 
   394 
   347 	/**
   395 	/**
   348 	 * Output list of authors with posts
   396 	 * Outputs list of authors with posts.
   349 	 *
   397 	 *
   350 	 * @since 3.1.0
   398 	 * @since 3.1.0
   351 	 *
   399 	 *
   352 	 * @global wpdb $wpdb WordPress database abstraction object.
   400 	 * @global wpdb $wpdb WordPress database abstraction object.
   353 	 *
   401 	 *
   354 	 * @param int[] $post_ids Optional. Array of post IDs to filter the query by.
   402 	 * @param int[] $post_ids Optional. Array of post IDs to filter the query by.
   355 	 */
   403 	 */
   356 	function wxr_authors_list( array $post_ids = null ) {
   404 	function wxr_authors_list( ?array $post_ids = null ) {
   357 		global $wpdb;
   405 		global $wpdb;
   358 
   406 
   359 		if ( ! empty( $post_ids ) ) {
   407 		if ( ! empty( $post_ids ) ) {
   360 			$post_ids = array_map( 'absint', $post_ids );
   408 			$post_ids = array_map( 'absint', $post_ids );
   361 			$and      = 'AND ID IN ( ' . implode( ', ', $post_ids ) . ')';
   409 			$and      = 'AND ID IN ( ' . implode( ', ', $post_ids ) . ')';
   382 			echo "</wp:author>\n";
   430 			echo "</wp:author>\n";
   383 		}
   431 		}
   384 	}
   432 	}
   385 
   433 
   386 	/**
   434 	/**
   387 	 * Output all navigation menu terms
   435 	 * Outputs all navigation menu terms.
   388 	 *
   436 	 *
   389 	 * @since 3.1.0
   437 	 * @since 3.1.0
   390 	 */
   438 	 */
   391 	function wxr_nav_menu_terms() {
   439 	function wxr_nav_menu_terms() {
   392 		$nav_menus = wp_get_nav_menus();
   440 		$nav_menus = wp_get_nav_menus();
   403 			echo "</wp:term>\n";
   451 			echo "</wp:term>\n";
   404 		}
   452 		}
   405 	}
   453 	}
   406 
   454 
   407 	/**
   455 	/**
   408 	 * Output list of taxonomy terms, in XML tag format, associated with a post
   456 	 * Outputs list of taxonomy terms, in XML tag format, associated with a post.
   409 	 *
   457 	 *
   410 	 * @since 2.3.0
   458 	 * @since 2.3.0
   411 	 */
   459 	 */
   412 	function wxr_post_taxonomy() {
   460 	function wxr_post_taxonomy() {
   413 		$post = get_post();
   461 		$post = get_post();
   422 			echo "\t\t<category domain=\"{$term->taxonomy}\" nicename=\"{$term->slug}\">" . wxr_cdata( $term->name ) . "</category>\n";
   470 			echo "\t\t<category domain=\"{$term->taxonomy}\" nicename=\"{$term->slug}\">" . wxr_cdata( $term->name ) . "</category>\n";
   423 		}
   471 		}
   424 	}
   472 	}
   425 
   473 
   426 	/**
   474 	/**
   427 	 * @param bool   $return_me
   475 	 * Determines whether to selectively skip post meta used for WXR exports.
   428 	 * @param string $meta_key
   476 	 *
       
   477 	 * @since 3.3.0
       
   478 	 *
       
   479 	 * @param bool   $return_me Whether to skip the current post meta. Default false.
       
   480 	 * @param string $meta_key  Meta key.
   429 	 * @return bool
   481 	 * @return bool
   430 	 */
   482 	 */
   431 	function wxr_filter_postmeta( $return_me, $meta_key ) {
   483 	function wxr_filter_postmeta( $return_me, $meta_key ) {
   432 		if ( '_edit_lock' === $meta_key ) {
   484 		if ( '_edit_lock' === $meta_key ) {
   433 			$return_me = true;
   485 			$return_me = true;
   513 		?>
   565 		?>
   514 	</wp:term>
   566 	</wp:term>
   515 	<?php endforeach; ?>
   567 	<?php endforeach; ?>
   516 	<?php
   568 	<?php
   517 	if ( 'all' === $args['content'] ) {
   569 	if ( 'all' === $args['content'] ) {
   518 		wxr_nav_menu_terms();}
   570 		wxr_nav_menu_terms();
       
   571 	}
   519 	?>
   572 	?>
   520 
   573 
   521 	<?php
   574 	<?php
   522 	/** This action is documented in wp-includes/feed-rss2.php */
   575 	/** This action is documented in wp-includes/feed-rss2.php */
   523 	do_action( 'rss2_head' );
   576 	do_action( 'rss2_head' );
   630 					?>
   683 					?>
   631 		<wp:comment>
   684 		<wp:comment>
   632 			<wp:comment_id><?php echo (int) $c->comment_ID; ?></wp:comment_id>
   685 			<wp:comment_id><?php echo (int) $c->comment_ID; ?></wp:comment_id>
   633 			<wp:comment_author><?php echo wxr_cdata( $c->comment_author ); ?></wp:comment_author>
   686 			<wp:comment_author><?php echo wxr_cdata( $c->comment_author ); ?></wp:comment_author>
   634 			<wp:comment_author_email><?php echo wxr_cdata( $c->comment_author_email ); ?></wp:comment_author_email>
   687 			<wp:comment_author_email><?php echo wxr_cdata( $c->comment_author_email ); ?></wp:comment_author_email>
   635 			<wp:comment_author_url><?php echo esc_url_raw( $c->comment_author_url ); ?></wp:comment_author_url>
   688 			<wp:comment_author_url><?php echo sanitize_url( $c->comment_author_url ); ?></wp:comment_author_url>
   636 			<wp:comment_author_IP><?php echo wxr_cdata( $c->comment_author_IP ); ?></wp:comment_author_IP>
   689 			<wp:comment_author_IP><?php echo wxr_cdata( $c->comment_author_IP ); ?></wp:comment_author_IP>
   637 			<wp:comment_date><?php echo wxr_cdata( $c->comment_date ); ?></wp:comment_date>
   690 			<wp:comment_date><?php echo wxr_cdata( $c->comment_date ); ?></wp:comment_date>
   638 			<wp:comment_date_gmt><?php echo wxr_cdata( $c->comment_date_gmt ); ?></wp:comment_date_gmt>
   691 			<wp:comment_date_gmt><?php echo wxr_cdata( $c->comment_date_gmt ); ?></wp:comment_date_gmt>
   639 			<wp:comment_content><?php echo wxr_cdata( $c->comment_content ); ?></wp:comment_content>
   692 			<wp:comment_content><?php echo wxr_cdata( $c->comment_content ); ?></wp:comment_content>
   640 			<wp:comment_approved><?php echo wxr_cdata( $c->comment_approved ); ?></wp:comment_approved>
   693 			<wp:comment_approved><?php echo wxr_cdata( $c->comment_approved ); ?></wp:comment_approved>