_unzip_file_ziparchive

This function should not be called directly, use unzip_file instead.

Description

_unzip_file_ziparchive( (string) $file, (string) $to, (array) $needed_dirs = array() ); 

Attempts to unzip an archive using the ZipArchive class. Assumes that WP_Filesystem() has already been called and set up.

Parameters (3)

0. $file (string)
Full path and filename of zip archive
1. $to (string)
Full path on the filesystem to extract archive to
2. $needed_dirs — Optional. (array) => array()
A partial list of required folders needed to be created.

Usage

  1. if ( !function_exists( '_unzip_file_ziparchive' ) ) { 
  2. require_once ABSPATH . '/wp-admin/includes/file.php'; 
  3.  
  4. // Full path and filename of zip archive 
  5. $file = ''; 
  6.  
  7. // Full path on the filesystem to extract archive to 
  8. $to = ''; 
  9.  
  10. // A partial list of required folders needed to be created. 
  11. $needed_dirs = array(); 
  12.  
  13. // NOTICE! Understand what this does before running. 
  14. $result = _unzip_file_ziparchive($file, $to, $needed_dirs); 
  15.  

Defined (1)

The function is defined in the following location(s).

/wp-admin/includes/file.php  
  1. function _unzip_file_ziparchive($file, $to, $needed_dirs = array() ) { 
  2. global $wp_filesystem; 
  3.  
  4. $z = new ZipArchive(); 
  5.  
  6. $zopen = $z->open( $file, ZIPARCHIVE::CHECKCONS ); 
  7. if ( true !== $zopen ) 
  8. return new WP_Error( 'incompatible_archive', __( 'Incompatible Archive.' ), array( 'ziparchive_error' => $zopen ) ); 
  9.  
  10. $uncompressed_size = 0; 
  11.  
  12. for ( $i = 0; $i < $z->numFiles; $i++ ) { 
  13. if ( ! $info = $z->statIndex($i) ) 
  14. return new WP_Error( 'stat_failed_ziparchive', __( 'Could not retrieve file from archive.' ) ); 
  15.  
  16. if ( '__MACOSX/' === substr($info['name'], 0, 9) ) // Skip the OS X-created __MACOSX directory 
  17. continue; 
  18.  
  19. $uncompressed_size += $info['size']; 
  20.  
  21. if ( '/' === substr( $info['name'], -1 ) ) { 
  22. // Directory. 
  23. $needed_dirs[] = $to . untrailingslashit( $info['name'] ); 
  24. } elseif ( '.' !== $dirname = dirname( $info['name'] ) ) { 
  25. // Path to a file. 
  26. $needed_dirs[] = $to . untrailingslashit( $dirname ); 
  27.  
  28. /** 
  29. * disk_free_space() could return false. Assume that any falsey value is an error. 
  30. * A disk that has zero free bytes has bigger problems. 
  31. * Require we have enough space to unzip the file and copy its contents, with a 10% buffer. 
  32. */ 
  33. if ( defined( 'DOING_CRON' ) && DOING_CRON ) { 
  34. $available_space = @disk_free_space( WP_CONTENT_DIR ); 
  35. if ( $available_space && ( $uncompressed_size * 2.1 ) > $available_space ) 
  36. return new WP_Error( 'disk_full_unzip_file', __( 'Could not copy files. You may have run out of disk space.' ), compact( 'uncompressed_size', 'available_space' ) ); 
  37.  
  38. $needed_dirs = array_unique($needed_dirs); 
  39. foreach ( $needed_dirs as $dir ) { 
  40. // Check the parent folders of the folders all exist within the creation array. 
  41. if ( untrailingslashit($to) == $dir ) // Skip over the working directory, We know this exists (or will exist) 
  42. continue; 
  43. if ( strpos($dir, $to) === false ) // If the directory is not within the working directory, Skip it 
  44. continue; 
  45.  
  46. $parent_folder = dirname($dir); 
  47. while ( !empty($parent_folder) && untrailingslashit($to) != $parent_folder && !in_array($parent_folder, $needed_dirs) ) { 
  48. $needed_dirs[] = $parent_folder; 
  49. $parent_folder = dirname($parent_folder); 
  50. asort($needed_dirs); 
  51.  
  52. // Create those directories if need be: 
  53. foreach ( $needed_dirs as $_dir ) { 
  54. // Only check to see if the Dir exists upon creation failure. Less I/O this way. 
  55. if ( ! $wp_filesystem->mkdir( $_dir, FS_CHMOD_DIR ) && ! $wp_filesystem->is_dir( $_dir ) ) { 
  56. return new WP_Error( 'mkdir_failed_ziparchive', __( 'Could not create directory.' ), substr( $_dir, strlen( $to ) ) ); 
  57. unset($needed_dirs); 
  58.  
  59. for ( $i = 0; $i < $z->numFiles; $i++ ) { 
  60. if ( ! $info = $z->statIndex($i) ) 
  61. return new WP_Error( 'stat_failed_ziparchive', __( 'Could not retrieve file from archive.' ) ); 
  62.  
  63. if ( '/' == substr($info['name'], -1) ) // directory 
  64. continue; 
  65.  
  66. if ( '__MACOSX/' === substr($info['name'], 0, 9) ) // Don't extract the OS X-created __MACOSX directory files 
  67. continue; 
  68.  
  69. $contents = $z->getFromIndex($i); 
  70. if ( false === $contents ) 
  71. return new WP_Error( 'extract_failed_ziparchive', __( 'Could not extract file from archive.' ), $info['name'] ); 
  72.  
  73. if ( ! $wp_filesystem->put_contents( $to . $info['name'], $contents, FS_CHMOD_FILE) ) 
  74. return new WP_Error( 'copy_failed_ziparchive', __( 'Could not copy file.' ), $info['name'] ); 
  75.  
  76. $z->close(); 
  77.  
  78. return true;