120 | 120 | $this->strings['fs_unavailable'] = __('Could not access filesystem.'); |
121 | 121 | $this->strings['fs_error'] = __('Filesystem error.'); |
122 | 122 | $this->strings['fs_no_root_dir'] = __('Unable to locate WordPress Root directory.'); |
123 | 123 | $this->strings['fs_no_content_dir'] = __('Unable to locate WordPress Content directory (wp-content).'); |
124 | 124 | $this->strings['fs_no_plugins_dir'] = __('Unable to locate WordPress Plugin directory.'); |
125 | 125 | $this->strings['fs_no_themes_dir'] = __('Unable to locate WordPress Theme directory.'); |
126 | 126 | /* translators: %s: directory name */ |
127 | 127 | $this->strings['fs_no_folder'] = __('Unable to locate needed folder (%s).'); |
128 | 128 | |
129 | 129 | $this->strings['download_failed'] = __('Download failed.'); |
130 | 130 | $this->strings['installing_package'] = __('Installing the latest version…'); |
131 | 131 | $this->strings['no_files'] = __('The package contains no files.'); |
132 | 132 | $this->strings['folder_exists'] = __('Destination folder already exists.'); |
133 | 133 | $this->strings['mkdir_failed'] = __('Could not create directory.'); |
134 | 134 | $this->strings['incompatible_archive'] = __('The package could not be installed.'); |
| 297 | * Clears the directory where this item is going to be installed into. |
| 298 | * |
| 299 | * @since 4.3.0 |
| 300 | * |
| 301 | * @global WP_Filesystem_Base $wp_filesystem Subclass |
| 302 | * |
| 303 | * @param string $remote_destination The location on the remote filesystem to be cleared |
| 304 | * |
| 305 | * @return bool|WP_Error true upon success, {@see WP_Error} on failure. |
| 306 | */ |
| 307 | function clear_destination( $remote_destination ) { |
| 308 | global $wp_filesystem; |
| 309 | |
| 310 | if ( ! $wp_filesystem->exists( $remote_destination ) ) { |
| 311 | return true; |
| 312 | } |
| 313 | |
| 314 | // Check all files are writable before attempting to clear the destination |
| 315 | $unwritable_files = array(); |
| 316 | |
| 317 | $_files = $wp_filesystem->dirlist( $remote_destination, true, true ); |
| 318 | // Flatten the resulting array, iterate using each as we append to the array during iteration |
| 319 | while ( $f = each( $_files ) ) { |
| 320 | $file = $f['value']; |
| 321 | $name = $f['key']; |
| 322 | |
| 323 | if ( ! isset( $file['files'] ) ) { |
| 324 | continue; |
| 325 | } |
| 326 | |
| 327 | foreach ( $file['files'] as $filename => $details ) { |
| 328 | $_files[ $name . '/' . $filename ] = $details; |
| 329 | } |
| 330 | } |
| 331 | |
| 332 | // Check writability |
| 333 | foreach ( $_files as $filename => $file_details ) { |
| 334 | if ( ! $wp_filesystem->is_writable( $remote_destination . $filename ) ) { |
| 335 | // Attempt to alter permissions to allow writes and try again |
| 336 | $wp_filesystem->chmod( $remote_destination . $filename, ( 'd' == $file_details['type'] ? FS_CHMOD_DIR : FS_CHMOD_FILE ) ); |
| 337 | if ( ! $wp_filesystem->is_writable( $remote_destination . $filename ) ) { |
| 338 | $unwritable_files[] = $filename; |
| 339 | } |
| 340 | } |
| 341 | } |
| 342 | |
| 343 | if ( ! empty( $unwritable_files ) ) { |
| 344 | return new WP_Error( 'files_not_writable', $this->strings['files_not_writable'], implode( ', ', $unwritable_files ) ); |
| 345 | } |
| 346 | |
| 347 | if ( ! $wp_filesystem->delete( $remote_destination, true ) ) { |
| 348 | return new WP_Error( 'remove_old_failed', $this->strings['remove_old_failed'] ); |
| 349 | } |
| 350 | |
| 351 | return true; |
| 352 | } |
| 353 | |
| 354 | /** |
296 | 355 | * Install a package. |
297 | 356 | * |
298 | 357 | * Copies the contents of a package form a source directory, and installs them in |
299 | 358 | * a destination directory. Optionally removes the source. It can also optionally |
300 | 359 | * clear out the destination folder if it already exists. |
301 | 360 | * |
302 | 361 | * @since 2.8.0 |
303 | 362 | * |
304 | 363 | * @global WP_Filesystem_Base $wp_filesystem Subclass |
305 | 364 | * @global array $wp_theme_directories |
306 | 365 | * |
307 | 366 | * @param array|string $args { |
308 | 367 | * Optional. Array or string of arguments for installing a package. Default empty array. |
309 | 368 | * |
310 | 369 | * @type string $source Required path to the package source. Default empty. |
405 | 464 | * destination directory (WP_PLUGIN_DIR / wp-content/themes) intending |
406 | 465 | * to copy the directory into the directory, whilst they pass the source |
407 | 466 | * as the actual files to copy. |
408 | 467 | */ |
409 | 468 | $protected_directories = array( ABSPATH, WP_CONTENT_DIR, WP_PLUGIN_DIR, WP_CONTENT_DIR . '/themes' ); |
410 | 469 | |
411 | 470 | if ( is_array( $wp_theme_directories ) ) { |
412 | 471 | $protected_directories = array_merge( $protected_directories, $wp_theme_directories ); |
413 | 472 | } |
414 | 473 | if ( in_array( $destination, $protected_directories ) ) { |
415 | 474 | $remote_destination = trailingslashit( $remote_destination ) . trailingslashit( basename( $source ) ); |
416 | 475 | $destination = trailingslashit( $destination ) . trailingslashit( basename( $source ) ); |
417 | 476 | } |
418 | 477 | |
419 | 478 | if ( $clear_destination ) { |
443 | 498 | } |
444 | 499 | } elseif ( $args['abort_if_destination_exists'] && $wp_filesystem->exists($remote_destination) ) { |
445 | 500 | //If we're not clearing the destination folder and something exists there already, Bail. |
446 | 501 | //But first check to see if there are actually any files in the folder. |
447 | 502 | $_files = $wp_filesystem->dirlist($remote_destination); |
448 | 503 | if ( ! empty($_files) ) { |
449 | 504 | $wp_filesystem->delete($remote_source, true); //Clear out the source files. |
450 | 505 | return new WP_Error('folder_exists', $this->strings['folder_exists'], $remote_destination ); |
451 | 506 | } |
452 | 507 | } |
453 | 508 | |
454 | 509 | //Create destination if needed |
455 | 510 | if ( ! $wp_filesystem->exists( $remote_destination ) ) { |
456 | 511 | if ( ! $wp_filesystem->mkdir( $remote_destination, FS_CHMOD_DIR ) ) { |
457 | 512 | return new WP_Error( 'mkdir_failed_destination', $this->strings['mkdir_failed'], $remote_destination ); |