run:R W Run
7.85 KB
2026-03-11 16:18:51
R W Run
3.54 KB
2026-03-11 16:18:51
R W Run
148.33 KB
2026-03-11 16:18:51
R W Run
11.45 KB
2026-03-11 16:18:51
R W Run
3.58 KB
2026-03-11 16:18:51
R W Run
2.53 KB
2026-03-11 16:18:51
R W Run
2.6 KB
2026-03-11 16:18:51
R W Run
6.59 KB
2026-03-11 16:18:51
R W Run
14.83 KB
2026-03-11 16:18:51
R W Run
21.18 KB
2026-03-11 16:18:51
R W Run
48.13 KB
2026-03-11 16:18:51
R W Run
4.07 KB
2026-03-11 16:18:51
R W Run
5.3 KB
2026-03-11 16:18:51
R W Run
8.28 KB
2026-03-11 16:18:51
R W Run
26.73 KB
2026-03-11 16:18:51
R W Run
2.8 KB
2026-03-11 16:18:51
R W Run
15.2 KB
2026-03-11 16:18:51
R W Run
192.08 KB
2026-03-11 16:18:51
R W Run
11.77 KB
2026-03-11 16:18:51
R W Run
3.2 KB
2026-03-11 16:18:51
R W Run
22.89 KB
2026-03-11 16:18:51
R W Run
12.77 KB
2026-03-11 16:18:51
R W Run
4.08 KB
2026-03-11 16:18:51
R W Run
26.27 KB
2026-03-11 16:18:51
R W Run
4.97 KB
2026-03-11 16:18:51
R W Run
5.57 KB
2026-03-11 16:18:51
R W Run
13.93 KB
2026-03-11 16:18:51
R W Run
4.09 KB
2026-03-11 16:18:51
R W Run
6.79 KB
2026-03-11 16:18:51
R W Run
60.45 KB
2026-03-11 16:18:51
R W Run
32.4 KB
2026-03-11 16:18:51
R W Run
18.24 KB
2026-03-11 16:18:51
R W Run
66.01 KB
2026-03-11 16:18:51
R W Run
23.84 KB
2026-03-11 16:18:51
R W Run
17.72 KB
2026-03-11 16:18:51
R W Run
22.71 KB
2026-03-11 16:18:51
R W Run
18.05 KB
2026-03-11 16:18:51
R W Run
22.76 KB
2026-03-11 16:18:51
R W Run
7.34 KB
2026-03-11 16:18:51
R W Run
4.51 KB
2026-03-11 16:18:51
R W Run
9.02 KB
2026-03-11 16:18:51
R W Run
1.46 KB
2026-03-11 16:18:51
R W Run
51.76 KB
2026-03-11 16:18:51
R W Run
25.29 KB
2026-03-11 16:18:51
R W Run
21.61 KB
2026-03-11 16:18:51
R W Run
27.77 KB
2026-03-11 16:18:51
R W Run
15.35 KB
2026-03-11 16:18:51
R W Run
24.54 KB
2026-03-11 16:18:51
R W Run
56.44 KB
2026-03-11 16:18:51
R W Run
1.42 KB
2026-03-11 16:18:51
R W Run
63.66 KB
2026-03-11 16:18:51
R W Run
31.9 KB
2026-03-11 16:18:51
R W Run
14.44 KB
2026-03-11 16:18:51
R W Run
36.47 KB
2026-03-11 16:18:51
R W Run
14 KB
2026-03-11 16:18:51
R W Run
121.89 KB
2026-03-11 16:18:51
R W Run
6.26 KB
2026-03-11 16:18:51
R W Run
20.73 KB
2026-03-11 16:18:51
R W Run
15.23 KB
2026-03-11 16:18:51
R W Run
10.14 KB
2026-03-11 16:18:51
R W Run
6.94 KB
2026-03-11 16:18:51
R W Run
1.44 KB
2026-03-11 16:18:51
R W Run
46.85 KB
2026-03-11 16:18:51
R W Run
18.61 KB
2026-03-11 16:18:51
R W Run
6.08 KB
2026-03-11 16:18:51
R W Run
20.06 KB
2026-03-11 16:18:51
R W Run
5.73 KB
2026-03-11 16:18:51
R W Run
68.18 KB
2026-03-11 16:18:51
R W Run
40.8 KB
2026-03-11 16:18:51
R W Run
1.44 KB
2026-03-11 16:18:51
R W Run
25.26 KB
2026-03-11 16:18:51
R W Run
95.94 KB
2026-03-11 16:18:51
R W Run
43.12 KB
2026-03-11 16:18:51
R W Run
41.73 KB
2026-03-11 16:18:51
R W Run
6.46 KB
2026-03-11 16:18:51
R W Run
3.71 KB
2026-03-11 16:18:51
R W Run
116.31 KB
2026-03-11 16:18:51
R W Run
9.39 KB
2026-03-11 16:18:51
R W Run
64.34 KB
2026-03-11 16:18:51
R W Run
44.73 KB
2026-03-11 16:18:51
R W Run
1.27 KB
2026-03-11 16:18:51
R W Run
3.68 KB
2026-03-11 16:18:51
R W Run
33.53 KB
2026-03-11 16:18:51
R W Run
48.84 KB
2026-03-11 16:18:51
R W Run
26.35 KB
2026-03-11 16:18:51
R W Run
1.12 KB
2026-03-11 16:18:51
R W Run
4.19 KB
2026-03-11 16:18:51
R W Run
38.19 KB
2026-03-11 16:18:51
R W Run
91.33 KB
2026-03-11 16:18:51
R W Run
80.39 KB
2026-03-11 16:18:51
R W Run
32.67 KB
2026-03-11 16:18:51
R W Run
16.18 KB
2026-03-11 16:18:51
R W Run
44.46 KB
2026-03-11 16:18:51
R W Run
6.23 KB
2026-03-11 16:18:51
R W Run
8.23 KB
2026-03-11 16:18:51
R W Run
96.96 KB
2026-03-11 16:18:51
R W Run
6.83 KB
2026-03-11 16:18:51
R W Run
46.62 KB
2026-03-11 16:18:51
R W Run
10.82 KB
2026-03-11 16:18:51
R W Run
68.86 KB
2026-03-11 16:18:51
R W Run
33.63 KB
2026-03-11 16:18:51
R W Run
113.3 KB
2026-03-11 16:18:51
R W Run
22.98 KB
2026-03-11 16:18:51
R W Run
10.66 KB
2026-03-11 16:18:51
R W Run
error_log
📄class-theme-upgrader.php
1<?php
2/**
3 * Upgrade API: Theme_Upgrader class
4 *
5 * @package WordPress
6 * @subpackage Upgrader
7 * @since 4.6.0
8 */
9
10/**
11 * Core class used for upgrading/installing themes.
12 *
13 * It is designed to upgrade/install themes from a local zip, remote zip URL,
14 * or uploaded zip file.
15 *
16 * @since 2.8.0
17 * @since 4.6.0 Moved to its own file from wp-admin/includes/class-wp-upgrader.php.
18 *
19 * @see WP_Upgrader
20 */
21class Theme_Upgrader extends WP_Upgrader {
22
23 /**
24 * Result of the theme upgrade offer.
25 *
26 * @since 2.8.0
27 * @var array|WP_Error $result
28 * @see WP_Upgrader::$result
29 */
30 public $result;
31
32 /**
33 * Whether multiple themes are being upgraded/installed in bulk.
34 *
35 * @since 2.9.0
36 * @var bool $bulk
37 */
38 public $bulk = false;
39
40 /**
41 * New theme info.
42 *
43 * @since 5.5.0
44 * @var array $new_theme_data
45 *
46 * @see check_package()
47 */
48 public $new_theme_data = array();
49
50 /**
51 * Initializes the upgrade strings.
52 *
53 * @since 2.8.0
54 */
55 public function upgrade_strings() {
56 $this->strings['up_to_date'] = __( 'The theme is at the latest version.' );
57 $this->strings['no_package'] = __( 'Update package not available.' );
58 /* translators: %s: Package URL. */
59 $this->strings['downloading_package'] = sprintf( __( 'Downloading update from %s&#8230;' ), '<span class="code pre">%s</span>' );
60 $this->strings['unpack_package'] = __( 'Unpacking the update&#8230;' );
61 $this->strings['remove_old'] = __( 'Removing the old version of the theme&#8230;' );
62 $this->strings['remove_old_failed'] = __( 'Could not remove the old theme.' );
63 $this->strings['process_failed'] = __( 'Theme update failed.' );
64 $this->strings['process_success'] = __( 'Theme updated successfully.' );
65 }
66
67 /**
68 * Initializes the installation strings.
69 *
70 * @since 2.8.0
71 */
72 public function install_strings() {
73 $this->strings['no_package'] = __( 'Installation package not available.' );
74 /* translators: %s: Package URL. */
75 $this->strings['downloading_package'] = sprintf( __( 'Downloading installation package from %s&#8230;' ), '<span class="code pre">%s</span>' );
76 $this->strings['unpack_package'] = __( 'Unpacking the package&#8230;' );
77 $this->strings['installing_package'] = __( 'Installing the theme&#8230;' );
78 $this->strings['remove_old'] = __( 'Removing the old version of the theme&#8230;' );
79 $this->strings['remove_old_failed'] = __( 'Could not remove the old theme.' );
80 $this->strings['no_files'] = __( 'The theme contains no files.' );
81 $this->strings['process_failed'] = __( 'Theme installation failed.' );
82 $this->strings['process_success'] = __( 'Theme installed successfully.' );
83 /* translators: 1: Theme name, 2: Theme version. */
84 $this->strings['process_success_specific'] = __( 'Successfully installed the theme <strong>%1$s %2$s</strong>.' );
85 $this->strings['parent_theme_search'] = __( 'This theme requires a parent theme. Checking if it is installed&#8230;' );
86 /* translators: 1: Theme name, 2: Theme version. */
87 $this->strings['parent_theme_prepare_install'] = __( 'Preparing to install <strong>%1$s %2$s</strong>&#8230;' );
88 /* translators: 1: Theme name, 2: Theme version. */
89 $this->strings['parent_theme_currently_installed'] = __( 'The parent theme, <strong>%1$s %2$s</strong>, is currently installed.' );
90 /* translators: 1: Theme name, 2: Theme version. */
91 $this->strings['parent_theme_install_success'] = __( 'Successfully installed the parent theme, <strong>%1$s %2$s</strong>.' );
92 /* translators: %s: Theme name. */
93 $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>' );
94 /* translators: %s: Theme error. */
95 $this->strings['current_theme_has_errors'] = __( 'The active theme has the following error: "%s".' );
96
97 if ( ! empty( $this->skin->overwrite ) ) {
98 if ( 'update-theme' === $this->skin->overwrite ) {
99 $this->strings['installing_package'] = __( 'Updating the theme&#8230;' );
100 $this->strings['process_failed'] = __( 'Theme update failed.' );
101 $this->strings['process_success'] = __( 'Theme updated successfully.' );
102 }
103
104 if ( 'downgrade-theme' === $this->skin->overwrite ) {
105 $this->strings['installing_package'] = __( 'Downgrading the theme&#8230;' );
106 $this->strings['process_failed'] = __( 'Theme downgrade failed.' );
107 $this->strings['process_success'] = __( 'Theme downgraded successfully.' );
108 }
109 }
110 }
111
112 /**
113 * Checks if a child theme is being installed and its parent also needs to be installed.
114 *
115 * Hooked to the {@see 'upgrader_post_install'} filter by Theme_Upgrader::install().
116 *
117 * @since 3.4.0
118 *
119 * @param bool $install_result
120 * @param array $hook_extra
121 * @param array $child_result
122 * @return bool
123 */
124 public function check_parent_theme_filter( $install_result, $hook_extra, $child_result ) {
125 // Check to see if we need to install a parent theme.
126 $theme_info = $this->theme_info();
127
128 if ( ! $theme_info->parent() ) {
129 return $install_result;
130 }
131
132 $this->skin->feedback( 'parent_theme_search' );
133
134 if ( ! $theme_info->parent()->errors() ) {
135 $this->skin->feedback( 'parent_theme_currently_installed', $theme_info->parent()->display( 'Name' ), $theme_info->parent()->display( 'Version' ) );
136 // We already have the theme, fall through.
137 return $install_result;
138 }
139
140 // We don't have the parent theme, let's install it.
141 $api = themes_api(
142 'theme_information',
143 array(
144 'slug' => $theme_info->get( 'Template' ),
145 'fields' => array(
146 'sections' => false,
147 'tags' => false,
148 ),
149 )
150 ); // Save on a bit of bandwidth.
151
152 if ( ! $api || is_wp_error( $api ) ) {
153 $this->skin->feedback( 'parent_theme_not_found', $theme_info->get( 'Template' ) );
154 // Don't show activate or preview actions after installation.
155 add_filter( 'install_theme_complete_actions', array( $this, 'hide_activate_preview_actions' ) );
156 return $install_result;
157 }
158
159 // Backup required data we're going to override:
160 $child_api = $this->skin->api;
161 $child_success_message = $this->strings['process_success'];
162
163 // Override them.
164 $this->skin->api = $api;
165
166 $this->strings['process_success_specific'] = $this->strings['parent_theme_install_success'];
167
168 $this->skin->feedback( 'parent_theme_prepare_install', $api->name, $api->version );
169
170 add_filter( 'install_theme_complete_actions', '__return_false', 999 ); // Don't show any actions after installing the theme.
171
172 // Install the parent theme.
173 $parent_result = $this->run(
174 array(
175 'package' => $api->download_link,
176 'destination' => get_theme_root(),
177 'clear_destination' => false, // Do not overwrite files.
178 'clear_working' => true,
179 )
180 );
181
182 if ( is_wp_error( $parent_result ) ) {
183 add_filter( 'install_theme_complete_actions', array( $this, 'hide_activate_preview_actions' ) );
184 }
185
186 // Start cleaning up after the parent's installation.
187 remove_filter( 'install_theme_complete_actions', '__return_false', 999 );
188
189 // Reset child's result and data.
190 $this->result = $child_result;
191 $this->skin->api = $child_api;
192 $this->strings['process_success'] = $child_success_message;
193
194 return $install_result;
195 }
196
197 /**
198 * Don't display the activate and preview actions to the user.
199 *
200 * Hooked to the {@see 'install_theme_complete_actions'} filter by
201 * Theme_Upgrader::check_parent_theme_filter() when installing
202 * a child theme and installing the parent theme fails.
203 *
204 * @since 3.4.0
205 *
206 * @param array $actions Preview actions.
207 * @return array
208 */
209 public function hide_activate_preview_actions( $actions ) {
210 unset( $actions['activate'], $actions['preview'] );
211 return $actions;
212 }
213
214 /**
215 * Install a theme package.
216 *
217 * @since 2.8.0
218 * @since 3.7.0 The `$args` parameter was added, making clearing the update cache optional.
219 *
220 * @param string $package The full local path or URI of the package.
221 * @param array $args {
222 * Optional. Other arguments for installing a theme package. Default empty array.
223 *
224 * @type bool $clear_update_cache Whether to clear the updates cache if successful.
225 * Default true.
226 * }
227 *
228 * @return bool|WP_Error True if the installation was successful, false or a WP_Error object otherwise.
229 */
230 public function install( $package, $args = array() ) {
231 $defaults = array(
232 'clear_update_cache' => true,
233 'overwrite_package' => false, // Do not overwrite files.
234 );
235 $parsed_args = wp_parse_args( $args, $defaults );
236
237 $this->init();
238 $this->install_strings();
239
240 add_filter( 'upgrader_source_selection', array( $this, 'check_package' ) );
241 add_filter( 'upgrader_post_install', array( $this, 'check_parent_theme_filter' ), 10, 3 );
242
243 if ( $parsed_args['clear_update_cache'] ) {
244 // Clear cache so wp_update_themes() knows about the new theme.
245 add_action( 'upgrader_process_complete', 'wp_clean_themes_cache', 9, 0 );
246 }
247
248 $this->run(
249 array(
250 'package' => $package,
251 'destination' => get_theme_root(),
252 'clear_destination' => $parsed_args['overwrite_package'],
253 'clear_working' => true,
254 'hook_extra' => array(
255 'type' => 'theme',
256 'action' => 'install',
257 ),
258 )
259 );
260
261 remove_action( 'upgrader_process_complete', 'wp_clean_themes_cache', 9 );
262 remove_filter( 'upgrader_source_selection', array( $this, 'check_package' ) );
263 remove_filter( 'upgrader_post_install', array( $this, 'check_parent_theme_filter' ) );
264
265 if ( ! $this->result || is_wp_error( $this->result ) ) {
266 return $this->result;
267 }
268
269 // Refresh the Theme Update information.
270 wp_clean_themes_cache( $parsed_args['clear_update_cache'] );
271
272 if ( $parsed_args['overwrite_package'] ) {
273 /** This action is documented in wp-admin/includes/class-plugin-upgrader.php */
274 do_action( 'upgrader_overwrote_package', $package, $this->new_theme_data, 'theme' );
275 }
276
277 return true;
278 }
279
280 /**
281 * Upgrades a theme.
282 *
283 * @since 2.8.0
284 * @since 3.7.0 The `$args` parameter was added, making clearing the update cache optional.
285 *
286 * @param string $theme The theme slug.
287 * @param array $args {
288 * Optional. Other arguments for upgrading a theme. Default empty array.
289 *
290 * @type bool $clear_update_cache Whether to clear the update cache if successful.
291 * Default true.
292 * }
293 * @return bool|WP_Error True if the upgrade was successful, false or a WP_Error object otherwise.
294 */
295 public function upgrade( $theme, $args = array() ) {
296 $defaults = array(
297 'clear_update_cache' => true,
298 );
299 $parsed_args = wp_parse_args( $args, $defaults );
300
301 $this->init();
302 $this->upgrade_strings();
303
304 // Is an update available?
305 $current = get_site_transient( 'update_themes' );
306 if ( ! isset( $current->response[ $theme ] ) ) {
307 $this->skin->before();
308 $this->skin->set_result( false );
309 $this->skin->error( 'up_to_date' );
310 $this->skin->after();
311 return false;
312 }
313
314 $upgrade_data = $current->response[ $theme ];
315
316 add_filter( 'upgrader_pre_install', array( $this, 'current_before' ), 10, 2 );
317 add_filter( 'upgrader_post_install', array( $this, 'current_after' ), 10, 2 );
318 add_filter( 'upgrader_clear_destination', array( $this, 'delete_old_theme' ), 10, 4 );
319 if ( $parsed_args['clear_update_cache'] ) {
320 // Clear cache so wp_update_themes() knows about the new theme.
321 add_action( 'upgrader_process_complete', 'wp_clean_themes_cache', 9, 0 );
322 }
323
324 $this->run(
325 array(
326 'package' => $upgrade_data['package'],
327 'destination' => get_theme_root( $theme ),
328 'clear_destination' => true,
329 'clear_working' => true,
330 'hook_extra' => array(
331 'theme' => $theme,
332 'type' => 'theme',
333 'action' => 'update',
334 'temp_backup' => array(
335 'slug' => $theme,
336 'src' => get_theme_root( $theme ),
337 'dir' => 'themes',
338 ),
339 ),
340 )
341 );
342
343 remove_action( 'upgrader_process_complete', 'wp_clean_themes_cache', 9 );
344 remove_filter( 'upgrader_pre_install', array( $this, 'current_before' ) );
345 remove_filter( 'upgrader_post_install', array( $this, 'current_after' ) );
346 remove_filter( 'upgrader_clear_destination', array( $this, 'delete_old_theme' ) );
347
348 if ( ! $this->result || is_wp_error( $this->result ) ) {
349 return $this->result;
350 }
351
352 wp_clean_themes_cache( $parsed_args['clear_update_cache'] );
353
354 /*
355 * Ensure any future auto-update failures trigger a failure email by removing
356 * the last failure notification from the list when themes update successfully.
357 */
358 $past_failure_emails = get_option( 'auto_plugin_theme_update_emails', array() );
359
360 if ( isset( $past_failure_emails[ $theme ] ) ) {
361 unset( $past_failure_emails[ $theme ] );
362 update_option( 'auto_plugin_theme_update_emails', $past_failure_emails );
363 }
364
365 return true;
366 }
367
368 /**
369 * Upgrades several themes at once.
370 *
371 * @since 3.0.0
372 * @since 3.7.0 The `$args` parameter was added, making clearing the update cache optional.
373 *
374 * @param string[] $themes Array of the theme slugs.
375 * @param array $args {
376 * Optional. Other arguments for upgrading several themes at once. Default empty array.
377 *
378 * @type bool $clear_update_cache Whether to clear the update cache if successful.
379 * Default true.
380 * }
381 * @return array[]|false An array of results, or false if unable to connect to the filesystem.
382 */
383 public function bulk_upgrade( $themes, $args = array() ) {
384 $wp_version = wp_get_wp_version();
385 $defaults = array(
386 'clear_update_cache' => true,
387 );
388 $parsed_args = wp_parse_args( $args, $defaults );
389
390 $this->init();
391 $this->bulk = true;
392 $this->upgrade_strings();
393
394 $current = get_site_transient( 'update_themes' );
395
396 add_filter( 'upgrader_pre_install', array( $this, 'current_before' ), 10, 2 );
397 add_filter( 'upgrader_post_install', array( $this, 'current_after' ), 10, 2 );
398 add_filter( 'upgrader_clear_destination', array( $this, 'delete_old_theme' ), 10, 4 );
399
400 $this->skin->header();
401
402 // Connect to the filesystem first.
403 $connected = $this->fs_connect( array( WP_CONTENT_DIR ) );
404 if ( ! $connected ) {
405 $this->skin->footer();
406 return false;
407 }
408
409 $this->skin->bulk_header();
410
411 /*
412 * Only start maintenance mode if:
413 * - running Multisite and there are one or more themes specified, OR
414 * - a theme with an update available is currently in use.
415 * @todo For multisite, maintenance mode should only kick in for individual sites if at all possible.
416 */
417 $maintenance = ( is_multisite() && ! empty( $themes ) );
418 foreach ( $themes as $theme ) {
419 $maintenance = $maintenance || get_stylesheet() === $theme || get_template() === $theme;
420 }
421 if ( $maintenance ) {
422 $this->maintenance_mode( true );
423 }
424
425 $results = array();
426
427 $this->update_count = count( $themes );
428 $this->update_current = 0;
429 foreach ( $themes as $theme ) {
430 ++$this->update_current;
431
432 $this->skin->theme_info = $this->theme_info( $theme );
433
434 if ( ! isset( $current->response[ $theme ] ) ) {
435 $this->skin->set_result( true );
436 $this->skin->before();
437 $this->skin->feedback( 'up_to_date' );
438 $this->skin->after();
439 $results[ $theme ] = true;
440 continue;
441 }
442
443 // Get the URL to the zip file.
444 $upgrade_data = $current->response[ $theme ];
445
446 if ( isset( $upgrade_data['requires'] ) && ! is_wp_version_compatible( $upgrade_data['requires'] ) ) {
447 $result = new WP_Error(
448 'incompatible_wp_required_version',
449 sprintf(
450 /* translators: 1: Current WordPress version, 2: WordPress version required by the new theme version. */
451 __( 'Your WordPress version is %1$s, however the new theme version requires %2$s.' ),
452 $wp_version,
453 $upgrade_data['requires']
454 )
455 );
456
457 $this->skin->before( $result );
458 $this->skin->error( $result );
459 $this->skin->after();
460 } elseif ( isset( $upgrade_data['requires_php'] ) && ! is_php_version_compatible( $upgrade_data['requires_php'] ) ) {
461 $result = new WP_Error(
462 'incompatible_php_required_version',
463 sprintf(
464 /* translators: 1: Current PHP version, 2: PHP version required by the new theme version. */
465 __( 'The PHP version on your server is %1$s, however the new theme version requires %2$s.' ),
466 PHP_VERSION,
467 $upgrade_data['requires_php']
468 )
469 );
470
471 $this->skin->before( $result );
472 $this->skin->error( $result );
473 $this->skin->after();
474 } else {
475 add_filter( 'upgrader_source_selection', array( $this, 'check_package' ) );
476 $result = $this->run(
477 array(
478 'package' => $upgrade_data['package'],
479 'destination' => get_theme_root( $theme ),
480 'clear_destination' => true,
481 'clear_working' => true,
482 'is_multi' => true,
483 'hook_extra' => array(
484 'theme' => $theme,
485 'temp_backup' => array(
486 'slug' => $theme,
487 'src' => get_theme_root( $theme ),
488 'dir' => 'themes',
489 ),
490 ),
491 )
492 );
493 remove_filter( 'upgrader_source_selection', array( $this, 'check_package' ) );
494 }
495
496 $results[ $theme ] = $result;
497
498 // Prevent credentials auth screen from displaying multiple times.
499 if ( false === $result ) {
500 break;
501 }
502 } // End foreach $themes.
503
504 $this->maintenance_mode( false );
505
506 // Refresh the Theme Update information.
507 wp_clean_themes_cache( $parsed_args['clear_update_cache'] );
508
509 /** This action is documented in wp-admin/includes/class-wp-upgrader.php */
510 do_action(
511 'upgrader_process_complete',
512 $this,
513 array(
514 'action' => 'update',
515 'type' => 'theme',
516 'bulk' => true,
517 'themes' => $themes,
518 )
519 );
520
521 $this->skin->bulk_footer();
522
523 $this->skin->footer();
524
525 // Cleanup our hooks, in case something else does an upgrade on this connection.
526 remove_filter( 'upgrader_pre_install', array( $this, 'current_before' ) );
527 remove_filter( 'upgrader_post_install', array( $this, 'current_after' ) );
528 remove_filter( 'upgrader_clear_destination', array( $this, 'delete_old_theme' ) );
529
530 /*
531 * Ensure any future auto-update failures trigger a failure email by removing
532 * the last failure notification from the list when themes update successfully.
533 */
534 $past_failure_emails = get_option( 'auto_plugin_theme_update_emails', array() );
535
536 foreach ( $results as $theme => $result ) {
537 // Maintain last failure notification when themes failed to update manually.
538 if ( ! $result || is_wp_error( $result ) || ! isset( $past_failure_emails[ $theme ] ) ) {
539 continue;
540 }
541
542 unset( $past_failure_emails[ $theme ] );
543 }
544
545 update_option( 'auto_plugin_theme_update_emails', $past_failure_emails );
546
547 return $results;
548 }
549
550 /**
551 * Checks that the package source contains a valid theme.
552 *
553 * Hooked to the {@see 'upgrader_source_selection'} filter by Theme_Upgrader::install().
554 *
555 * @since 3.3.0
556 *
557 * @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass.
558 *
559 * @param string $source The path to the downloaded package source.
560 * @return string|WP_Error The source as passed, or a WP_Error object on failure.
561 */
562 public function check_package( $source ) {
563 global $wp_filesystem;
564
565 $wp_version = wp_get_wp_version();
566 $this->new_theme_data = array();
567
568 if ( is_wp_error( $source ) ) {
569 return $source;
570 }
571
572 // Check that the folder contains a valid theme.
573 $working_directory = str_replace( $wp_filesystem->wp_content_dir(), trailingslashit( WP_CONTENT_DIR ), $source );
574 if ( ! is_dir( $working_directory ) ) { // Confidence check, if the above fails, let's not prevent installation.
575 return $source;
576 }
577
578 // A proper archive should have a style.css file in the single subdirectory.
579 if ( ! file_exists( $working_directory . 'style.css' ) ) {
580 return new WP_Error(
581 'incompatible_archive_theme_no_style',
582 $this->strings['incompatible_archive'],
583 sprintf(
584 /* translators: %s: style.css */
585 __( 'The theme is missing the %s stylesheet.' ),
586 '<code>style.css</code>'
587 )
588 );
589 }
590
591 // All these headers are needed on Theme_Installer_Skin::do_overwrite().
592 $new_theme_data = get_file_data(
593 $working_directory . 'style.css',
594 array(
595 'Name' => 'Theme Name',
596 'Version' => 'Version',
597 'Author' => 'Author',
598 'Template' => 'Template',
599 'RequiresWP' => 'Requires at least',
600 'RequiresPHP' => 'Requires PHP',
601 )
602 );
603
604 if ( empty( $new_theme_data['Name'] ) ) {
605 return new WP_Error(
606 'incompatible_archive_theme_no_name',
607 $this->strings['incompatible_archive'],
608 sprintf(
609 /* translators: %s: style.css */
610 __( 'The %s stylesheet does not contain a valid theme header.' ),
611 '<code>style.css</code>'
612 )
613 );
614 }
615
616 /*
617 * Parent themes must contain an index file:
618 * - classic themes require /index.php
619 * - block themes require /templates/index.html or block-templates/index.html (deprecated 5.9.0).
620 */
621 if (
622 empty( $new_theme_data['Template'] ) &&
623 ! file_exists( $working_directory . 'index.php' ) &&
624 ! file_exists( $working_directory . 'templates/index.html' ) &&
625 ! file_exists( $working_directory . 'block-templates/index.html' )
626 ) {
627 return new WP_Error(
628 'incompatible_archive_theme_no_index',
629 $this->strings['incompatible_archive'],
630 sprintf(
631 /* translators: 1: templates/index.html, 2: index.php, 3: Documentation URL, 4: Template, 5: style.css */
632 __( 'Template is missing. Standalone themes need to have a %1$s or %2$s template file. <a href="%3$s">Child themes</a> need to have a %4$s header in the %5$s stylesheet.' ),
633 '<code>templates/index.html</code>',
634 '<code>index.php</code>',
635 __( 'https://developer.wordpress.org/themes/advanced-topics/child-themes/' ),
636 '<code>Template</code>',
637 '<code>style.css</code>'
638 )
639 );
640 }
641
642 $requires_php = isset( $new_theme_data['RequiresPHP'] ) ? $new_theme_data['RequiresPHP'] : null;
643 $requires_wp = isset( $new_theme_data['RequiresWP'] ) ? $new_theme_data['RequiresWP'] : null;
644
645 if ( ! is_php_version_compatible( $requires_php ) ) {
646 $error = sprintf(
647 /* translators: 1: Current PHP version, 2: Version required by the uploaded theme. */
648 __( 'The PHP version on your server is %1$s, however the uploaded theme requires %2$s.' ),
649 PHP_VERSION,
650 $requires_php
651 );
652
653 return new WP_Error( 'incompatible_php_required_version', $this->strings['incompatible_archive'], $error );
654 }
655 if ( ! is_wp_version_compatible( $requires_wp ) ) {
656 $error = sprintf(
657 /* translators: 1: Current WordPress version, 2: Version required by the uploaded theme. */
658 __( 'Your WordPress version is %1$s, however the uploaded theme requires %2$s.' ),
659 $wp_version,
660 $requires_wp
661 );
662
663 return new WP_Error( 'incompatible_wp_required_version', $this->strings['incompatible_archive'], $error );
664 }
665
666 $this->new_theme_data = $new_theme_data;
667
668 return $source;
669 }
670
671 /**
672 * Turns on maintenance mode before attempting to upgrade the active theme.
673 *
674 * Hooked to the {@see 'upgrader_pre_install'} filter by Theme_Upgrader::upgrade() and
675 * Theme_Upgrader::bulk_upgrade().
676 *
677 * @since 2.8.0
678 *
679 * @param bool|WP_Error $response The installation response before the installation has started.
680 * @param array $theme Theme arguments.
681 * @return bool|WP_Error The original `$response` parameter or WP_Error.
682 */
683 public function current_before( $response, $theme ) {
684 if ( is_wp_error( $response ) ) {
685 return $response;
686 }
687
688 $theme = isset( $theme['theme'] ) ? $theme['theme'] : '';
689
690 // Only run if active theme.
691 if ( get_stylesheet() !== $theme ) {
692 return $response;
693 }
694
695 // Change to maintenance mode. Bulk edit handles this separately.
696 if ( ! $this->bulk ) {
697 $this->maintenance_mode( true );
698 }
699
700 return $response;
701 }
702
703 /**
704 * Turns off maintenance mode after upgrading the active theme.
705 *
706 * Hooked to the {@see 'upgrader_post_install'} filter by Theme_Upgrader::upgrade()
707 * and Theme_Upgrader::bulk_upgrade().
708 *
709 * @since 2.8.0
710 *
711 * @param bool|WP_Error $response The installation response after the installation has finished.
712 * @param array $theme Theme arguments.
713 * @return bool|WP_Error The original `$response` parameter or WP_Error.
714 */
715 public function current_after( $response, $theme ) {
716 if ( is_wp_error( $response ) ) {
717 return $response;
718 }
719
720 $theme = isset( $theme['theme'] ) ? $theme['theme'] : '';
721
722 // Only run if active theme.
723 if ( get_stylesheet() !== $theme ) {
724 return $response;
725 }
726
727 // Ensure stylesheet name hasn't changed after the upgrade:
728 if ( get_stylesheet() === $theme && $theme !== $this->result['destination_name'] ) {
729 wp_clean_themes_cache();
730 $stylesheet = $this->result['destination_name'];
731 switch_theme( $stylesheet );
732 }
733
734 // Time to remove maintenance mode. Bulk edit handles this separately.
735 if ( ! $this->bulk ) {
736 $this->maintenance_mode( false );
737 }
738 return $response;
739 }
740
741 /**
742 * Deletes the old theme during an upgrade.
743 *
744 * Hooked to the {@see 'upgrader_clear_destination'} filter by Theme_Upgrader::upgrade()
745 * and Theme_Upgrader::bulk_upgrade().
746 *
747 * @since 2.8.0
748 *
749 * @global WP_Filesystem_Base $wp_filesystem Subclass
750 *
751 * @param bool $removed
752 * @param string $local_destination
753 * @param string $remote_destination
754 * @param array $theme
755 * @return bool
756 */
757 public function delete_old_theme( $removed, $local_destination, $remote_destination, $theme ) {
758 global $wp_filesystem;
759
760 if ( is_wp_error( $removed ) ) {
761 return $removed; // Pass errors through.
762 }
763
764 if ( ! isset( $theme['theme'] ) ) {
765 return $removed;
766 }
767
768 $theme = $theme['theme'];
769 $themes_dir = trailingslashit( $wp_filesystem->wp_themes_dir( $theme ) );
770 if ( $wp_filesystem->exists( $themes_dir . $theme ) ) {
771 if ( ! $wp_filesystem->delete( $themes_dir . $theme, true ) ) {
772 return false;
773 }
774 }
775
776 return true;
777 }
778
779 /**
780 * Gets the WP_Theme object for a theme.
781 *
782 * @since 2.8.0
783 * @since 3.0.0 The `$theme` argument was added.
784 *
785 * @param string $theme The directory name of the theme. This is optional, and if not supplied,
786 * the directory name from the last result will be used.
787 * @return WP_Theme|false The theme's info object, or false `$theme` is not supplied
788 * and the last result isn't set.
789 */
790 public function theme_info( $theme = null ) {
791 if ( empty( $theme ) ) {
792 if ( ! empty( $this->result['destination_name'] ) ) {
793 $theme = $this->result['destination_name'];
794 } else {
795 return false;
796 }
797 }
798
799 $theme = wp_get_theme( $theme );
800 $theme->cache_delete();
801
802 return $theme;
803 }
804}
805
Ui Ux Design – Teachers Night Out

Get in Touch

© 2024 Teachers Night Out. All Rights Reserved.