405 | 405 | * destination directory (WP_PLUGIN_DIR / wp-content/themes) intending |
406 | 406 | * to copy the directory into the directory, whilst they pass the source |
407 | 407 | * as the actual files to copy. |
408 | 408 | */ |
409 | 409 | $protected_directories = array( ABSPATH, WP_CONTENT_DIR, WP_PLUGIN_DIR, WP_CONTENT_DIR . '/themes' ); |
410 | 410 | |
411 | 411 | if ( is_array( $wp_theme_directories ) ) { |
412 | 412 | $protected_directories = array_merge( $protected_directories, $wp_theme_directories ); |
413 | 413 | } |
414 | 414 | if ( in_array( $destination, $protected_directories ) ) { |
415 | 415 | $remote_destination = trailingslashit( $remote_destination ) . trailingslashit( basename( $source ) ); |
416 | 416 | $destination = trailingslashit( $destination ) . trailingslashit( basename( $source ) ); |
417 | 417 | } |
418 | 418 | |
419 | 419 | if ( $clear_destination ) { |
424 | | $removed = $wp_filesystem->delete( $remote_destination, true ); |
| 425 | // Check all files are writable before attempting to clear the destination |
| 426 | $unwritable_files = array(); |
| 427 | |
| 428 | $_files = $wp_filesystem->dirlist( $remote_destination, true, true ); |
| 429 | // Flatten the resulting array |
| 430 | while ( $f = each( $_files ) ) { |
| 431 | $file = $f['value']; |
| 432 | $name = $f['key']; |
| 433 | |
| 434 | if ( ! isset( $file['files'] ) ) { |
| 435 | continue; |
| 436 | } |
| 437 | |
| 438 | foreach ( $file['files'] as $filename => $details ) { |
| 439 | $_files[ $name . '/' . $filename ] = $details; |
| 440 | } |
| 441 | } |
| 442 | |
| 443 | // Check writability |
| 444 | foreach ( $_files as $filename => $file_details ) { |
| 445 | if ( ! $wp_filesystem->is_writable( $remote_destination . $filename ) ) { |
| 446 | $unwritable_files[] = $filename; |
| 447 | } |
| 448 | } |
| 449 | |
| 450 | if ( empty( $unwritable_files ) ) { |
| 451 | $removed = $wp_filesystem->delete( $remote_destination, true ); |
| 452 | } else { |
| 453 | $removed = new WP_Error( 'unwritable_files', 'Some files are unwritable, abort abort!', $unwritable_files ); |
| 454 | } |
425 | 455 | } |
426 | 456 | |
427 | 457 | /** |
428 | 458 | * Filter whether the upgrader cleared the destination. |
429 | 459 | * |
430 | 460 | * @since 2.8.0 |
431 | 461 | * |
432 | 462 | * @param bool $removed Whether the destination was cleared. |
433 | 463 | * @param string $local_destination The local package destination. |
434 | 464 | * @param string $remote_destination The remote package destination. |
435 | 465 | * @param array $hook_extra Extra arguments passed to hooked filters. |
436 | 466 | */ |
437 | 467 | $removed = apply_filters( 'upgrader_clear_destination', $removed, $local_destination, $remote_destination, $args['hook_extra'] ); |
438 | 468 | |
439 | 469 | if ( is_wp_error($removed) ) { |