133 * and also add the generic strings to `WP_Upgrader::$strings`. |
134 * and also add the generic strings to `WP_Upgrader::$strings`. |
134 * |
135 * |
135 * @since 2.8.0 |
136 * @since 2.8.0 |
136 */ |
137 */ |
137 public function init() { |
138 public function init() { |
138 $this->skin->set_upgrader($this); |
139 $this->skin->set_upgrader( $this ); |
139 $this->generic_strings(); |
140 $this->generic_strings(); |
140 } |
141 } |
141 |
142 |
142 /** |
143 /** |
143 * Add the generic strings to WP_Upgrader::$strings. |
144 * Add the generic strings to WP_Upgrader::$strings. |
144 * |
145 * |
145 * @since 2.8.0 |
146 * @since 2.8.0 |
146 */ |
147 */ |
147 public function generic_strings() { |
148 public function generic_strings() { |
148 $this->strings['bad_request'] = __('Invalid data provided.'); |
149 $this->strings['bad_request'] = __( 'Invalid data provided.' ); |
149 $this->strings['fs_unavailable'] = __('Could not access filesystem.'); |
150 $this->strings['fs_unavailable'] = __( 'Could not access filesystem.' ); |
150 $this->strings['fs_error'] = __('Filesystem error.'); |
151 $this->strings['fs_error'] = __( 'Filesystem error.' ); |
151 $this->strings['fs_no_root_dir'] = __('Unable to locate WordPress root directory.'); |
152 $this->strings['fs_no_root_dir'] = __( 'Unable to locate WordPress root directory.' ); |
152 $this->strings['fs_no_content_dir'] = __('Unable to locate WordPress content directory (wp-content).'); |
153 $this->strings['fs_no_content_dir'] = __( 'Unable to locate WordPress content directory (wp-content).' ); |
153 $this->strings['fs_no_plugins_dir'] = __('Unable to locate WordPress plugin directory.'); |
154 $this->strings['fs_no_plugins_dir'] = __( 'Unable to locate WordPress plugin directory.' ); |
154 $this->strings['fs_no_themes_dir'] = __('Unable to locate WordPress theme directory.'); |
155 $this->strings['fs_no_themes_dir'] = __( 'Unable to locate WordPress theme directory.' ); |
155 /* translators: %s: directory name */ |
156 /* translators: %s: directory name */ |
156 $this->strings['fs_no_folder'] = __('Unable to locate needed folder (%s).'); |
157 $this->strings['fs_no_folder'] = __( 'Unable to locate needed folder (%s).' ); |
157 |
158 |
158 $this->strings['download_failed'] = __('Download failed.'); |
159 $this->strings['download_failed'] = __( 'Download failed.' ); |
159 $this->strings['installing_package'] = __('Installing the latest version…'); |
160 $this->strings['installing_package'] = __( 'Installing the latest version…' ); |
160 $this->strings['no_files'] = __('The package contains no files.'); |
161 $this->strings['no_files'] = __( 'The package contains no files.' ); |
161 $this->strings['folder_exists'] = __('Destination folder already exists.'); |
162 $this->strings['folder_exists'] = __( 'Destination folder already exists.' ); |
162 $this->strings['mkdir_failed'] = __('Could not create directory.'); |
163 $this->strings['mkdir_failed'] = __( 'Could not create directory.' ); |
163 $this->strings['incompatible_archive'] = __('The package could not be installed.'); |
164 $this->strings['incompatible_archive'] = __( 'The package could not be installed.' ); |
164 $this->strings['files_not_writable'] = __( 'The update cannot be installed because we will be unable to copy some files. This is usually due to inconsistent file permissions.' ); |
165 $this->strings['files_not_writable'] = __( 'The update cannot be installed because we will be unable to copy some files. This is usually due to inconsistent file permissions.' ); |
165 |
166 |
166 $this->strings['maintenance_start'] = __('Enabling Maintenance mode…'); |
167 $this->strings['maintenance_start'] = __( 'Enabling Maintenance mode…' ); |
167 $this->strings['maintenance_end'] = __('Disabling Maintenance mode…'); |
168 $this->strings['maintenance_end'] = __( 'Disabling Maintenance mode…' ); |
168 } |
169 } |
169 |
170 |
170 /** |
171 /** |
171 * Connect to the filesystem. |
172 * Connect to the filesystem. |
172 * |
173 * |
173 * @since 2.8.0 |
174 * @since 2.8.0 |
174 * |
175 * |
175 * @global WP_Filesystem_Base $wp_filesystem Subclass |
176 * @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass. |
176 * |
177 * |
177 * @param array $directories Optional. A list of directories. If any of these do |
178 * @param array $directories Optional. A list of directories. If any of these do |
178 * not exist, a WP_Error object will be returned. |
179 * not exist, a WP_Error object will be returned. |
179 * Default empty array. |
180 * Default empty array. |
180 * @param bool $allow_relaxed_file_ownership Whether to allow relaxed file ownership. |
181 * @param bool $allow_relaxed_file_ownership Whether to allow relaxed file ownership. |
188 return false; |
189 return false; |
189 } |
190 } |
190 |
191 |
191 if ( ! WP_Filesystem( $credentials, $directories[0], $allow_relaxed_file_ownership ) ) { |
192 if ( ! WP_Filesystem( $credentials, $directories[0], $allow_relaxed_file_ownership ) ) { |
192 $error = true; |
193 $error = true; |
193 if ( is_object($wp_filesystem) && $wp_filesystem->errors->get_error_code() ) |
194 if ( is_object( $wp_filesystem ) && $wp_filesystem->errors->has_errors() ) { |
194 $error = $wp_filesystem->errors; |
195 $error = $wp_filesystem->errors; |
|
196 } |
195 // Failed to connect, Error and request again |
197 // Failed to connect, Error and request again |
196 $this->skin->request_filesystem_credentials( $error, $directories[0], $allow_relaxed_file_ownership ); |
198 $this->skin->request_filesystem_credentials( $error, $directories[0], $allow_relaxed_file_ownership ); |
197 return false; |
199 return false; |
198 } |
200 } |
199 |
201 |
200 if ( ! is_object($wp_filesystem) ) |
202 if ( ! is_object( $wp_filesystem ) ) { |
201 return new WP_Error('fs_unavailable', $this->strings['fs_unavailable'] ); |
203 return new WP_Error( 'fs_unavailable', $this->strings['fs_unavailable'] ); |
202 |
204 } |
203 if ( is_wp_error($wp_filesystem->errors) && $wp_filesystem->errors->get_error_code() ) |
205 |
204 return new WP_Error('fs_error', $this->strings['fs_error'], $wp_filesystem->errors); |
206 if ( is_wp_error( $wp_filesystem->errors ) && $wp_filesystem->errors->has_errors() ) { |
205 |
207 return new WP_Error( 'fs_error', $this->strings['fs_error'], $wp_filesystem->errors ); |
206 foreach ( (array)$directories as $dir ) { |
208 } |
|
209 |
|
210 foreach ( (array) $directories as $dir ) { |
207 switch ( $dir ) { |
211 switch ( $dir ) { |
208 case ABSPATH: |
212 case ABSPATH: |
209 if ( ! $wp_filesystem->abspath() ) |
213 if ( ! $wp_filesystem->abspath() ) { |
210 return new WP_Error('fs_no_root_dir', $this->strings['fs_no_root_dir']); |
214 return new WP_Error( 'fs_no_root_dir', $this->strings['fs_no_root_dir'] ); |
|
215 } |
211 break; |
216 break; |
212 case WP_CONTENT_DIR: |
217 case WP_CONTENT_DIR: |
213 if ( ! $wp_filesystem->wp_content_dir() ) |
218 if ( ! $wp_filesystem->wp_content_dir() ) { |
214 return new WP_Error('fs_no_content_dir', $this->strings['fs_no_content_dir']); |
219 return new WP_Error( 'fs_no_content_dir', $this->strings['fs_no_content_dir'] ); |
|
220 } |
215 break; |
221 break; |
216 case WP_PLUGIN_DIR: |
222 case WP_PLUGIN_DIR: |
217 if ( ! $wp_filesystem->wp_plugins_dir() ) |
223 if ( ! $wp_filesystem->wp_plugins_dir() ) { |
218 return new WP_Error('fs_no_plugins_dir', $this->strings['fs_no_plugins_dir']); |
224 return new WP_Error( 'fs_no_plugins_dir', $this->strings['fs_no_plugins_dir'] ); |
|
225 } |
219 break; |
226 break; |
220 case get_theme_root(): |
227 case get_theme_root(): |
221 if ( ! $wp_filesystem->wp_themes_dir() ) |
228 if ( ! $wp_filesystem->wp_themes_dir() ) { |
222 return new WP_Error('fs_no_themes_dir', $this->strings['fs_no_themes_dir']); |
229 return new WP_Error( 'fs_no_themes_dir', $this->strings['fs_no_themes_dir'] ); |
|
230 } |
223 break; |
231 break; |
224 default: |
232 default: |
225 if ( ! $wp_filesystem->find_folder($dir) ) |
233 if ( ! $wp_filesystem->find_folder( $dir ) ) { |
226 return new WP_Error( 'fs_no_folder', sprintf( $this->strings['fs_no_folder'], esc_html( basename( $dir ) ) ) ); |
234 return new WP_Error( 'fs_no_folder', sprintf( $this->strings['fs_no_folder'], esc_html( basename( $dir ) ) ) ); |
|
235 } |
227 break; |
236 break; |
228 } |
237 } |
229 } |
238 } |
230 return true; |
239 return true; |
231 } //end fs_connect(); |
240 } //end fs_connect(); |
250 * Default false. |
260 * Default false. |
251 * @param string $package The package file name. |
261 * @param string $package The package file name. |
252 * @param WP_Upgrader $this The WP_Upgrader instance. |
262 * @param WP_Upgrader $this The WP_Upgrader instance. |
253 */ |
263 */ |
254 $reply = apply_filters( 'upgrader_pre_download', false, $package, $this ); |
264 $reply = apply_filters( 'upgrader_pre_download', false, $package, $this ); |
255 if ( false !== $reply ) |
265 if ( false !== $reply ) { |
256 return $reply; |
266 return $reply; |
257 |
267 } |
258 if ( ! preg_match('!^(http|https|ftp)://!i', $package) && file_exists($package) ) //Local file or remote? |
268 |
|
269 if ( ! preg_match( '!^(http|https|ftp)://!i', $package ) && file_exists( $package ) ) { //Local file or remote? |
259 return $package; //must be a local file.. |
270 return $package; //must be a local file.. |
260 |
271 } |
261 if ( empty($package) ) |
272 |
262 return new WP_Error('no_package', $this->strings['no_package']); |
273 if ( empty( $package ) ) { |
263 |
274 return new WP_Error( 'no_package', $this->strings['no_package'] ); |
264 $this->skin->feedback('downloading_package', $package); |
275 } |
265 |
276 |
266 $download_file = download_url($package); |
277 $this->skin->feedback( 'downloading_package', $package ); |
267 |
278 |
268 if ( is_wp_error($download_file) ) |
279 $download_file = download_url( $package, 300, $check_signatures ); |
269 return new WP_Error('download_failed', $this->strings['download_failed'], $download_file->get_error_message()); |
280 |
|
281 if ( is_wp_error( $download_file ) && ! $download_file->get_error_data( 'softfail-filename' ) ) { |
|
282 return new WP_Error( 'download_failed', $this->strings['download_failed'], $download_file->get_error_message() ); |
|
283 } |
270 |
284 |
271 return $download_file; |
285 return $download_file; |
272 } |
286 } |
273 |
287 |
274 /** |
288 /** |
275 * Unpack a compressed package file. |
289 * Unpack a compressed package file. |
276 * |
290 * |
277 * @since 2.8.0 |
291 * @since 2.8.0 |
278 * |
292 * |
279 * @global WP_Filesystem_Base $wp_filesystem Subclass |
293 * @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass. |
280 * |
294 * |
281 * @param string $package Full path to the package file. |
295 * @param string $package Full path to the package file. |
282 * @param bool $delete_package Optional. Whether to delete the package file after attempting |
296 * @param bool $delete_package Optional. Whether to delete the package file after attempting |
283 * to unpack it. Default true. |
297 * to unpack it. Default true. |
284 * @return string|WP_Error The path to the unpacked contents, or a WP_Error on failure. |
298 * @return string|WP_Error The path to the unpacked contents, or a WP_Error on failure. |
285 */ |
299 */ |
286 public function unpack_package( $package, $delete_package = true ) { |
300 public function unpack_package( $package, $delete_package = true ) { |
287 global $wp_filesystem; |
301 global $wp_filesystem; |
288 |
302 |
289 $this->skin->feedback('unpack_package'); |
303 $this->skin->feedback( 'unpack_package' ); |
290 |
304 |
291 $upgrade_folder = $wp_filesystem->wp_content_dir() . 'upgrade/'; |
305 $upgrade_folder = $wp_filesystem->wp_content_dir() . 'upgrade/'; |
292 |
306 |
293 //Clean up contents of upgrade directory beforehand. |
307 //Clean up contents of upgrade directory beforehand. |
294 $upgrade_files = $wp_filesystem->dirlist($upgrade_folder); |
308 $upgrade_files = $wp_filesystem->dirlist( $upgrade_folder ); |
295 if ( !empty($upgrade_files) ) { |
309 if ( ! empty( $upgrade_files ) ) { |
296 foreach ( $upgrade_files as $file ) |
310 foreach ( $upgrade_files as $file ) { |
297 $wp_filesystem->delete($upgrade_folder . $file['name'], true); |
311 $wp_filesystem->delete( $upgrade_folder . $file['name'], true ); |
|
312 } |
298 } |
313 } |
299 |
314 |
300 // We need a working directory - Strip off any .tmp or .zip suffixes |
315 // We need a working directory - Strip off any .tmp or .zip suffixes |
301 $working_dir = $upgrade_folder . basename( basename( $package, '.tmp' ), '.zip' ); |
316 $working_dir = $upgrade_folder . basename( basename( $package, '.tmp' ), '.zip' ); |
302 |
317 |
303 // Clean up working directory |
318 // Clean up working directory |
304 if ( $wp_filesystem->is_dir($working_dir) ) |
319 if ( $wp_filesystem->is_dir( $working_dir ) ) { |
305 $wp_filesystem->delete($working_dir, true); |
320 $wp_filesystem->delete( $working_dir, true ); |
|
321 } |
306 |
322 |
307 // Unzip package to working directory |
323 // Unzip package to working directory |
308 $result = unzip_file( $package, $working_dir ); |
324 $result = unzip_file( $package, $working_dir ); |
309 |
325 |
310 // Once extracted, delete the package if required. |
326 // Once extracted, delete the package if required. |
311 if ( $delete_package ) |
327 if ( $delete_package ) { |
312 unlink($package); |
328 unlink( $package ); |
313 |
329 } |
314 if ( is_wp_error($result) ) { |
330 |
315 $wp_filesystem->delete($working_dir, true); |
331 if ( is_wp_error( $result ) ) { |
|
332 $wp_filesystem->delete( $working_dir, true ); |
316 if ( 'incompatible_archive' == $result->get_error_code() ) { |
333 if ( 'incompatible_archive' == $result->get_error_code() ) { |
317 return new WP_Error( 'incompatible_archive', $this->strings['incompatible_archive'], $result->get_error_data() ); |
334 return new WP_Error( 'incompatible_archive', $this->strings['incompatible_archive'], $result->get_error_data() ); |
318 } |
335 } |
319 return $result; |
336 return $result; |
320 } |
337 } |
430 */ |
447 */ |
431 public function install_package( $args = array() ) { |
448 public function install_package( $args = array() ) { |
432 global $wp_filesystem, $wp_theme_directories; |
449 global $wp_filesystem, $wp_theme_directories; |
433 |
450 |
434 $defaults = array( |
451 $defaults = array( |
435 'source' => '', // Please always pass this |
452 'source' => '', // Please always pass this |
436 'destination' => '', // and this |
453 'destination' => '', // and this |
437 'clear_destination' => false, |
454 'clear_destination' => false, |
438 'clear_working' => false, |
455 'clear_working' => false, |
439 'abort_if_destination_exists' => true, |
456 'abort_if_destination_exists' => true, |
440 'hook_extra' => array() |
457 'hook_extra' => array(), |
441 ); |
458 ); |
442 |
459 |
443 $args = wp_parse_args($args, $defaults); |
460 $args = wp_parse_args( $args, $defaults ); |
444 |
461 |
445 // These were previously extract()'d. |
462 // These were previously extract()'d. |
446 $source = $args['source']; |
463 $source = $args['source']; |
447 $destination = $args['destination']; |
464 $destination = $args['destination']; |
448 $clear_destination = $args['clear_destination']; |
465 $clear_destination = $args['clear_destination']; |
449 |
466 |
450 @set_time_limit( 300 ); |
467 @set_time_limit( 300 ); |
451 |
468 |
452 if ( empty( $source ) || empty( $destination ) ) { |
469 if ( empty( $source ) || empty( $destination ) ) { |
471 if ( is_wp_error( $res ) ) { |
488 if ( is_wp_error( $res ) ) { |
472 return $res; |
489 return $res; |
473 } |
490 } |
474 |
491 |
475 //Retain the Original source and destinations |
492 //Retain the Original source and destinations |
476 $remote_source = $args['source']; |
493 $remote_source = $args['source']; |
477 $local_destination = $destination; |
494 $local_destination = $destination; |
478 |
495 |
479 $source_files = array_keys( $wp_filesystem->dirlist( $remote_source ) ); |
496 $source_files = array_keys( $wp_filesystem->dirlist( $remote_source ) ); |
480 $remote_destination = $wp_filesystem->find_folder( $local_destination ); |
497 $remote_destination = $wp_filesystem->find_folder( $local_destination ); |
481 |
498 |
482 //Locate which directory to copy to the new folder, This is based on the actual folder holding the files. |
499 //Locate which directory to copy to the new folder, This is based on the actual folder holding the files. |
483 if ( 1 == count( $source_files ) && $wp_filesystem->is_dir( trailingslashit( $args['source'] ) . $source_files[0] . '/' ) ) { //Only one folder? Then we want its contents. |
500 if ( 1 == count( $source_files ) && $wp_filesystem->is_dir( trailingslashit( $args['source'] ) . $source_files[0] . '/' ) ) { //Only one folder? Then we want its contents. |
484 $source = trailingslashit( $args['source'] ) . trailingslashit( $source_files[0] ); |
501 $source = trailingslashit( $args['source'] ) . trailingslashit( $source_files[0] ); |
523 $protected_directories = array_merge( $protected_directories, $wp_theme_directories ); |
540 $protected_directories = array_merge( $protected_directories, $wp_theme_directories ); |
524 } |
541 } |
525 |
542 |
526 if ( in_array( $destination, $protected_directories ) ) { |
543 if ( in_array( $destination, $protected_directories ) ) { |
527 $remote_destination = trailingslashit( $remote_destination ) . trailingslashit( basename( $source ) ); |
544 $remote_destination = trailingslashit( $remote_destination ) . trailingslashit( basename( $source ) ); |
528 $destination = trailingslashit( $destination ) . trailingslashit( basename( $source ) ); |
545 $destination = trailingslashit( $destination ) . trailingslashit( basename( $source ) ); |
529 } |
546 } |
530 |
547 |
531 if ( $clear_destination ) { |
548 if ( $clear_destination ) { |
532 // We're going to clear the destination if there's something there. |
549 // We're going to clear the destination if there's something there. |
533 $this->skin->feedback('remove_old'); |
550 $this->skin->feedback( 'remove_old' ); |
534 |
551 |
535 $removed = $this->clear_destination( $remote_destination ); |
552 $removed = $this->clear_destination( $remote_destination ); |
536 |
553 |
537 /** |
554 /** |
538 * Filters whether the upgrader cleared the destination. |
555 * Filters whether the upgrader cleared the destination. |
547 $removed = apply_filters( 'upgrader_clear_destination', $removed, $local_destination, $remote_destination, $args['hook_extra'] ); |
564 $removed = apply_filters( 'upgrader_clear_destination', $removed, $local_destination, $remote_destination, $args['hook_extra'] ); |
548 |
565 |
549 if ( is_wp_error( $removed ) ) { |
566 if ( is_wp_error( $removed ) ) { |
550 return $removed; |
567 return $removed; |
551 } |
568 } |
552 } elseif ( $args['abort_if_destination_exists'] && $wp_filesystem->exists($remote_destination) ) { |
569 } elseif ( $args['abort_if_destination_exists'] && $wp_filesystem->exists( $remote_destination ) ) { |
553 //If we're not clearing the destination folder and something exists there already, Bail. |
570 //If we're not clearing the destination folder and something exists there already, Bail. |
554 //But first check to see if there are actually any files in the folder. |
571 //But first check to see if there are actually any files in the folder. |
555 $_files = $wp_filesystem->dirlist($remote_destination); |
572 $_files = $wp_filesystem->dirlist( $remote_destination ); |
556 if ( ! empty($_files) ) { |
573 if ( ! empty( $_files ) ) { |
557 $wp_filesystem->delete($remote_source, true); //Clear out the source files. |
574 $wp_filesystem->delete( $remote_source, true ); //Clear out the source files. |
558 return new WP_Error('folder_exists', $this->strings['folder_exists'], $remote_destination ); |
575 return new WP_Error( 'folder_exists', $this->strings['folder_exists'], $remote_destination ); |
559 } |
576 } |
560 } |
577 } |
561 |
578 |
562 //Create destination if needed |
579 //Create destination if needed |
563 if ( ! $wp_filesystem->exists( $remote_destination ) ) { |
580 if ( ! $wp_filesystem->exists( $remote_destination ) ) { |
564 if ( ! $wp_filesystem->mkdir( $remote_destination, FS_CHMOD_DIR ) ) { |
581 if ( ! $wp_filesystem->mkdir( $remote_destination, FS_CHMOD_DIR ) ) { |
565 return new WP_Error( 'mkdir_failed_destination', $this->strings['mkdir_failed'], $remote_destination ); |
582 return new WP_Error( 'mkdir_failed_destination', $this->strings['mkdir_failed'], $remote_destination ); |
566 } |
583 } |
567 } |
584 } |
568 // Copy new version of item into place. |
585 // Copy new version of item into place. |
569 $result = copy_dir($source, $remote_destination); |
586 $result = copy_dir( $source, $remote_destination ); |
570 if ( is_wp_error($result) ) { |
587 if ( is_wp_error( $result ) ) { |
571 if ( $args['clear_working'] ) { |
588 if ( $args['clear_working'] ) { |
572 $wp_filesystem->delete( $remote_source, true ); |
589 $wp_filesystem->delete( $remote_source, true ); |
573 } |
590 } |
574 return $result; |
591 return $result; |
575 } |
592 } |
577 //Clear the Working folder? |
594 //Clear the Working folder? |
578 if ( $args['clear_working'] ) { |
595 if ( $args['clear_working'] ) { |
579 $wp_filesystem->delete( $remote_source, true ); |
596 $wp_filesystem->delete( $remote_source, true ); |
580 } |
597 } |
581 |
598 |
582 $destination_name = basename( str_replace($local_destination, '', $destination) ); |
599 $destination_name = basename( str_replace( $local_destination, '', $destination ) ); |
583 if ( '.' == $destination_name ) { |
600 if ( '.' == $destination_name ) { |
584 $destination_name = ''; |
601 $destination_name = ''; |
585 } |
602 } |
586 |
603 |
587 $this->result = compact( 'source', 'source_files', 'destination', 'destination_name', 'local_destination', 'remote_destination', 'clear_destination' ); |
604 $this->result = compact( 'source', 'source_files', 'destination', 'destination_name', 'local_destination', 'remote_destination', 'clear_destination' ); |
640 * or false if unable to connect to the filesystem. |
657 * or false if unable to connect to the filesystem. |
641 */ |
658 */ |
642 public function run( $options ) { |
659 public function run( $options ) { |
643 |
660 |
644 $defaults = array( |
661 $defaults = array( |
645 'package' => '', // Please always pass this. |
662 'package' => '', // Please always pass this. |
646 'destination' => '', // And this |
663 'destination' => '', // And this |
647 'clear_destination' => false, |
664 'clear_destination' => false, |
648 'abort_if_destination_exists' => true, // Abort if the Destination directory exists, Pass clear_destination as false please |
665 'abort_if_destination_exists' => true, // Abort if the Destination directory exists, Pass clear_destination as false please |
649 'clear_working' => true, |
666 'clear_working' => true, |
650 'is_multi' => false, |
667 'is_multi' => false, |
651 'hook_extra' => array() // Pass any extra $hook_extra args here, this will be passed to any hooked filters. |
668 'hook_extra' => array(), // Pass any extra $hook_extra args here, this will be passed to any hooked filters. |
652 ); |
669 ); |
653 |
670 |
654 $options = wp_parse_args( $options, $defaults ); |
671 $options = wp_parse_args( $options, $defaults ); |
655 |
672 |
656 /** |
673 /** |
673 * Extra hook arguments. |
690 * Extra hook arguments. |
674 * |
691 * |
675 * @type string $action Type of action. Default 'update'. |
692 * @type string $action Type of action. Default 'update'. |
676 * @type string $type Type of update process. Accepts 'plugin', 'theme', or 'core'. |
693 * @type string $type Type of update process. Accepts 'plugin', 'theme', or 'core'. |
677 * @type bool $bulk Whether the update process is a bulk update. Default true. |
694 * @type bool $bulk Whether the update process is a bulk update. Default true. |
678 * @type string $plugin The base plugin path from the plugins directory. |
695 * @type string $plugin Path to the plugin file relative to the plugins directory. |
679 * @type string $theme The stylesheet or template name of the theme. |
696 * @type string $theme The stylesheet or template name of the theme. |
680 * @type string $language_update_type The language pack update type. Accepts 'plugin', 'theme', |
697 * @type string $language_update_type The language pack update type. Accepts 'plugin', 'theme', |
681 * or 'core'. |
698 * or 'core'. |
682 * @type object $language_update The language pack update offer. |
699 * @type object $language_update The language pack update offer. |
683 * } |
700 * } |
712 |
729 |
713 /* |
730 /* |
714 * Download the package (Note, This just returns the filename |
731 * Download the package (Note, This just returns the filename |
715 * of the file if the package is a local file) |
732 * of the file if the package is a local file) |
716 */ |
733 */ |
717 $download = $this->download_package( $options['package'] ); |
734 $download = $this->download_package( $options['package'], true ); |
718 if ( is_wp_error($download) ) { |
735 |
719 $this->skin->error($download); |
736 // Allow for signature soft-fail. |
|
737 // WARNING: This may be removed in the future. |
|
738 if ( is_wp_error( $download ) && $download->get_error_data( 'softfail-filename' ) ) { |
|
739 |
|
740 // Don't output the 'no signature could be found' failure message for now. |
|
741 if ( 'signature_verification_no_signature' != $download->get_error_code() || WP_DEBUG ) { |
|
742 // Outout the failure error as a normal feedback, and not as an error: |
|
743 $this->skin->feedback( $download->get_error_message() ); |
|
744 |
|
745 // Report this failure back to WordPress.org for debugging purposes. |
|
746 wp_version_check( |
|
747 array( |
|
748 'signature_failure_code' => $download->get_error_code(), |
|
749 'signature_failure_data' => $download->get_error_data(), |
|
750 ) |
|
751 ); |
|
752 } |
|
753 |
|
754 // Pretend this error didn't happen. |
|
755 $download = $download->get_error_data( 'softfail-filename' ); |
|
756 } |
|
757 |
|
758 if ( is_wp_error( $download ) ) { |
|
759 $this->skin->error( $download ); |
720 $this->skin->after(); |
760 $this->skin->after(); |
721 if ( ! $options['is_multi'] ) { |
761 if ( ! $options['is_multi'] ) { |
722 $this->skin->footer(); |
762 $this->skin->footer(); |
723 } |
763 } |
724 return $download; |
764 return $download; |
726 |
766 |
727 $delete_package = ( $download != $options['package'] ); // Do not delete a "local" file |
767 $delete_package = ( $download != $options['package'] ); // Do not delete a "local" file |
728 |
768 |
729 // Unzips the file into a temporary directory. |
769 // Unzips the file into a temporary directory. |
730 $working_dir = $this->unpack_package( $download, $delete_package ); |
770 $working_dir = $this->unpack_package( $download, $delete_package ); |
731 if ( is_wp_error($working_dir) ) { |
771 if ( is_wp_error( $working_dir ) ) { |
732 $this->skin->error($working_dir); |
772 $this->skin->error( $working_dir ); |
733 $this->skin->after(); |
773 $this->skin->after(); |
734 if ( ! $options['is_multi'] ) { |
774 if ( ! $options['is_multi'] ) { |
735 $this->skin->footer(); |
775 $this->skin->footer(); |
736 } |
776 } |
737 return $working_dir; |
777 return $working_dir; |
738 } |
778 } |
739 |
779 |
740 // With the given options, this installs it to the destination directory. |
780 // With the given options, this installs it to the destination directory. |
741 $result = $this->install_package( array( |
781 $result = $this->install_package( |
742 'source' => $working_dir, |
782 array( |
743 'destination' => $options['destination'], |
783 'source' => $working_dir, |
744 'clear_destination' => $options['clear_destination'], |
784 'destination' => $options['destination'], |
745 'abort_if_destination_exists' => $options['abort_if_destination_exists'], |
785 'clear_destination' => $options['clear_destination'], |
746 'clear_working' => $options['clear_working'], |
786 'abort_if_destination_exists' => $options['abort_if_destination_exists'], |
747 'hook_extra' => $options['hook_extra'] |
787 'clear_working' => $options['clear_working'], |
748 ) ); |
788 'hook_extra' => $options['hook_extra'], |
749 |
789 ) |
750 $this->skin->set_result($result); |
790 ); |
751 if ( is_wp_error($result) ) { |
791 |
752 $this->skin->error($result); |
792 $this->skin->set_result( $result ); |
753 $this->skin->feedback('process_failed'); |
793 if ( is_wp_error( $result ) ) { |
|
794 $this->skin->error( $result ); |
|
795 $this->skin->feedback( 'process_failed' ); |
754 } else { |
796 } else { |
755 // Installation succeeded. |
797 // Installation succeeded. |
756 $this->skin->feedback('process_success'); |
798 $this->skin->feedback( 'process_success' ); |
757 } |
799 } |
758 |
800 |
759 $this->skin->after(); |
801 $this->skin->after(); |
760 |
802 |
761 if ( ! $options['is_multi'] ) { |
803 if ( ! $options['is_multi'] ) { |
811 */ |
853 */ |
812 public function maintenance_mode( $enable = false ) { |
854 public function maintenance_mode( $enable = false ) { |
813 global $wp_filesystem; |
855 global $wp_filesystem; |
814 $file = $wp_filesystem->abspath() . '.maintenance'; |
856 $file = $wp_filesystem->abspath() . '.maintenance'; |
815 if ( $enable ) { |
857 if ( $enable ) { |
816 $this->skin->feedback('maintenance_start'); |
858 $this->skin->feedback( 'maintenance_start' ); |
817 // Create maintenance file to signal that we are upgrading |
859 // Create maintenance file to signal that we are upgrading |
818 $maintenance_string = '<?php $upgrading = ' . time() . '; ?>'; |
860 $maintenance_string = '<?php $upgrading = ' . time() . '; ?>'; |
819 $wp_filesystem->delete($file); |
861 $wp_filesystem->delete( $file ); |
820 $wp_filesystem->put_contents($file, $maintenance_string, FS_CHMOD_FILE); |
862 $wp_filesystem->put_contents( $file, $maintenance_string, FS_CHMOD_FILE ); |
821 } elseif ( ! $enable && $wp_filesystem->exists( $file ) ) { |
863 } elseif ( ! $enable && $wp_filesystem->exists( $file ) ) { |
822 $this->skin->feedback('maintenance_end'); |
864 $this->skin->feedback( 'maintenance_end' ); |
823 $wp_filesystem->delete($file); |
865 $wp_filesystem->delete( $file ); |
824 } |
866 } |
825 } |
867 } |
826 |
868 |
827 /** |
869 /** |
828 * Creates a lock using WordPress options. |
870 * Creates a lock using WordPress options. |
829 * |
871 * |
830 * @since 4.5.0 |
872 * @since 4.5.0 |
831 * @static |
873 * |
832 * |
874 * @param string $lock_name The name of this unique lock. |
833 * @param string $lock_name The name of this unique lock. |
875 * @param int $release_timeout Optional. The duration in seconds to respect an existing lock. |
834 * @param int $release_timeout Optional. The duration in seconds to respect an existing lock. |
|
835 * Default: 1 hour. |
876 * Default: 1 hour. |
836 * @return bool False if a lock couldn't be created or if the lock is still valid. True otherwise. |
877 * @return bool False if a lock couldn't be created or if the lock is still valid. True otherwise. |
837 */ |
878 */ |
838 public static function create_lock( $lock_name, $release_timeout = null ) { |
879 public static function create_lock( $lock_name, $release_timeout = null ) { |
839 global $wpdb; |
880 global $wpdb; |
840 if ( ! $release_timeout ) { |
881 if ( ! $release_timeout ) { |
841 $release_timeout = HOUR_IN_SECONDS; |
882 $release_timeout = HOUR_IN_SECONDS; |
842 } |
883 } |