WP_Upgrader::install_package() WordPress Method
The WP_Upgrader::install_package() method is used to install a package on a WordPress site. This is typically used when upgrading or installing a plugin or theme.
WP_Upgrader::install_package( array|string $args = array() ) #
Install a package.
Description
Copies the contents of a package from a source directory, and installs them in a destination directory. Optionally removes the source. It can also optionally clear out the destination folder if it already exists.
Parameters
- $args
(array|string)(Optional)Array or string of arguments for installing a package.
- 'source'
(string) Required path to the package source. - 'destination'
(string) Required path to a folder to install the package in. - 'clear_destination'
(bool) Whether to delete any files already in the destination folder. Default false. - 'clear_working'
(bool) Whether to delete the files from the working directory after copying them to the destination. Default false. - 'abort_if_destination_exists'
(bool) Whether to abort the installation if the destination folder already exists. Default true. - 'hook_extra'
(array) Extra arguments to pass to the filter hooks called by WP_Upgrader::install_package().
Default value: array()
- 'source'
Return
(array|WP_Error) The result (also stored in WP_Upgrader::$result
), or a WP_Error on failure.
Source
File: wp-admin/includes/class-wp-upgrader.php
453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 | public function install_package( $args = array () ) { global $wp_filesystem , $wp_theme_directories ; $defaults = array ( 'source' => '' , // Please always pass this. 'destination' => '' , // ...and this. 'clear_destination' => false, 'clear_working' => false, 'abort_if_destination_exists' => true, 'hook_extra' => array (), ); $args = wp_parse_args( $args , $defaults ); // These were previously extract()'d. $source = $args [ 'source' ]; $destination = $args [ 'destination' ]; $clear_destination = $args [ 'clear_destination' ]; set_time_limit( 300 ); if ( empty ( $source ) || empty ( $destination ) ) { return new WP_Error( 'bad_request' , $this ->strings[ 'bad_request' ] ); } $this ->skin->feedback( 'installing_package' ); /** * Filters the installation response before the installation has started. * * Returning a value that could be evaluated as a `WP_Error` will effectively * short-circuit the installation, returning that value instead. * * @since 2.8.0 * * @param bool|WP_Error $response Installation response. * @param array $hook_extra Extra arguments passed to hooked filters. */ $res = apply_filters( 'upgrader_pre_install' , true, $args [ 'hook_extra' ] ); if ( is_wp_error( $res ) ) { return $res ; } // Retain the original source and destinations. $remote_source = $args [ 'source' ]; $local_destination = $destination ; $source_files = array_keys ( $wp_filesystem ->dirlist( $remote_source ) ); $remote_destination = $wp_filesystem ->find_folder( $local_destination ); // Locate which directory to copy to the new folder. This is based on the actual folder holding the files. if ( 1 === count ( $source_files ) && $wp_filesystem -> is_dir ( trailingslashit( $args [ 'source' ] ) . $source_files [0] . '/' ) ) { // Only one folder? Then we want its contents. $source = trailingslashit( $args [ 'source' ] ) . trailingslashit( $source_files [0] ); } elseif ( 0 === count ( $source_files ) ) { // There are no files? return new WP_Error( 'incompatible_archive_empty' , $this ->strings[ 'incompatible_archive' ], $this ->strings[ 'no_files' ] ); } else { // It's only a single file, the upgrader will use the folder name of this file as the destination folder. // Folder name is based on zip filename. $source = trailingslashit( $args [ 'source' ] ); } /** * Filters the source file location for the upgrade package. * * @since 2.8.0 * @since 4.4.0 The $hook_extra parameter became available. * * @param string $source File source location. * @param string $remote_source Remote file source location. * @param WP_Upgrader $upgrader WP_Upgrader instance. * @param array $hook_extra Extra arguments passed to hooked filters. */ $source = apply_filters( 'upgrader_source_selection' , $source , $remote_source , $this , $args [ 'hook_extra' ] ); if ( is_wp_error( $source ) ) { return $source ; } // Has the source location changed? If so, we need a new source_files list. if ( $source !== $remote_source ) { $source_files = array_keys ( $wp_filesystem ->dirlist( $source ) ); } /* * Protection against deleting files in any important base directories. * Theme_Upgrader & Plugin_Upgrader also trigger this, as they pass the * destination directory (WP_PLUGIN_DIR / wp-content/themes) intending * to copy the directory into the directory, whilst they pass the source * as the actual files to copy. */ $protected_directories = array ( ABSPATH, WP_CONTENT_DIR, WP_PLUGIN_DIR, WP_CONTENT_DIR . '/themes' ); if ( is_array ( $wp_theme_directories ) ) { $protected_directories = array_merge ( $protected_directories , $wp_theme_directories ); } if ( in_array( $destination , $protected_directories , true ) ) { $remote_destination = trailingslashit( $remote_destination ) . trailingslashit( basename ( $source ) ); $destination = trailingslashit( $destination ) . trailingslashit( basename ( $source ) ); } if ( $clear_destination ) { // We're going to clear the destination if there's something there. $this ->skin->feedback( 'remove_old' ); $removed = $this ->clear_destination( $remote_destination ); /** * Filters whether the upgrader cleared the destination. * * @since 2.8.0 * * @param true|WP_Error $removed Whether the destination was cleared. * True upon success, WP_Error on failure. * @param string $local_destination The local package destination. * @param string $remote_destination The remote package destination. * @param array $hook_extra Extra arguments passed to hooked filters. */ $removed = apply_filters( 'upgrader_clear_destination' , $removed , $local_destination , $remote_destination , $args [ 'hook_extra' ] ); if ( is_wp_error( $removed ) ) { return $removed ; } } elseif ( $args [ 'abort_if_destination_exists' ] && $wp_filesystem ->exists( $remote_destination ) ) { // If we're not clearing the destination folder and something exists there already, bail. // But first check to see if there are actually any files in the folder. $_files = $wp_filesystem ->dirlist( $remote_destination ); if ( ! empty ( $_files ) ) { $wp_filesystem -> delete ( $remote_source , true ); // Clear out the source files. return new WP_Error( 'folder_exists' , $this ->strings[ 'folder_exists' ], $remote_destination ); } } // Create destination if needed. if ( ! $wp_filesystem ->exists( $remote_destination ) ) { if ( ! $wp_filesystem -> mkdir ( $remote_destination , FS_CHMOD_DIR ) ) { return new WP_Error( 'mkdir_failed_destination' , $this ->strings[ 'mkdir_failed' ], $remote_destination ); } } // Copy new version of item into place. $result = copy_dir( $source , $remote_destination ); if ( is_wp_error( $result ) ) { if ( $args [ 'clear_working' ] ) { $wp_filesystem -> delete ( $remote_source , true ); } return $result ; } // Clear the working folder? if ( $args [ 'clear_working' ] ) { $wp_filesystem -> delete ( $remote_source , true ); } $destination_name = basename ( str_replace ( $local_destination , '' , $destination ) ); if ( '.' === $destination_name ) { $destination_name = '' ; } $this ->result = compact( 'source' , 'source_files' , 'destination' , 'destination_name' , 'local_destination' , 'remote_destination' , 'clear_destination' ); /** * Filters the installation response after the installation has finished. * * @since 2.8.0 * * @param bool $response Installation response. * @param array $hook_extra Extra arguments passed to hooked filters. * @param array $result Installation result data. */ $res = apply_filters( 'upgrader_post_install' , true, $args [ 'hook_extra' ], $this ->result ); if ( is_wp_error( $res ) ) { $this ->result = $res ; return $res ; } // Bombard the calling function will all the info which we've just used. return $this ->result; } |
Expand full source codeCollapse full source codeView on TracView on GitHub
Changelog
Version | Description |
---|---|
2.8.0 | Introduced. |