41 * Initialize the upgrade strings. |
41 * Initialize the upgrade strings. |
42 * |
42 * |
43 * @since 2.8.0 |
43 * @since 2.8.0 |
44 */ |
44 */ |
45 public function upgrade_strings() { |
45 public function upgrade_strings() { |
46 $this->strings['up_to_date'] = __('The theme is at the latest version.'); |
46 $this->strings['up_to_date'] = __( 'The theme is at the latest version.' ); |
47 $this->strings['no_package'] = __('Update package not available.'); |
47 $this->strings['no_package'] = __( 'Update package not available.' ); |
48 /* translators: %s: package URL */ |
48 /* translators: %s: package URL */ |
49 $this->strings['downloading_package'] = sprintf( __( 'Downloading update from %s…' ), '<span class="code">%s</span>' ); |
49 $this->strings['downloading_package'] = sprintf( __( 'Downloading update from %s…' ), '<span class="code">%s</span>' ); |
50 $this->strings['unpack_package'] = __('Unpacking the update…'); |
50 $this->strings['unpack_package'] = __( 'Unpacking the update…' ); |
51 $this->strings['remove_old'] = __('Removing the old version of the theme…'); |
51 $this->strings['remove_old'] = __( 'Removing the old version of the theme…' ); |
52 $this->strings['remove_old_failed'] = __('Could not remove the old theme.'); |
52 $this->strings['remove_old_failed'] = __( 'Could not remove the old theme.' ); |
53 $this->strings['process_failed'] = __('Theme update failed.'); |
53 $this->strings['process_failed'] = __( 'Theme update failed.' ); |
54 $this->strings['process_success'] = __('Theme updated successfully.'); |
54 $this->strings['process_success'] = __( 'Theme updated successfully.' ); |
55 } |
55 } |
56 |
56 |
57 /** |
57 /** |
58 * Initialize the installation strings. |
58 * Initialize the installation strings. |
59 * |
59 * |
60 * @since 2.8.0 |
60 * @since 2.8.0 |
61 */ |
61 */ |
62 public function install_strings() { |
62 public function install_strings() { |
63 $this->strings['no_package'] = __('Installation package not available.'); |
63 $this->strings['no_package'] = __( 'Installation package not available.' ); |
64 /* translators: %s: package URL */ |
64 /* translators: %s: package URL */ |
65 $this->strings['downloading_package'] = sprintf( __( 'Downloading installation package from %s…' ), '<span class="code">%s</span>' ); |
65 $this->strings['downloading_package'] = sprintf( __( 'Downloading installation package from %s…' ), '<span class="code">%s</span>' ); |
66 $this->strings['unpack_package'] = __('Unpacking the package…'); |
66 $this->strings['unpack_package'] = __( 'Unpacking the package…' ); |
67 $this->strings['installing_package'] = __('Installing the theme…'); |
67 $this->strings['installing_package'] = __( 'Installing the theme…' ); |
68 $this->strings['no_files'] = __('The theme contains no files.'); |
68 $this->strings['no_files'] = __( 'The theme contains no files.' ); |
69 $this->strings['process_failed'] = __('Theme installation failed.'); |
69 $this->strings['process_failed'] = __( 'Theme installation failed.' ); |
70 $this->strings['process_success'] = __('Theme installed successfully.'); |
70 $this->strings['process_success'] = __( 'Theme installed successfully.' ); |
71 /* translators: 1: theme name, 2: version */ |
71 /* translators: 1: theme name, 2: version */ |
72 $this->strings['process_success_specific'] = __('Successfully installed the theme <strong>%1$s %2$s</strong>.'); |
72 $this->strings['process_success_specific'] = __( 'Successfully installed the theme <strong>%1$s %2$s</strong>.' ); |
73 $this->strings['parent_theme_search'] = __('This theme requires a parent theme. Checking if it is installed…'); |
73 $this->strings['parent_theme_search'] = __( 'This theme requires a parent theme. Checking if it is installed…' ); |
74 /* translators: 1: theme name, 2: version */ |
74 /* translators: 1: theme name, 2: version */ |
75 $this->strings['parent_theme_prepare_install'] = __('Preparing to install <strong>%1$s %2$s</strong>…'); |
75 $this->strings['parent_theme_prepare_install'] = __( 'Preparing to install <strong>%1$s %2$s</strong>…' ); |
76 /* translators: 1: theme name, 2: version */ |
76 /* translators: 1: theme name, 2: version */ |
77 $this->strings['parent_theme_currently_installed'] = __('The parent theme, <strong>%1$s %2$s</strong>, is currently installed.'); |
77 $this->strings['parent_theme_currently_installed'] = __( 'The parent theme, <strong>%1$s %2$s</strong>, is currently installed.' ); |
78 /* translators: 1: theme name, 2: version */ |
78 /* translators: 1: theme name, 2: version */ |
79 $this->strings['parent_theme_install_success'] = __('Successfully installed the parent theme, <strong>%1$s %2$s</strong>.'); |
79 $this->strings['parent_theme_install_success'] = __( 'Successfully installed the parent theme, <strong>%1$s %2$s</strong>.' ); |
80 /* translators: %s: theme name */ |
80 /* translators: %s: theme name */ |
81 $this->strings['parent_theme_not_found'] = sprintf( __( '<strong>The parent theme could not be found.</strong> You will need to install the parent theme, %s, before you can use this child theme.' ), '<strong>%s</strong>' ); |
81 $this->strings['parent_theme_not_found'] = sprintf( __( '<strong>The parent theme could not be found.</strong> You will need to install the parent theme, %s, before you can use this child theme.' ), '<strong>%s</strong>' ); |
82 } |
82 } |
83 |
83 |
84 /** |
84 /** |
95 */ |
95 */ |
96 public function check_parent_theme_filter( $install_result, $hook_extra, $child_result ) { |
96 public function check_parent_theme_filter( $install_result, $hook_extra, $child_result ) { |
97 // Check to see if we need to install a parent theme |
97 // Check to see if we need to install a parent theme |
98 $theme_info = $this->theme_info(); |
98 $theme_info = $this->theme_info(); |
99 |
99 |
100 if ( ! $theme_info->parent() ) |
100 if ( ! $theme_info->parent() ) { |
101 return $install_result; |
101 return $install_result; |
|
102 } |
102 |
103 |
103 $this->skin->feedback( 'parent_theme_search' ); |
104 $this->skin->feedback( 'parent_theme_search' ); |
104 |
105 |
105 if ( ! $theme_info->parent()->errors() ) { |
106 if ( ! $theme_info->parent()->errors() ) { |
106 $this->skin->feedback( 'parent_theme_currently_installed', $theme_info->parent()->display('Name'), $theme_info->parent()->display('Version') ); |
107 $this->skin->feedback( 'parent_theme_currently_installed', $theme_info->parent()->display( 'Name' ), $theme_info->parent()->display( 'Version' ) ); |
107 // We already have the theme, fall through. |
108 // We already have the theme, fall through. |
108 return $install_result; |
109 return $install_result; |
109 } |
110 } |
110 |
111 |
111 // We don't have the parent theme, let's install it. |
112 // We don't have the parent theme, let's install it. |
112 $api = themes_api('theme_information', array('slug' => $theme_info->get('Template'), 'fields' => array('sections' => false, 'tags' => false) ) ); //Save on a bit of bandwidth. |
113 $api = themes_api( |
113 |
114 'theme_information', |
114 if ( ! $api || is_wp_error($api) ) { |
115 array( |
115 $this->skin->feedback( 'parent_theme_not_found', $theme_info->get('Template') ); |
116 'slug' => $theme_info->get( 'Template' ), |
|
117 'fields' => array( |
|
118 'sections' => false, |
|
119 'tags' => false, |
|
120 ), |
|
121 ) |
|
122 ); //Save on a bit of bandwidth. |
|
123 |
|
124 if ( ! $api || is_wp_error( $api ) ) { |
|
125 $this->skin->feedback( 'parent_theme_not_found', $theme_info->get( 'Template' ) ); |
116 // Don't show activate or preview actions after installation |
126 // Don't show activate or preview actions after installation |
117 add_filter('install_theme_complete_actions', array($this, 'hide_activate_preview_actions') ); |
127 add_filter( 'install_theme_complete_actions', array( $this, 'hide_activate_preview_actions' ) ); |
118 return $install_result; |
128 return $install_result; |
119 } |
129 } |
120 |
130 |
121 // Backup required data we're going to override: |
131 // Backup required data we're going to override: |
122 $child_api = $this->skin->api; |
132 $child_api = $this->skin->api; |
123 $child_success_message = $this->strings['process_success']; |
133 $child_success_message = $this->strings['process_success']; |
124 |
134 |
125 // Override them |
135 // Override them |
126 $this->skin->api = $api; |
136 $this->skin->api = $api; |
127 $this->strings['process_success_specific'] = $this->strings['parent_theme_install_success'];//, $api->name, $api->version); |
137 $this->strings['process_success_specific'] = $this->strings['parent_theme_install_success'];//, $api->name, $api->version); |
128 |
138 |
129 $this->skin->feedback('parent_theme_prepare_install', $api->name, $api->version); |
139 $this->skin->feedback( 'parent_theme_prepare_install', $api->name, $api->version ); |
130 |
140 |
131 add_filter('install_theme_complete_actions', '__return_false', 999); // Don't show any actions after installing the theme. |
141 add_filter( 'install_theme_complete_actions', '__return_false', 999 ); // Don't show any actions after installing the theme. |
132 |
142 |
133 // Install the parent theme |
143 // Install the parent theme |
134 $parent_result = $this->run( array( |
144 $parent_result = $this->run( |
135 'package' => $api->download_link, |
145 array( |
136 'destination' => get_theme_root(), |
146 'package' => $api->download_link, |
137 'clear_destination' => false, //Do not overwrite files. |
147 'destination' => get_theme_root(), |
138 'clear_working' => true |
148 'clear_destination' => false, //Do not overwrite files. |
139 ) ); |
149 'clear_working' => true, |
140 |
150 ) |
141 if ( is_wp_error($parent_result) ) |
151 ); |
142 add_filter('install_theme_complete_actions', array($this, 'hide_activate_preview_actions') ); |
152 |
|
153 if ( is_wp_error( $parent_result ) ) { |
|
154 add_filter( 'install_theme_complete_actions', array( $this, 'hide_activate_preview_actions' ) ); |
|
155 } |
143 |
156 |
144 // Start cleaning up after the parents installation |
157 // Start cleaning up after the parents installation |
145 remove_filter('install_theme_complete_actions', '__return_false', 999); |
158 remove_filter( 'install_theme_complete_actions', '__return_false', 999 ); |
146 |
159 |
147 // Reset child's result and data |
160 // Reset child's result and data |
148 $this->result = $child_result; |
161 $this->result = $child_result; |
149 $this->skin->api = $child_api; |
162 $this->skin->api = $child_api; |
150 $this->strings['process_success'] = $child_success_message; |
163 $this->strings['process_success'] = $child_success_message; |
151 |
164 |
152 return $install_result; |
165 return $install_result; |
153 } |
166 } |
154 |
167 |
185 * |
198 * |
186 * @return bool|WP_Error True if the installation was successful, false or a WP_Error object otherwise. |
199 * @return bool|WP_Error True if the installation was successful, false or a WP_Error object otherwise. |
187 */ |
200 */ |
188 public function install( $package, $args = array() ) { |
201 public function install( $package, $args = array() ) { |
189 |
202 |
190 $defaults = array( |
203 $defaults = array( |
191 'clear_update_cache' => true, |
204 'clear_update_cache' => true, |
192 ); |
205 ); |
193 $parsed_args = wp_parse_args( $args, $defaults ); |
206 $parsed_args = wp_parse_args( $args, $defaults ); |
194 |
207 |
195 $this->init(); |
208 $this->init(); |
196 $this->install_strings(); |
209 $this->install_strings(); |
197 |
210 |
198 add_filter('upgrader_source_selection', array($this, 'check_package') ); |
211 add_filter( 'upgrader_source_selection', array( $this, 'check_package' ) ); |
199 add_filter('upgrader_post_install', array($this, 'check_parent_theme_filter'), 10, 3); |
212 add_filter( 'upgrader_post_install', array( $this, 'check_parent_theme_filter' ), 10, 3 ); |
200 if ( $parsed_args['clear_update_cache'] ) { |
213 if ( $parsed_args['clear_update_cache'] ) { |
201 // Clear cache so wp_update_themes() knows about the new theme. |
214 // Clear cache so wp_update_themes() knows about the new theme. |
202 add_action( 'upgrader_process_complete', 'wp_clean_themes_cache', 9, 0 ); |
215 add_action( 'upgrader_process_complete', 'wp_clean_themes_cache', 9, 0 ); |
203 } |
216 } |
204 |
217 |
205 $this->run( array( |
218 $this->run( |
206 'package' => $package, |
219 array( |
207 'destination' => get_theme_root(), |
220 'package' => $package, |
208 'clear_destination' => false, //Do not overwrite files. |
221 'destination' => get_theme_root(), |
209 'clear_working' => true, |
222 'clear_destination' => false, //Do not overwrite files. |
210 'hook_extra' => array( |
223 'clear_working' => true, |
211 'type' => 'theme', |
224 'hook_extra' => array( |
212 'action' => 'install', |
225 'type' => 'theme', |
213 ), |
226 'action' => 'install', |
214 ) ); |
227 ), |
|
228 ) |
|
229 ); |
215 |
230 |
216 remove_action( 'upgrader_process_complete', 'wp_clean_themes_cache', 9 ); |
231 remove_action( 'upgrader_process_complete', 'wp_clean_themes_cache', 9 ); |
217 remove_filter('upgrader_source_selection', array($this, 'check_package') ); |
232 remove_filter( 'upgrader_source_selection', array( $this, 'check_package' ) ); |
218 remove_filter('upgrader_post_install', array($this, 'check_parent_theme_filter')); |
233 remove_filter( 'upgrader_post_install', array( $this, 'check_parent_theme_filter' ) ); |
219 |
234 |
220 if ( ! $this->result || is_wp_error($this->result) ) |
235 if ( ! $this->result || is_wp_error( $this->result ) ) { |
221 return $this->result; |
236 return $this->result; |
|
237 } |
222 |
238 |
223 // Refresh the Theme Update information |
239 // Refresh the Theme Update information |
224 wp_clean_themes_cache( $parsed_args['clear_update_cache'] ); |
240 wp_clean_themes_cache( $parsed_args['clear_update_cache'] ); |
225 |
241 |
226 return true; |
242 return true; |
241 * } |
257 * } |
242 * @return bool|WP_Error True if the upgrade was successful, false or a WP_Error object otherwise. |
258 * @return bool|WP_Error True if the upgrade was successful, false or a WP_Error object otherwise. |
243 */ |
259 */ |
244 public function upgrade( $theme, $args = array() ) { |
260 public function upgrade( $theme, $args = array() ) { |
245 |
261 |
246 $defaults = array( |
262 $defaults = array( |
247 'clear_update_cache' => true, |
263 'clear_update_cache' => true, |
248 ); |
264 ); |
249 $parsed_args = wp_parse_args( $args, $defaults ); |
265 $parsed_args = wp_parse_args( $args, $defaults ); |
250 |
266 |
251 $this->init(); |
267 $this->init(); |
252 $this->upgrade_strings(); |
268 $this->upgrade_strings(); |
253 |
269 |
254 // Is an update available? |
270 // Is an update available? |
255 $current = get_site_transient( 'update_themes' ); |
271 $current = get_site_transient( 'update_themes' ); |
256 if ( !isset( $current->response[ $theme ] ) ) { |
272 if ( ! isset( $current->response[ $theme ] ) ) { |
257 $this->skin->before(); |
273 $this->skin->before(); |
258 $this->skin->set_result(false); |
274 $this->skin->set_result( false ); |
259 $this->skin->error( 'up_to_date' ); |
275 $this->skin->error( 'up_to_date' ); |
260 $this->skin->after(); |
276 $this->skin->after(); |
261 return false; |
277 return false; |
262 } |
278 } |
263 |
279 |
264 $r = $current->response[ $theme ]; |
280 $r = $current->response[ $theme ]; |
265 |
281 |
266 add_filter('upgrader_pre_install', array($this, 'current_before'), 10, 2); |
282 add_filter( 'upgrader_pre_install', array( $this, 'current_before' ), 10, 2 ); |
267 add_filter('upgrader_post_install', array($this, 'current_after'), 10, 2); |
283 add_filter( 'upgrader_post_install', array( $this, 'current_after' ), 10, 2 ); |
268 add_filter('upgrader_clear_destination', array($this, 'delete_old_theme'), 10, 4); |
284 add_filter( 'upgrader_clear_destination', array( $this, 'delete_old_theme' ), 10, 4 ); |
269 if ( $parsed_args['clear_update_cache'] ) { |
285 if ( $parsed_args['clear_update_cache'] ) { |
270 // Clear cache so wp_update_themes() knows about the new theme. |
286 // Clear cache so wp_update_themes() knows about the new theme. |
271 add_action( 'upgrader_process_complete', 'wp_clean_themes_cache', 9, 0 ); |
287 add_action( 'upgrader_process_complete', 'wp_clean_themes_cache', 9, 0 ); |
272 } |
288 } |
273 |
289 |
274 $this->run( array( |
290 $this->run( |
275 'package' => $r['package'], |
291 array( |
276 'destination' => get_theme_root( $theme ), |
292 'package' => $r['package'], |
277 'clear_destination' => true, |
293 'destination' => get_theme_root( $theme ), |
278 'clear_working' => true, |
294 'clear_destination' => true, |
279 'hook_extra' => array( |
295 'clear_working' => true, |
280 'theme' => $theme, |
296 'hook_extra' => array( |
281 'type' => 'theme', |
297 'theme' => $theme, |
282 'action' => 'update', |
298 'type' => 'theme', |
283 ), |
299 'action' => 'update', |
284 ) ); |
300 ), |
|
301 ) |
|
302 ); |
285 |
303 |
286 remove_action( 'upgrader_process_complete', 'wp_clean_themes_cache', 9 ); |
304 remove_action( 'upgrader_process_complete', 'wp_clean_themes_cache', 9 ); |
287 remove_filter('upgrader_pre_install', array($this, 'current_before')); |
305 remove_filter( 'upgrader_pre_install', array( $this, 'current_before' ) ); |
288 remove_filter('upgrader_post_install', array($this, 'current_after')); |
306 remove_filter( 'upgrader_post_install', array( $this, 'current_after' ) ); |
289 remove_filter('upgrader_clear_destination', array($this, 'delete_old_theme')); |
307 remove_filter( 'upgrader_clear_destination', array( $this, 'delete_old_theme' ) ); |
290 |
308 |
291 if ( ! $this->result || is_wp_error($this->result) ) |
309 if ( ! $this->result || is_wp_error( $this->result ) ) { |
292 return $this->result; |
310 return $this->result; |
|
311 } |
293 |
312 |
294 wp_clean_themes_cache( $parsed_args['clear_update_cache'] ); |
313 wp_clean_themes_cache( $parsed_args['clear_update_cache'] ); |
295 |
314 |
296 return true; |
315 return true; |
297 } |
316 } |
300 * Upgrade several themes at once. |
319 * Upgrade several themes at once. |
301 * |
320 * |
302 * @since 3.0.0 |
321 * @since 3.0.0 |
303 * @since 3.7.0 The `$args` parameter was added, making clearing the update cache optional. |
322 * @since 3.7.0 The `$args` parameter was added, making clearing the update cache optional. |
304 * |
323 * |
305 * @param array $themes The theme slugs. |
324 * @param string[] $themes Array of the theme slugs. |
306 * @param array $args { |
325 * @param array $args { |
307 * Optional. Other arguments for upgrading several themes at once. Default empty array. |
326 * Optional. Other arguments for upgrading several themes at once. Default empty array. |
308 * |
327 * |
309 * @type bool $clear_update_cache Whether to clear the update cache if successful. |
328 * @type bool $clear_update_cache Whether to clear the update cache if successful. |
310 * Default true. |
329 * Default true. |
311 * } |
330 * } |
312 * @return array[]|false An array of results, or false if unable to connect to the filesystem. |
331 * @return array[]|false An array of results, or false if unable to connect to the filesystem. |
313 */ |
332 */ |
314 public function bulk_upgrade( $themes, $args = array() ) { |
333 public function bulk_upgrade( $themes, $args = array() ) { |
315 |
334 |
316 $defaults = array( |
335 $defaults = array( |
317 'clear_update_cache' => true, |
336 'clear_update_cache' => true, |
318 ); |
337 ); |
319 $parsed_args = wp_parse_args( $args, $defaults ); |
338 $parsed_args = wp_parse_args( $args, $defaults ); |
320 |
339 |
321 $this->init(); |
340 $this->init(); |
322 $this->bulk = true; |
341 $this->bulk = true; |
323 $this->upgrade_strings(); |
342 $this->upgrade_strings(); |
324 |
343 |
325 $current = get_site_transient( 'update_themes' ); |
344 $current = get_site_transient( 'update_themes' ); |
326 |
345 |
327 add_filter('upgrader_pre_install', array($this, 'current_before'), 10, 2); |
346 add_filter( 'upgrader_pre_install', array( $this, 'current_before' ), 10, 2 ); |
328 add_filter('upgrader_post_install', array($this, 'current_after'), 10, 2); |
347 add_filter( 'upgrader_post_install', array( $this, 'current_after' ), 10, 2 ); |
329 add_filter('upgrader_clear_destination', array($this, 'delete_old_theme'), 10, 4); |
348 add_filter( 'upgrader_clear_destination', array( $this, 'delete_old_theme' ), 10, 4 ); |
330 |
349 |
331 $this->skin->header(); |
350 $this->skin->header(); |
332 |
351 |
333 // Connect to the Filesystem first. |
352 // Connect to the Filesystem first. |
334 $res = $this->fs_connect( array(WP_CONTENT_DIR) ); |
353 $res = $this->fs_connect( array( WP_CONTENT_DIR ) ); |
335 if ( ! $res ) { |
354 if ( ! $res ) { |
336 $this->skin->footer(); |
355 $this->skin->footer(); |
337 return false; |
356 return false; |
338 } |
357 } |
339 |
358 |
342 // Only start maintenance mode if: |
361 // Only start maintenance mode if: |
343 // - running Multisite and there are one or more themes specified, OR |
362 // - running Multisite and there are one or more themes specified, OR |
344 // - a theme with an update available is currently in use. |
363 // - a theme with an update available is currently in use. |
345 // @TODO: For multisite, maintenance mode should only kick in for individual sites if at all possible. |
364 // @TODO: For multisite, maintenance mode should only kick in for individual sites if at all possible. |
346 $maintenance = ( is_multisite() && ! empty( $themes ) ); |
365 $maintenance = ( is_multisite() && ! empty( $themes ) ); |
347 foreach ( $themes as $theme ) |
366 foreach ( $themes as $theme ) { |
348 $maintenance = $maintenance || $theme == get_stylesheet() || $theme == get_template(); |
367 $maintenance = $maintenance || $theme == get_stylesheet() || $theme == get_template(); |
349 if ( $maintenance ) |
368 } |
350 $this->maintenance_mode(true); |
369 if ( $maintenance ) { |
|
370 $this->maintenance_mode( true ); |
|
371 } |
351 |
372 |
352 $results = array(); |
373 $results = array(); |
353 |
374 |
354 $this->update_count = count($themes); |
375 $this->update_count = count( $themes ); |
355 $this->update_current = 0; |
376 $this->update_current = 0; |
356 foreach ( $themes as $theme ) { |
377 foreach ( $themes as $theme ) { |
357 $this->update_current++; |
378 $this->update_current++; |
358 |
379 |
359 $this->skin->theme_info = $this->theme_info($theme); |
380 $this->skin->theme_info = $this->theme_info( $theme ); |
360 |
381 |
361 if ( !isset( $current->response[ $theme ] ) ) { |
382 if ( ! isset( $current->response[ $theme ] ) ) { |
362 $this->skin->set_result(true); |
383 $this->skin->set_result( true ); |
363 $this->skin->before(); |
384 $this->skin->before(); |
364 $this->skin->feedback( 'up_to_date' ); |
385 $this->skin->feedback( 'up_to_date' ); |
365 $this->skin->after(); |
386 $this->skin->after(); |
366 $results[$theme] = true; |
387 $results[ $theme ] = true; |
367 continue; |
388 continue; |
368 } |
389 } |
369 |
390 |
370 // Get the URL to the zip file |
391 // Get the URL to the zip file |
371 $r = $current->response[ $theme ]; |
392 $r = $current->response[ $theme ]; |
372 |
393 |
373 $result = $this->run( array( |
394 $result = $this->run( |
374 'package' => $r['package'], |
395 array( |
375 'destination' => get_theme_root( $theme ), |
396 'package' => $r['package'], |
376 'clear_destination' => true, |
397 'destination' => get_theme_root( $theme ), |
377 'clear_working' => true, |
398 'clear_destination' => true, |
378 'is_multi' => true, |
399 'clear_working' => true, |
379 'hook_extra' => array( |
400 'is_multi' => true, |
380 'theme' => $theme |
401 'hook_extra' => array( |
381 ), |
402 'theme' => $theme, |
382 ) ); |
403 ), |
383 |
404 ) |
384 $results[$theme] = $this->result; |
405 ); |
|
406 |
|
407 $results[ $theme ] = $this->result; |
385 |
408 |
386 // Prevent credentials auth screen from displaying multiple times |
409 // Prevent credentials auth screen from displaying multiple times |
387 if ( false === $result ) |
410 if ( false === $result ) { |
388 break; |
411 break; |
|
412 } |
389 } //end foreach $plugins |
413 } //end foreach $plugins |
390 |
414 |
391 $this->maintenance_mode(false); |
415 $this->maintenance_mode( false ); |
392 |
416 |
393 // Refresh the Theme Update information |
417 // Refresh the Theme Update information |
394 wp_clean_themes_cache( $parsed_args['clear_update_cache'] ); |
418 wp_clean_themes_cache( $parsed_args['clear_update_cache'] ); |
395 |
419 |
396 /** This action is documented in wp-admin/includes/class-wp-upgrader.php */ |
420 /** This action is documented in wp-admin/includes/class-wp-upgrader.php */ |
397 do_action( 'upgrader_process_complete', $this, array( |
421 do_action( |
398 'action' => 'update', |
422 'upgrader_process_complete', |
399 'type' => 'theme', |
423 $this, |
400 'bulk' => true, |
424 array( |
401 'themes' => $themes, |
425 'action' => 'update', |
402 ) ); |
426 'type' => 'theme', |
|
427 'bulk' => true, |
|
428 'themes' => $themes, |
|
429 ) |
|
430 ); |
403 |
431 |
404 $this->skin->bulk_footer(); |
432 $this->skin->bulk_footer(); |
405 |
433 |
406 $this->skin->footer(); |
434 $this->skin->footer(); |
407 |
435 |
408 // Cleanup our hooks, in case something else does a upgrade on this connection. |
436 // Cleanup our hooks, in case something else does a upgrade on this connection. |
409 remove_filter('upgrader_pre_install', array($this, 'current_before')); |
437 remove_filter( 'upgrader_pre_install', array( $this, 'current_before' ) ); |
410 remove_filter('upgrader_post_install', array($this, 'current_after')); |
438 remove_filter( 'upgrader_post_install', array( $this, 'current_after' ) ); |
411 remove_filter('upgrader_clear_destination', array($this, 'delete_old_theme')); |
439 remove_filter( 'upgrader_clear_destination', array( $this, 'delete_old_theme' ) ); |
412 |
440 |
413 return $results; |
441 return $results; |
414 } |
442 } |
415 |
443 |
416 /** |
444 /** |
420 * It will return an error if the theme doesn't have style.css or index.php |
448 * It will return an error if the theme doesn't have style.css or index.php |
421 * files. |
449 * files. |
422 * |
450 * |
423 * @since 3.3.0 |
451 * @since 3.3.0 |
424 * |
452 * |
425 * @global WP_Filesystem_Base $wp_filesystem Subclass |
453 * @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass. |
426 * |
454 * |
427 * @param string $source The full path to the package source. |
455 * @param string $source The full path to the package source. |
428 * @return string|WP_Error The source or a WP_Error. |
456 * @return string|WP_Error The source or a WP_Error. |
429 */ |
457 */ |
430 public function check_package( $source ) { |
458 public function check_package( $source ) { |
431 global $wp_filesystem; |
459 global $wp_filesystem; |
432 |
460 |
433 if ( is_wp_error($source) ) |
461 if ( is_wp_error( $source ) ) { |
434 return $source; |
462 return $source; |
|
463 } |
435 |
464 |
436 // Check the folder contains a valid theme |
465 // Check the folder contains a valid theme |
437 $working_directory = str_replace( $wp_filesystem->wp_content_dir(), trailingslashit(WP_CONTENT_DIR), $source); |
466 $working_directory = str_replace( $wp_filesystem->wp_content_dir(), trailingslashit( WP_CONTENT_DIR ), $source ); |
438 if ( ! is_dir($working_directory) ) // Sanity check, if the above fails, let's not prevent installation. |
467 if ( ! is_dir( $working_directory ) ) { // Sanity check, if the above fails, let's not prevent installation. |
439 return $source; |
468 return $source; |
|
469 } |
440 |
470 |
441 // A proper archive should have a style.css file in the single subdirectory |
471 // A proper archive should have a style.css file in the single subdirectory |
442 if ( ! file_exists( $working_directory . 'style.css' ) ) { |
472 if ( ! file_exists( $working_directory . 'style.css' ) ) { |
443 return new WP_Error( 'incompatible_archive_theme_no_style', $this->strings['incompatible_archive'], |
473 return new WP_Error( |
444 /* translators: %s: style.css */ |
474 'incompatible_archive_theme_no_style', |
445 sprintf( __( 'The theme is missing the %s stylesheet.' ), |
475 $this->strings['incompatible_archive'], |
|
476 sprintf( |
|
477 /* translators: %s: style.css */ |
|
478 __( 'The theme is missing the %s stylesheet.' ), |
446 '<code>style.css</code>' |
479 '<code>style.css</code>' |
447 ) |
480 ) |
448 ); |
481 ); |
449 } |
482 } |
450 |
483 |
451 $info = get_file_data( $working_directory . 'style.css', array( 'Name' => 'Theme Name', 'Template' => 'Template' ) ); |
484 $info = get_file_data( |
|
485 $working_directory . 'style.css', |
|
486 array( |
|
487 'Name' => 'Theme Name', |
|
488 'Template' => 'Template', |
|
489 ) |
|
490 ); |
452 |
491 |
453 if ( empty( $info['Name'] ) ) { |
492 if ( empty( $info['Name'] ) ) { |
454 return new WP_Error( 'incompatible_archive_theme_no_name', $this->strings['incompatible_archive'], |
493 return new WP_Error( |
455 /* translators: %s: style.css */ |
494 'incompatible_archive_theme_no_name', |
456 sprintf( __( 'The %s stylesheet doesn’t contain a valid theme header.' ), |
495 $this->strings['incompatible_archive'], |
|
496 sprintf( |
|
497 /* translators: %s: style.css */ |
|
498 __( 'The %s stylesheet doesn’t contain a valid theme header.' ), |
457 '<code>style.css</code>' |
499 '<code>style.css</code>' |
458 ) |
500 ) |
459 ); |
501 ); |
460 } |
502 } |
461 |
503 |
462 // If it's not a child theme, it must have at least an index.php to be legit. |
504 // If it's not a child theme, it must have at least an index.php to be legit. |
463 if ( empty( $info['Template'] ) && ! file_exists( $working_directory . 'index.php' ) ) { |
505 if ( empty( $info['Template'] ) && ! file_exists( $working_directory . 'index.php' ) ) { |
464 return new WP_Error( 'incompatible_archive_theme_no_index', $this->strings['incompatible_archive'], |
506 return new WP_Error( |
465 /* translators: %s: index.php */ |
507 'incompatible_archive_theme_no_index', |
466 sprintf( __( 'The theme is missing the %s file.' ), |
508 $this->strings['incompatible_archive'], |
|
509 sprintf( |
|
510 /* translators: %s: index.php */ |
|
511 __( 'The theme is missing the %s file.' ), |
467 '<code>index.php</code>' |
512 '<code>index.php</code>' |
468 ) |
513 ) |
469 ); |
514 ); |
470 } |
515 } |
471 |
516 |
509 * |
557 * |
510 * @param bool|WP_Error $return |
558 * @param bool|WP_Error $return |
511 * @param array $theme |
559 * @param array $theme |
512 * @return bool|WP_Error |
560 * @return bool|WP_Error |
513 */ |
561 */ |
514 public function current_after($return, $theme) { |
562 public function current_after( $return, $theme ) { |
515 if ( is_wp_error($return) ) |
563 if ( is_wp_error( $return ) ) { |
516 return $return; |
564 return $return; |
517 |
565 } |
518 $theme = isset($theme['theme']) ? $theme['theme'] : ''; |
566 |
519 |
567 $theme = isset( $theme['theme'] ) ? $theme['theme'] : ''; |
520 if ( $theme != get_stylesheet() ) // If not current |
568 |
|
569 if ( $theme != get_stylesheet() ) { // If not current |
521 return $return; |
570 return $return; |
|
571 } |
522 |
572 |
523 // Ensure stylesheet name hasn't changed after the upgrade: |
573 // Ensure stylesheet name hasn't changed after the upgrade: |
524 if ( $theme == get_stylesheet() && $theme != $this->result['destination_name'] ) { |
574 if ( $theme == get_stylesheet() && $theme != $this->result['destination_name'] ) { |
525 wp_clean_themes_cache(); |
575 wp_clean_themes_cache(); |
526 $stylesheet = $this->result['destination_name']; |
576 $stylesheet = $this->result['destination_name']; |
527 switch_theme( $stylesheet ); |
577 switch_theme( $stylesheet ); |
528 } |
578 } |
529 |
579 |
530 //Time to remove maintenance mode |
580 //Time to remove maintenance mode |
531 if ( ! $this->bulk ) |
581 if ( ! $this->bulk ) { |
532 $this->maintenance_mode(false); |
582 $this->maintenance_mode( false ); |
|
583 } |
533 return $return; |
584 return $return; |
534 } |
585 } |
535 |
586 |
536 /** |
587 /** |
537 * Delete the old theme during an upgrade. |
588 * Delete the old theme during an upgrade. |
550 * @return bool |
601 * @return bool |
551 */ |
602 */ |
552 public function delete_old_theme( $removed, $local_destination, $remote_destination, $theme ) { |
603 public function delete_old_theme( $removed, $local_destination, $remote_destination, $theme ) { |
553 global $wp_filesystem; |
604 global $wp_filesystem; |
554 |
605 |
555 if ( is_wp_error( $removed ) ) |
606 if ( is_wp_error( $removed ) ) { |
556 return $removed; // Pass errors through. |
607 return $removed; // Pass errors through. |
557 |
608 } |
558 if ( ! isset( $theme['theme'] ) ) |
609 |
|
610 if ( ! isset( $theme['theme'] ) ) { |
559 return $removed; |
611 return $removed; |
560 |
612 } |
561 $theme = $theme['theme']; |
613 |
|
614 $theme = $theme['theme']; |
562 $themes_dir = trailingslashit( $wp_filesystem->wp_themes_dir( $theme ) ); |
615 $themes_dir = trailingslashit( $wp_filesystem->wp_themes_dir( $theme ) ); |
563 if ( $wp_filesystem->exists( $themes_dir . $theme ) ) { |
616 if ( $wp_filesystem->exists( $themes_dir . $theme ) ) { |
564 if ( ! $wp_filesystem->delete( $themes_dir . $theme, true ) ) |
617 if ( ! $wp_filesystem->delete( $themes_dir . $theme, true ) ) { |
565 return false; |
618 return false; |
|
619 } |
566 } |
620 } |
567 |
621 |
568 return true; |
622 return true; |
569 } |
623 } |
570 |
624 |
577 * @param string $theme The directory name of the theme. This is optional, and if not supplied, |
631 * @param string $theme The directory name of the theme. This is optional, and if not supplied, |
578 * the directory name from the last result will be used. |
632 * the directory name from the last result will be used. |
579 * @return WP_Theme|false The theme's info object, or false `$theme` is not supplied |
633 * @return WP_Theme|false The theme's info object, or false `$theme` is not supplied |
580 * and the last result isn't set. |
634 * and the last result isn't set. |
581 */ |
635 */ |
582 public function theme_info($theme = null) { |
636 public function theme_info( $theme = null ) { |
583 |
637 |
584 if ( empty($theme) ) { |
638 if ( empty( $theme ) ) { |
585 if ( !empty($this->result['destination_name']) ) |
639 if ( ! empty( $this->result['destination_name'] ) ) { |
586 $theme = $this->result['destination_name']; |
640 $theme = $this->result['destination_name']; |
587 else |
641 } else { |
588 return false; |
642 return false; |
|
643 } |
589 } |
644 } |
590 return wp_get_theme( $theme ); |
645 return wp_get_theme( $theme ); |
591 } |
646 } |
592 |
647 |
593 } |
648 } |