: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
if ( is_array( $wp_theme_directories ) ) {
$protected_directories = array_merge( $protected_directories, $wp_theme_directories );
if ( in_array( $destination, $protected_directories ) ) {
$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.
$removed = $this->clear_destination( $remote_destination );
* Filter whether the upgrader cleared the destination.
* @param mixed $removed Whether the destination was cleared. true on 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 ) ) {
} 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 );
// 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 === '.' ) {
$this->result = compact( 'source', 'source_files', 'destination', 'destination_name', 'local_destination', 'remote_destination', 'clear_destination' );
* Filter the installation response after the installation has finished.
* @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 ) ) {
// Bombard the calling function will all the info which we've just used.
* Install a plugin package.
* @param string $package The full local path or URI of the package.
* @param array $args Optional. Other arguments for installing a plugin package. Default empty array.
* @return bool|\WP_Error True if the installation was successful, false or a WP_Error otherwise.
public function install( $package, $args = [] ) {
$result = parent::install( $package, $args );
if ( true === $result ) {
do_action( 'wpforms_plugin_installed', $package );