19 * @see WP_Upgrader |
19 * @see WP_Upgrader |
20 */ |
20 */ |
21 class Core_Upgrader extends WP_Upgrader { |
21 class Core_Upgrader extends WP_Upgrader { |
22 |
22 |
23 /** |
23 /** |
24 * Initialize the upgrade strings. |
24 * Initializes the upgrade strings. |
25 * |
25 * |
26 * @since 2.8.0 |
26 * @since 2.8.0 |
27 */ |
27 */ |
28 public function upgrade_strings() { |
28 public function upgrade_strings() { |
29 $this->strings['up_to_date'] = __( 'WordPress is at the latest version.' ); |
29 $this->strings['up_to_date'] = __( 'WordPress is at the latest version.' ); |
30 $this->strings['locked'] = __( 'Another update is currently in progress.' ); |
30 $this->strings['locked'] = __( 'Another update is currently in progress.' ); |
31 $this->strings['no_package'] = __( 'Update package not available.' ); |
31 $this->strings['no_package'] = __( 'Update package not available.' ); |
32 /* translators: %s: Package URL. */ |
32 /* translators: %s: Package URL. */ |
33 $this->strings['downloading_package'] = sprintf( __( 'Downloading update from %s…' ), '<span class="code">%s</span>' ); |
33 $this->strings['downloading_package'] = sprintf( __( 'Downloading update from %s…' ), '<span class="code pre">%s</span>' ); |
34 $this->strings['unpack_package'] = __( 'Unpacking the update…' ); |
34 $this->strings['unpack_package'] = __( 'Unpacking the update…' ); |
35 $this->strings['copy_failed'] = __( 'Could not copy files.' ); |
35 $this->strings['copy_failed'] = __( 'Could not copy files.' ); |
36 $this->strings['copy_failed_space'] = __( 'Could not copy files. You may have run out of disk space.' ); |
36 $this->strings['copy_failed_space'] = __( 'Could not copy files. You may have run out of disk space.' ); |
37 $this->strings['start_rollback'] = __( 'Attempting to roll back to previous version.' ); |
37 $this->strings['start_rollback'] = __( 'Attempting to restore the previous version.' ); |
38 $this->strings['rollback_was_required'] = __( 'Due to an error during updating, WordPress has rolled back to your previous version.' ); |
38 $this->strings['rollback_was_required'] = __( 'Due to an error during updating, WordPress has been restored to your previous version.' ); |
39 } |
39 } |
40 |
40 |
41 /** |
41 /** |
42 * Upgrade WordPress core. |
42 * Upgrades WordPress core. |
43 * |
43 * |
44 * @since 2.8.0 |
44 * @since 2.8.0 |
45 * |
45 * |
46 * @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass. |
46 * @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass. |
47 * @global callable $_wp_filesystem_direct_method |
47 * @global callable $_wp_filesystem_direct_method |
119 $lock = WP_Upgrader::create_lock( 'core_updater', 15 * MINUTE_IN_SECONDS ); |
119 $lock = WP_Upgrader::create_lock( 'core_updater', 15 * MINUTE_IN_SECONDS ); |
120 if ( ! $lock ) { |
120 if ( ! $lock ) { |
121 return new WP_Error( 'locked', $this->strings['locked'] ); |
121 return new WP_Error( 'locked', $this->strings['locked'] ); |
122 } |
122 } |
123 |
123 |
124 $download = $this->download_package( $current->packages->$to_download, true ); |
124 $download = $this->download_package( $current->packages->$to_download, false ); |
125 |
125 |
126 // Allow for signature soft-fail. |
126 /* |
127 // WARNING: This may be removed in the future. |
127 * Allow for signature soft-fail. |
|
128 * WARNING: This may be removed in the future. |
|
129 */ |
128 if ( is_wp_error( $download ) && $download->get_error_data( 'softfail-filename' ) ) { |
130 if ( is_wp_error( $download ) && $download->get_error_data( 'softfail-filename' ) ) { |
129 // Output the failure error as a normal feedback, and not as an error: |
131 // Output the failure error as a normal feedback, and not as an error: |
130 /** This filter is documented in wp-admin/includes/update-core.php */ |
132 /** This filter is documented in wp-admin/includes/update-core.php */ |
131 apply_filters( 'update_feedback', $download->get_error_message() ); |
133 apply_filters( 'update_feedback', $download->get_error_message() ); |
132 |
134 |
179 /* |
181 /* |
180 * Not all errors are equal. These codes are critical: copy_failed__copy_dir, |
182 * Not all errors are equal. These codes are critical: copy_failed__copy_dir, |
181 * mkdir_failed__copy_dir, copy_failed__copy_dir_retry, and disk_full. |
183 * mkdir_failed__copy_dir, copy_failed__copy_dir_retry, and disk_full. |
182 * do_rollback allows for update_core() to trigger a rollback if needed. |
184 * do_rollback allows for update_core() to trigger a rollback if needed. |
183 */ |
185 */ |
184 if ( false !== strpos( $error_code, 'do_rollback' ) ) { |
186 if ( str_contains( $error_code, 'do_rollback' ) ) { |
185 $try_rollback = true; |
187 $try_rollback = true; |
186 } elseif ( false !== strpos( $error_code, '__copy_dir' ) ) { |
188 } elseif ( str_contains( $error_code, '__copy_dir' ) ) { |
187 $try_rollback = true; |
189 $try_rollback = true; |
188 } elseif ( 'disk_full' === $error_code ) { |
190 } elseif ( 'disk_full' === $error_code ) { |
189 $try_rollback = true; |
191 $try_rollback = true; |
190 } |
192 } |
191 } |
193 } |
321 if ( ! empty( $failure_data['critical'] ) ) { |
323 if ( ! empty( $failure_data['critical'] ) ) { |
322 return false; |
324 return false; |
323 } |
325 } |
324 |
326 |
325 // Don't claim we can update on update-core.php if we have a non-critical failure logged. |
327 // Don't claim we can update on update-core.php if we have a non-critical failure logged. |
326 if ( $wp_version === $failure_data['current'] && false !== strpos( $offered_ver, '.1.next.minor' ) ) { |
328 if ( $wp_version === $failure_data['current'] && str_contains( $offered_ver, '.1.next.minor' ) ) { |
327 return false; |
329 return false; |
328 } |
330 } |
329 |
331 |
330 /* |
332 /* |
331 * Cannot update if we're retrying the same A to B update that caused a non-critical failure. |
333 * Cannot update if we're retrying the same A to B update that caused a non-critical failure. |
383 // If we're not sure, we don't want it. |
385 // If we're not sure, we don't want it. |
384 return false; |
386 return false; |
385 } |
387 } |
386 |
388 |
387 /** |
389 /** |
388 * Compare the disk file checksums against the expected checksums. |
390 * Compares the disk file checksums against the expected checksums. |
389 * |
391 * |
390 * @since 3.7.0 |
392 * @since 3.7.0 |
391 * |
393 * |
392 * @global string $wp_version The WordPress version string. |
394 * @global string $wp_version The WordPress version string. |
393 * @global string $wp_local_package Locale code of the package. |
395 * @global string $wp_local_package Locale code of the package. |
403 return false; |
405 return false; |
404 } |
406 } |
405 |
407 |
406 foreach ( $checksums as $file => $checksum ) { |
408 foreach ( $checksums as $file => $checksum ) { |
407 // Skip files which get updated. |
409 // Skip files which get updated. |
408 if ( 'wp-content' === substr( $file, 0, 10 ) ) { |
410 if ( str_starts_with( $file, 'wp-content' ) ) { |
409 continue; |
411 continue; |
410 } |
412 } |
411 if ( ! file_exists( ABSPATH . $file ) || md5_file( ABSPATH . $file ) !== $checksum ) { |
413 if ( ! file_exists( ABSPATH . $file ) || md5_file( ABSPATH . $file ) !== $checksum ) { |
412 return false; |
414 return false; |
413 } |
415 } |