2011-05-06 17:55:49 +00:00
< ? php
/*
* This file is part of Composer .
*
* ( c ) Nils Adermann < naderman @ naderman . de >
* Jordi Boggiano < j . boggiano @ seld . be >
*
* For the full copyright and license information , please view the LICENSE
* file that was distributed with this source code .
*/
namespace Composer\Downloader ;
2012-10-21 15:56:57 +00:00
use Composer\Config ;
2012-11-10 22:17:36 +00:00
use Composer\Cache ;
2012-01-18 15:37:55 +00:00
use Composer\Util\ProcessExecutor ;
2012-01-18 16:11:26 +00:00
use Composer\IO\IOInterface ;
2012-03-29 13:08:47 +00:00
use ZipArchive ;
2011-05-06 17:55:49 +00:00
/**
* @ author Jordi Boggiano < j . boggiano @ seld . be >
*/
2012-02-17 22:10:02 +00:00
class ZipDownloader extends ArchiveDownloader
2011-05-06 17:55:49 +00:00
{
2012-01-18 15:37:55 +00:00
protected $process ;
2012-11-10 22:17:36 +00:00
public function __construct ( IOInterface $io , Config $config , Cache $cache = null , ProcessExecutor $process = null )
2012-01-18 15:37:55 +00:00
{
$this -> process = $process ? : new ProcessExecutor ;
2012-11-10 22:17:36 +00:00
parent :: __construct ( $io , $config , $cache );
2012-01-18 15:37:55 +00:00
}
2011-09-28 22:48:17 +00:00
protected function extract ( $file , $path )
2011-05-06 17:55:49 +00:00
{
2013-01-31 09:57:59 +00:00
$processError = null ;
// try to use unzip on *nix
if ( ! defined ( 'PHP_WINDOWS_VERSION_BUILD' )) {
$command = 'unzip ' . escapeshellarg ( $file ) . ' -d ' . escapeshellarg ( $path );
if ( 0 === $this -> process -> execute ( $command , $ignoredOutput )) {
return ;
}
$processError = 'Failed to execute ' . $command . " \n \n " . $this -> process -> getErrorOutput ();
}
2011-05-06 17:55:49 +00:00
if ( ! class_exists ( 'ZipArchive' )) {
2012-11-28 20:26:58 +00:00
// php.ini path is added to the error message to help users find the correct file
$iniPath = php_ini_loaded_file ();
if ( $iniPath ) {
$iniMessage = 'The php.ini used by your command-line PHP is: ' . $iniPath ;
} else {
$iniMessage = 'A php.ini file does not exist. You will have to create one.' ;
}
2013-02-11 21:55:14 +00:00
$error = " Could not decompress the archive, enable the PHP zip extension or install unzip. \n "
. $iniMessage . " \n " . $processError ;
2012-04-10 12:59:20 +00:00
2011-12-16 21:22:08 +00:00
if ( ! defined ( 'PHP_WINDOWS_VERSION_BUILD' )) {
2013-02-11 21:55:14 +00:00
$error = " Could not decompress the archive, enable the PHP zip extension. \n " . $iniMessage ;
2011-12-16 21:22:08 +00:00
}
2012-04-10 12:59:20 +00:00
throw new \RuntimeException ( $error );
2011-05-06 17:55:49 +00:00
}
2012-03-29 13:08:47 +00:00
$zipArchive = new ZipArchive ();
2011-05-06 17:55:49 +00:00
2011-09-28 22:48:17 +00:00
if ( true !== ( $retval = $zipArchive -> open ( $file ))) {
2013-07-29 20:00:12 +00:00
if ( ZipArchive :: ER_NOZIP === $retval ) {
@ copy ( $file , $copy = sys_get_temp_dir () . '/composer-zip-debug.zip' );
throw new \UnexpectedValueException ( $this -> getErrorMessage ( $retval , $file ) . ' filesize: ' . filesize ( $file ) . ', file copied to ' . $copy . ' for debugging, please report this and email us the file if possible' );
}
2012-03-29 13:08:47 +00:00
throw new \UnexpectedValueException ( $this -> getErrorMessage ( $retval , $file ));
2011-05-06 17:55:49 +00:00
}
2011-09-28 22:48:17 +00:00
2012-08-17 20:06:58 +00:00
if ( true !== $zipArchive -> extractTo ( $path )) {
throw new \RuntimeException ( " There was an error extracting the ZIP file. Corrupt file? " );
}
2011-09-28 22:48:17 +00:00
$zipArchive -> close ();
2011-05-06 17:55:49 +00:00
}
2012-03-29 12:19:41 +00:00
2012-03-29 12:22:26 +00:00
/**
2012-03-29 13:08:47 +00:00
* Give a meaningful error message to the user .
2012-03-29 12:22:26 +00:00
*
2012-05-22 10:07:08 +00:00
* @ param int $retval
* @ param string $file
2012-03-29 13:08:47 +00:00
* @ return string
2012-03-29 12:22:26 +00:00
*/
2012-03-29 13:08:47 +00:00
protected function getErrorMessage ( $retval , $file )
2012-03-29 12:19:41 +00:00
{
switch ( $retval ) {
2012-03-29 13:08:47 +00:00
case ZipArchive :: ER_EXISTS :
return sprintf ( " File '%s' already exists. " , $file );
case ZipArchive :: ER_INCONS :
return sprintf ( " Zip archive '%s' is inconsistent. " , $file );
case ZipArchive :: ER_INVAL :
return sprintf ( " Invalid argument (%s) " , $file );
case ZipArchive :: ER_MEMORY :
return sprintf ( " Malloc failure (%s) " , $file );
case ZipArchive :: ER_NOENT :
return sprintf ( " No such zip file: '%s' " , $file );
case ZipArchive :: ER_NOZIP :
return sprintf ( " '%s' is not a zip archive. " , $file );
case ZipArchive :: ER_OPEN :
return sprintf ( " Can't open zip file: %s " , $file );
case ZipArchive :: ER_READ :
return sprintf ( " Zip read error (%s) " , $file );
case ZipArchive :: ER_SEEK :
return sprintf ( " Zip seek error (%s) " , $file );
default :
return sprintf ( " '%s' is not a valid zip archive, got error code: %s " , $file , $retval );
2012-03-29 12:19:41 +00:00
}
}
2011-09-17 13:12:45 +00:00
}