From 4b2b97a3b3bb534bab8030495f01d5fe317ab2b9 Mon Sep 17 00:00:00 2001 From: Dion Hulse Date: Wed, 11 Oct 2017 04:23:49 +0000 Subject: [PATCH] Upgrades: Remove the usage of `each()` from `WP_Upgrader` for PHP 7.2 compatibility. Props chrisvendiadvertisingcom, dd32. Fixes #41524 git-svn-id: https://develop.svn.wordpress.org/trunk@41821 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/includes/class-wp-upgrader.php | 54 +++++++++++++-------- 1 file changed, 35 insertions(+), 19 deletions(-) diff --git a/src/wp-admin/includes/class-wp-upgrader.php b/src/wp-admin/includes/class-wp-upgrader.php index f7dea257ea..fd70ba469e 100644 --- a/src/wp-admin/includes/class-wp-upgrader.php +++ b/src/wp-admin/includes/class-wp-upgrader.php @@ -322,6 +322,33 @@ class WP_Upgrader { return $working_dir; } + /** + * Flatten the results of WP_Filesystem::dirlist() for iterating over. + * + * @since 4.9.0 + * @access protected + * + * @param array $nested_files Array of files as returned by WP_Filesystem::dirlist() + * @param string $path Relative path to prepend to child nodes. Optional. + * @return array $files A flattened array of the $nested_files specified. + */ + protected function flatten_dirlist( $nested_files, $path = '' ) { + $files = array(); + + foreach ( $nested_files as $name => $details ) { + $files[ $path . $name ] = $details; + + // Append children recursively + if ( ! empty( $details['files'] ) ) { + $children = $this->flatten_dirlist( $details['files'], $path . $name . '/' ); + + $files = array_merge( $files, $children ); + } + } + + return $files; + } + /** * Clears the directory where this item is going to be installed into. * @@ -335,33 +362,22 @@ class WP_Upgrader { public function clear_destination( $remote_destination ) { global $wp_filesystem; - if ( ! $wp_filesystem->exists( $remote_destination ) ) { + $files = $wp_filesystem->dirlist( $remote_destination, true, true ); + + // False indicates that the $remote_destination doesn't exist. + if ( false === $files ) { return true; } + // Flatten the file list to iterate over + $files = $this->flatten_dirlist( $files ); + // Check all files are writable before attempting to clear the destination. $unwritable_files = array(); - $_files = $wp_filesystem->dirlist( $remote_destination, true, true ); - - // Flatten the resulting array, iterate using each as we append to the array during iteration. - while ( $f = each( $_files ) ) { - $file = $f['value']; - $name = $f['key']; - - if ( ! isset( $file['files'] ) ) { - continue; - } - - foreach ( $file['files'] as $filename => $details ) { - $_files[ $name . '/' . $filename ] = $details; - } - } - // Check writability. - foreach ( $_files as $filename => $file_details ) { + foreach ( $files as $filename => $file_details ) { if ( ! $wp_filesystem->is_writable( $remote_destination . $filename ) ) { - // Attempt to alter permissions to allow writes and try again. $wp_filesystem->chmod( $remote_destination . $filename, ( 'd' == $file_details['type'] ? FS_CHMOD_DIR : FS_CHMOD_FILE ) ); if ( ! $wp_filesystem->is_writable( $remote_destination . $filename ) ) {