WordPress.org

Make WordPress Core

Ticket #28146: 28146.7

File 28146.7, 8.0 KB (added by ivanblagdan, 6 years ago)
Line 
1diff --git a/src/wp-admin/includes/export.php b/src/wp-admin/includes/export.php
2index 6d01a2c..b200c0d 100644
3--- a/src/wp-admin/includes/export.php
4+++ b/src/wp-admin/includes/export.php
5@@ -42,6 +42,7 @@ function export_wp( $args = array() ) {
6         */
7        do_action( 'export_wp', $args );
8 
9+       // Set export file name
10        $sitename = sanitize_key( get_bloginfo( 'name' ) );
11        if ( ! empty( $sitename ) ) {
12                $sitename .= '.';
13@@ -59,48 +60,98 @@ function export_wp( $args = array() ) {
14         */
15        $filename = apply_filters( 'export_wp_filename', $wp_filename, $sitename, $date );
16 
17+       // Set content headers
18        header( 'Content-Description: File Transfer' );
19        header( 'Content-Disposition: attachment; filename=' . $filename );
20        header( 'Content-Type: text/xml; charset=' . get_option( 'blog_charset' ), true );
21 
22-       if ( 'all' != $args['content'] && post_type_exists( $args['content'] ) ) {
23-               $ptype = get_post_type_object( $args['content'] );
24-               if ( ! $ptype->can_export )
25-                       $args['content'] = 'post';
26+       $query_args = array(
27+               'post_status' => 'any',
28+               'posts_per_page' => -1
29+       );
30 
31-               $where = $wpdb->prepare( "{$wpdb->posts}.post_type = %s", $args['content'] );
32+       if ( 'all' != $args['content'] ) {
33+               $post_types = (array) $args['content'];
34+
35+               $query_args['post_type'] = array();
36+
37+               foreach( $post_types as $post_type ) {
38+                       $post_type_object = get_post_type_object( $post_type );
39+
40+                       if ( $post_type_object && $post_type_object->can_export ) {
41+                               $query_args['post_type'][] = $post_type;
42+                       }
43+               }
44+
45+               if ( empty( $query_args['post_type'] ) ) {
46+                       $query_args['post_type'] = 'post';
47+               }
48        } else {
49-               $post_types = get_post_types( array( 'can_export' => true ) );
50-               $esses = array_fill( 0, count($post_types), '%s' );
51-               $where = $wpdb->prepare( "{$wpdb->posts}.post_type IN (" . implode( ',', $esses ) . ')', $post_types );
52+               $query_args['post_type'] = array_values( get_post_types( array( 'can_export' => true ) ) );
53        }
54 
55-       if ( $args['status'] && ( 'post' == $args['content'] || 'page' == $args['content'] ) )
56-               $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_status = %s", $args['status'] );
57-       else
58-               $where .= " AND {$wpdb->posts}.post_status != 'auto-draft'";
59+       if ( $args['status'] && ( 'post' == $args['content'] || 'page' == $args['content'] ) ) {
60+               $query_args['post_status'] = $args['status'];
61+       }
62 
63-       $join = '';
64        if ( $args['category'] && 'post' == $args['content'] ) {
65                if ( $term = term_exists( $args['category'], 'category' ) ) {
66-                       $join = "INNER JOIN {$wpdb->term_relationships} ON ({$wpdb->posts}.ID = {$wpdb->term_relationships}.object_id)";
67-                       $where .= $wpdb->prepare( " AND {$wpdb->term_relationships}.term_taxonomy_id = %d", $term['term_taxonomy_id'] );
68+                       $query_args['tax_query'] = array(
69+                               array(
70+                                       'taxonomy' => 'category',
71+                                       'terms' => $term->term_id,
72+                                       'include_children' => false
73+                               )
74+                       );
75                }
76        }
77 
78-       if ( 'post' == $args['content'] || 'page' == $args['content'] || 'attachment' == $args['content'] ) {
79+       if ( 'post' == $args['content'] || 'page' == $args['content'] ) {
80                if ( $args['author'] )
81-                       $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_author = %d", $args['author'] );
82+                       $query_args['author'] = (int) $args['author'];
83+
84+               $date_query = array();
85+
86 
87                if ( $args['start_date'] )
88-                       $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_date >= %s", date( 'Y-m-d', strtotime($args['start_date']) ) );
89+                       $date_query[]['after'] = $args['start_date'];
90 
91-               if ( $args['end_date'] )
92-                       $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_date < %s", date( 'Y-m-d', strtotime('+1 month', strtotime($args['end_date'])) ) );
93+               if ( $args['end_date'] ) {
94+                       $date_query[]['before'] =  '@' . strtotime( '+1 month', strtotime( $args['end_date'] ) );
95+               }
96+
97+
98+               if ( ! empty( $date_query ) ) {
99+                       $query_args['date_query'] = $date_query;
100+               }
101        }
102 
103-       // Grab a snapshot of post IDs, just in case it changes during the export.
104-       $post_ids = $wpdb->get_col( "SELECT ID FROM {$wpdb->posts} $join WHERE $where" );
105+       /**
106+        * Filter WP_Query arguments for which posts to export.
107+        *
108+        * @todo Update since
109+        * @since 4.X
110+        *
111+        * @param array $query_args An array of WP_Query arguments.
112+        * @param array $args An array of export arguments.
113+        */
114+       $query_args = apply_filters( 'export_wp_query_args', $query_args, $args );
115+
116+       $query_args['fields'] = 'ids';
117+
118+       $post_ids = get_posts( $query_args );
119+
120+       /**
121+        * Filter Post IDs to be exported.
122+        *
123+        * @todo Update since
124+        * @since 4.X
125+        *
126+        * @param array $post_ids An array of Post IDs to export.
127+        * @param array $query_args An array of WP_Query arguments.
128+        * @param array $args An array of export arguments.
129+        */
130+       $post_ids = apply_filters( 'export_wp_post_ids', $post_ids, $query_args, $args );
131 
132        /*
133         * Get the requested terms ready, empty unless posts filtered by category
134@@ -111,29 +162,36 @@ function export_wp( $args = array() ) {
135                $cat = get_term( $term['term_id'], 'category' );
136                $cats = array( $cat->term_id => $cat );
137                unset( $term, $cat );
138-       } elseif ( 'all' == $args['content'] ) {
139+       } else if ( 'all' == $args['content'] ) {
140                $categories = (array) get_categories( array( 'get' => 'all' ) );
141                $tags = (array) get_tags( array( 'get' => 'all' ) );
142 
143                $custom_taxonomies = get_taxonomies( array( '_builtin' => false ) );
144                $custom_terms = (array) get_terms( $custom_taxonomies, array( 'get' => 'all' ) );
145 
146-               // Put categories in order with no child going before its parent.
147-               while ( $cat = array_shift( $categories ) ) {
148-                       if ( $cat->parent == 0 || isset( $cats[$cat->parent] ) )
149-                               $cats[$cat->term_id] = $cat;
150-                       else
151-                               $categories[] = $cat;
152+               // Put categories in order with no child going before its parent
153+               if( $categories ) {
154+                       while ( $cat = array_shift( $categories ) ) {
155+                               if ( $cat->parent == 0 || isset( $cats[$cat->parent] ) ) {
156+                                       $cats[$cat->term_id] = $cat;
157+                               } else {
158+                                       $categories[] = $cat;
159+                               }
160+                       }
161                }
162 
163-               // Put terms in order with no child going before its parent.
164-               while ( $t = array_shift( $custom_terms ) ) {
165-                       if ( $t->parent == 0 || isset( $terms[$t->parent] ) )
166-                               $terms[$t->term_id] = $t;
167-                       else
168-                               $custom_terms[] = $t;
169+               // Put terms in order with no child going before its parent
170+               if( $custom_terms ) {
171+                       while ( $t = array_shift( $custom_terms ) ) {
172+                               if ( $t->parent == 0 || isset( $terms[$t->parent] ) ) {
173+                                       $terms[$t->term_id] = $t;
174+                               } else {
175+                                       $custom_terms[] = $t;
176+                               }
177+                       }
178                }
179 
180+               // Clean up
181                unset( $categories, $custom_taxonomies, $custom_terms );
182        }
183 
184@@ -401,24 +459,27 @@ function export_wp( $args = array() ) {
185        do_action( 'rss2_head' );
186        ?>
187 
188-<?php if ( $post_ids ) {
189-       /**
190-        * @global WP_Query $wp_query
191-        */
192-       global $wp_query;
193-
194-       // Fake being in the loop.
195-       $wp_query->in_the_loop = true;
196-
197-       // Fetch 20 posts at a time rather than loading the entire table into memory.
198-       while ( $next_posts = array_splice( $post_ids, 0, 20 ) ) {
199-       $where = 'WHERE ID IN (' . join( ',', $next_posts ) . ')';
200-       $posts = $wpdb->get_results( "SELECT * FROM {$wpdb->posts} $where" );
201-
202-       // Begin Loop.
203-       foreach ( $posts as $post ) {
204-               setup_postdata( $post );
205-               $is_sticky = is_sticky( $post->ID ) ? 1 : 0;
206+       <?php
207+       if ( $post_ids ) {
208+               $posts_per_page = 20;
209+
210+               $wp_query_args = array(
211+                       'post_type'      => 'any',
212+                       'post_status'    => 'any',
213+                       'posts_per_page' => $posts_per_page,
214+                       'post__in'       => array_slice( $post_ids, 0, $posts_per_page )
215+               );
216+
217+               $query = new WP_Query( $wp_query_args );
218+
219+               $page = 0;
220+
221+               // Paginate posts 20 at a time
222+               while ( $query->have_posts() ) {
223+                       // Begin Loop.
224+                       while ( $query->have_posts() ) {
225+                               $query->the_post();
226+                                       $is_sticky = is_sticky( $post->ID ) ? 1 : 0;
227 ?>
228        <item>
229                <title><?php
230@@ -532,9 +593,17 @@ function export_wp( $args = array() ) {
231 <?php  endforeach; ?>
232        </item>
233 <?php
234+                       }
235+
236+                       // Fetch next set of posts
237+                       $wp_query_args['post__in'] = array_slice( $post_ids, ( $page * $posts_per_page ), $posts_per_page );
238+
239+                       $query->query( $wp_query_args );
240+
241+                       $page++;
242+               }
243        }
244-       }
245-} ?>
246+?>
247 </channel>
248 </rss>
249 <?php