WordPress.org

Make WordPress Core

Changeset 12794


Ignore:
Timestamp:
01/22/2010 11:02:09 AM (10 years ago)
Author:
dd32
Message:

Optimised unzip_file(), reduces is_dir() IO calls. See #10779

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/wp-admin/includes/file.php

    r12789 r12794  
    505505    @ini_set('memory_limit', '256M');
    506506
    507     $fs =& $wp_filesystem;
    508 
    509507    require_once(ABSPATH . 'wp-admin/includes/class-pclzip.php');
    510508
     
    518516        return new WP_Error('empty_archive', __('Empty archive.'));
    519517
    520     $path = explode('/', untrailingslashit($to));
    521     for ( $i = count($path); $i > 0; $i-- ) { //>0 = first element is empty allways for paths starting with '/'
    522         $tmppath = implode('/', array_slice($path, 0, $i) );
    523         if ( $fs->is_dir($tmppath) ) { //Found the highest folder that exists, Create from here(ie +1)
    524             for ( $i = $i + 1; $i <= count($path); $i++ ) {
    525                 $tmppath = implode('/', array_slice($path, 0, $i) );
    526                 if ( ! $fs->mkdir($tmppath, FS_CHMOD_DIR) )
    527                     return new WP_Error('mkdir_failed', __('Could not create directory.'), $tmppath);
    528             }
    529             break; //Exit main for loop
    530         }
    531     }
    532 
     518    $needed_dirs = array();
    533519    $to = trailingslashit($to);
    534     foreach ($archive_files as $file) {
    535         $path = $file['folder'] ? $file['filename'] : dirname($file['filename']);
    536         $path = explode('/', $path);
    537         for ( $i = count($path); $i >= 0; $i-- ) { //>=0 as the first element contains data
     520
     521    // Determine any parent dir's needed (of the upgrade directory)
     522    if ( ! $wp_filesystem->is_dir($to) ) { //Only do parents if no children exist
     523        $path = preg_split('![/\\\]!', untrailingslashit($to));
     524        for ( $i = count($path); $i >= 0; $i-- ) {
    538525            if ( empty($path[$i]) )
    539526                continue;
    540             $tmppath = $to . implode('/', array_slice($path, 0, $i) );
    541             if ( $fs->is_dir($tmppath) ) {//Found the highest folder that exists, Create from here
    542                 for ( $i = $i + 1; $i <= count($path); $i++ ) { //< count() no file component please.
    543                     $tmppath = $to . implode('/', array_slice($path, 0, $i) );
    544                     if ( ! $fs->is_dir($tmppath) && ! $fs->mkdir($tmppath, FS_CHMOD_DIR) )
    545                         return new WP_Error('mkdir_failed', __('Could not create directory.'), $tmppath);
    546                 }
    547                 break; //Exit main for loop
    548             }
     527
     528            $dir = implode('/', array_slice($path, 0, $i+1) );
     529            if ( preg_match('!^[a-z]:$!i', $dir) ) // Skip it if it looks like a Windows Drive letter only.
     530                continue;
     531
     532            if ( ! $wp_filesystem->is_dir($dir) )
     533                $needed_dirs[] = $dir;
     534            else
     535                break; // A folder exists, therefor, we dont need the check the levels below this
    549536        }
    550 
    551         // We've made sure the folders are there, so let's extract the file now:
    552         if ( ! $file['folder'] ) {
    553             if ( !$fs->put_contents( $to . $file['filename'], $file['content'], FS_CHMOD_FILE) )
    554                 return new WP_Error('copy_failed', __('Could not copy file.'), $to . $file['filename']);
    555         }
     537    }
     538
     539    // Determine any children directories needed (From within the archive)
     540    foreach ( $archive_files as $file )
     541        $needed_dirs[] = $to . untrailingslashit( $file['folder'] ? $file['filename'] : dirname($file['filename']) );
     542
     543    $needed_dirs = array_unique($needed_dirs);
     544    asort($needed_dirs);
     545
     546    // Create those directories if need be:
     547    foreach ( $needed_dirs as $_dir ) {
     548        if ( ! $wp_filesystem->mkdir($_dir, FS_CHMOD_DIR) && ! $wp_filesystem->is_dir($_dir) ) // Only check to see if the Dir exists upon creation failure. Less I/O this way.
     549            return new WP_Error('mkdir_failed', __('Could not create directory.'), $_dir);
     550    }
     551
     552    // Extract the files from the zip
     553    foreach ( $archive_files as $file ) {
     554        if ( $file['folder'] )
     555            continue;
     556
     557        if ( ! $wp_filesystem->put_contents( $to . $file['filename'], $file['content'], FS_CHMOD_FILE) )
     558            return new WP_Error('copy_failed', __('Could not copy file.'), $to . $file['filename']);
    556559    }
    557560    return true;
Note: See TracChangeset for help on using the changeset viewer.