--- a/wp/wp-admin/includes/export.php Thu Sep 29 08:06:27 2022 +0200
+++ b/wp/wp-admin/includes/export.php Fri Sep 05 18:40:08 2025 +0200
@@ -31,27 +31,27 @@
* @param array $args {
* Optional. Arguments for generating the WXR export file for download. Default empty array.
*
- * @type string $content Type of content to export. If set, only the post content of this post type
- * will be exported. Accepts 'all', 'post', 'page', 'attachment', or a defined
- * custom post. If an invalid custom post type is supplied, every post type for
- * which `can_export` is enabled will be exported instead. If a valid custom post
- * type is supplied but `can_export` is disabled, then 'posts' will be exported
- * instead. When 'all' is supplied, only post types with `can_export` enabled will
- * be exported. Default 'all'.
- * @type string $author Author to export content for. Only used when `$content` is 'post', 'page', or
- * 'attachment'. Accepts false (all) or a specific author ID. Default false (all).
- * @type string $category Category (slug) to export content for. Used only when `$content` is 'post'. If
- * set, only post content assigned to `$category` will be exported. Accepts false
- * or a specific category slug. Default is false (all categories).
- * @type string $start_date Start date to export content from. Expected date format is 'Y-m-d'. Used only
- * when `$content` is 'post', 'page' or 'attachment'. Default false (since the
- * beginning of time).
- * @type string $end_date End date to export content to. Expected date format is 'Y-m-d'. Used only when
- * `$content` is 'post', 'page' or 'attachment'. Default false (latest publish date).
- * @type string $status Post status to export posts for. Used only when `$content` is 'post' or 'page'.
- * Accepts false (all statuses except 'auto-draft'), or a specific status, i.e.
- * 'publish', 'pending', 'draft', 'auto-draft', 'future', 'private', 'inherit', or
- * 'trash'. Default false (all statuses except 'auto-draft').
+ * @type string $content Type of content to export. If set, only the post content of this post type
+ * will be exported. Accepts 'all', 'post', 'page', 'attachment', or a defined
+ * custom post. If an invalid custom post type is supplied, every post type for
+ * which `can_export` is enabled will be exported instead. If a valid custom post
+ * type is supplied but `can_export` is disabled, then 'posts' will be exported
+ * instead. When 'all' is supplied, only post types with `can_export` enabled will
+ * be exported. Default 'all'.
+ * @type string $author Author to export content for. Only used when `$content` is 'post', 'page', or
+ * 'attachment'. Accepts false (all) or a specific author ID. Default false (all).
+ * @type string $category Category (slug) to export content for. Used only when `$content` is 'post'. If
+ * set, only post content assigned to `$category` will be exported. Accepts false
+ * or a specific category slug. Default is false (all categories).
+ * @type string $start_date Start date to export content from. Expected date format is 'Y-m-d'. Used only
+ * when `$content` is 'post', 'page' or 'attachment'. Default false (since the
+ * beginning of time).
+ * @type string $end_date End date to export content to. Expected date format is 'Y-m-d'. Used only when
+ * `$content` is 'post', 'page' or 'attachment'. Default false (latest publish date).
+ * @type string $status Post status to export posts for. Used only when `$content` is 'post' or 'page'.
+ * Accepts false (all statuses except 'auto-draft'), or a specific status, i.e.
+ * 'publish', 'pending', 'draft', 'auto-draft', 'future', 'private', 'inherit', or
+ * 'trash'. Default false (all statuses except 'auto-draft').
* }
*/
function export_wp( $args = array() ) {
@@ -144,6 +144,52 @@
// Grab a snapshot of post IDs, just in case it changes during the export.
$post_ids = $wpdb->get_col( "SELECT ID FROM {$wpdb->posts} $join WHERE $where" );
+ // Get IDs for the attachments of each post, unless all content is already being exported.
+ if ( ! in_array( $args['content'], array( 'all', 'attachment' ), true ) ) {
+ // Array to hold all additional IDs (attachments and thumbnails).
+ $additional_ids = array();
+
+ // Create a copy of the post IDs array to avoid modifying the original array.
+ $processing_ids = $post_ids;
+
+ while ( $next_posts = array_splice( $processing_ids, 0, 20 ) ) {
+ $posts_in = array_map( 'absint', $next_posts );
+ $placeholders = array_fill( 0, count( $posts_in ), '%d' );
+
+ // Create a string for the placeholders.
+ $in_placeholder = implode( ',', $placeholders );
+
+ // Prepare the SQL statement for attachment ids.
+ $attachment_ids = $wpdb->get_col(
+ $wpdb->prepare(
+ "
+ SELECT ID
+ FROM $wpdb->posts
+ WHERE post_parent IN ($in_placeholder) AND post_type = 'attachment'
+ ",
+ $posts_in
+ )
+ );
+
+ $thumbnails_ids = $wpdb->get_col(
+ $wpdb->prepare(
+ "
+ SELECT meta_value
+ FROM $wpdb->postmeta
+ WHERE $wpdb->postmeta.post_id IN ($in_placeholder)
+ AND $wpdb->postmeta.meta_key = '_thumbnail_id'
+ ",
+ $posts_in
+ )
+ );
+
+ $additional_ids = array_merge( $additional_ids, $attachment_ids, $thumbnails_ids );
+ }
+
+ // Merge the additional IDs back with the original post IDs after processing all posts
+ $post_ids = array_unique( array_merge( $post_ids, $additional_ids ) );
+ }
+
/*
* Get the requested terms ready, empty unless posts filtered by category
* or all content.
@@ -189,7 +235,7 @@
}
/**
- * Wrap given string in XML CDATA tag.
+ * Wraps given string in XML CDATA tag.
*
* @since 2.1.0
*
@@ -207,7 +253,7 @@
}
/**
- * Return the URL of the site
+ * Returns the URL of the site.
*
* @since 2.5.0
*
@@ -218,17 +264,17 @@
// Multisite: the base URL.
return network_home_url();
} else {
- // WordPress (single site): the blog URL.
+ // WordPress (single site): the site URL.
return get_bloginfo_rss( 'url' );
}
}
/**
- * Output a cat_name XML tag from a given category object
+ * Outputs a cat_name XML tag from a given category object.
*
* @since 2.1.0
*
- * @param WP_Term $category Category Object
+ * @param WP_Term $category Category Object.
*/
function wxr_cat_name( $category ) {
if ( empty( $category->name ) ) {
@@ -239,11 +285,11 @@
}
/**
- * Output a category_description XML tag from a given category object
+ * Outputs a category_description XML tag from a given category object.
*
* @since 2.1.0
*
- * @param WP_Term $category Category Object
+ * @param WP_Term $category Category Object.
*/
function wxr_category_description( $category ) {
if ( empty( $category->description ) ) {
@@ -254,11 +300,11 @@
}
/**
- * Output a tag_name XML tag from a given tag object
+ * Outputs a tag_name XML tag from a given tag object.
*
* @since 2.3.0
*
- * @param WP_Term $tag Tag Object
+ * @param WP_Term $tag Tag Object.
*/
function wxr_tag_name( $tag ) {
if ( empty( $tag->name ) ) {
@@ -269,11 +315,11 @@
}
/**
- * Output a tag_description XML tag from a given tag object
+ * Outputs a tag_description XML tag from a given tag object.
*
* @since 2.3.0
*
- * @param WP_Term $tag Tag Object
+ * @param WP_Term $tag Tag Object.
*/
function wxr_tag_description( $tag ) {
if ( empty( $tag->description ) ) {
@@ -284,11 +330,11 @@
}
/**
- * Output a term_name XML tag from a given term object
+ * Outputs a term_name XML tag from a given term object.
*
* @since 2.9.0
*
- * @param WP_Term $term Term Object
+ * @param WP_Term $term Term Object.
*/
function wxr_term_name( $term ) {
if ( empty( $term->name ) ) {
@@ -299,11 +345,11 @@
}
/**
- * Output a term_description XML tag from a given term object
+ * Outputs a term_description XML tag from a given term object.
*
* @since 2.9.0
*
- * @param WP_Term $term Term Object
+ * @param WP_Term $term Term Object.
*/
function wxr_term_description( $term ) {
if ( empty( $term->description ) ) {
@@ -314,10 +360,12 @@
}
/**
- * Output term meta XML tags for a given term object.
+ * Outputs term meta XML tags for a given term object.
*
* @since 4.6.0
*
+ * @global wpdb $wpdb WordPress database abstraction object.
+ *
* @param WP_Term $term Term object.
*/
function wxr_term_meta( $term ) {
@@ -345,7 +393,7 @@
}
/**
- * Output list of authors with posts
+ * Outputs list of authors with posts.
*
* @since 3.1.0
*
@@ -353,7 +401,7 @@
*
* @param int[] $post_ids Optional. Array of post IDs to filter the query by.
*/
- function wxr_authors_list( array $post_ids = null ) {
+ function wxr_authors_list( ?array $post_ids = null ) {
global $wpdb;
if ( ! empty( $post_ids ) ) {
@@ -384,7 +432,7 @@
}
/**
- * Output all navigation menu terms
+ * Outputs all navigation menu terms.
*
* @since 3.1.0
*/
@@ -405,7 +453,7 @@
}
/**
- * Output list of taxonomy terms, in XML tag format, associated with a post
+ * Outputs list of taxonomy terms, in XML tag format, associated with a post.
*
* @since 2.3.0
*/
@@ -424,8 +472,12 @@
}
/**
- * @param bool $return_me
- * @param string $meta_key
+ * Determines whether to selectively skip post meta used for WXR exports.
+ *
+ * @since 3.3.0
+ *
+ * @param bool $return_me Whether to skip the current post meta. Default false.
+ * @param string $meta_key Meta key.
* @return bool
*/
function wxr_filter_postmeta( $return_me, $meta_key ) {
@@ -515,7 +567,8 @@
<?php endforeach; ?>
<?php
if ( 'all' === $args['content'] ) {
- wxr_nav_menu_terms();}
+ wxr_nav_menu_terms();
+ }
?>
<?php
@@ -632,7 +685,7 @@
<wp:comment_id><?php echo (int) $c->comment_ID; ?></wp:comment_id>
<wp:comment_author><?php echo wxr_cdata( $c->comment_author ); ?></wp:comment_author>
<wp:comment_author_email><?php echo wxr_cdata( $c->comment_author_email ); ?></wp:comment_author_email>
- <wp:comment_author_url><?php echo esc_url_raw( $c->comment_author_url ); ?></wp:comment_author_url>
+ <wp:comment_author_url><?php echo sanitize_url( $c->comment_author_url ); ?></wp:comment_author_url>
<wp:comment_author_IP><?php echo wxr_cdata( $c->comment_author_IP ); ?></wp:comment_author_IP>
<wp:comment_date><?php echo wxr_cdata( $c->comment_date ); ?></wp:comment_date>
<wp:comment_date_gmt><?php echo wxr_cdata( $c->comment_date_gmt ); ?></wp:comment_date_gmt>