function &download($params)
{
if (!count($params)) {
$a = array();
return $a;
}
if (!isset($this->_registry)) {
$this->_registry =& $this->config->getRegistry();
}
$channelschecked = array();
// convert all parameters into PEAR_Downloader_Package objects
foreach ($params as $i => $param) {
$params[$i] =& $this->newDownloaderPackage($this);
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$err = $params[$i]->initialize($param);
PEAR::staticPopErrorHandling();
if (!$err) {
// skip parameters that were missed by preferred_state
continue;
}
if (PEAR::isError($err)) {
if (!isset($this->_options['soft']) && $err->getMessage() !== '') {
$this->log(0, $err->getMessage());
}
$params[$i] = false;
if (is_object($param)) {
$param = $param->getChannel() . '/' . $param->getPackage();
}
if (!isset($this->_options['soft'])) {
$this->log(2, 'Package "' . $param . '" is not valid');
}
// Message logged above in a specific verbose mode, passing null to not show up on CLI
$this->pushError(null, PEAR_INSTALLER_SKIPPED);
} else {
do {
if ($params[$i] && $params[$i]->getType() == 'local') {
// bug #7090 skip channel.xml check for local packages
break;
}
if ($params[$i] && !isset($channelschecked[$params[$i]->getChannel()]) && !isset($this->_options['offline'])) {
$channelschecked[$params[$i]->getChannel()] = true;
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
if (!class_exists('System')) {
require_once 'System.php';
}
$curchannel =& $this->_registry->getChannel($params[$i]->getChannel());
if (PEAR::isError($curchannel)) {
PEAR::staticPopErrorHandling();
return $this->raiseError($curchannel);
}
if (PEAR::isError($dir = $this->getDownloadDir())) {
PEAR::staticPopErrorHandling();
break;
}
$mirror = $this->config->get('preferred_mirror', null, $params[$i]->getChannel());
$url = 'http://' . $mirror . '/channel.xml';
$a = $this->downloadHttp($url, $this->ui, $dir, null, $curchannel->lastModified());
PEAR::staticPopErrorHandling();
if (PEAR::isError($a) || !$a) {
// Attempt fallback to https automatically
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
$a = $this->downloadHttp('https://' . $mirror . '/channel.xml', $this->ui, $dir, null, $curchannel->lastModified());
PEAR::staticPopErrorHandling();
if (PEAR::isError($a) || !$a) {
break;
}
}
$this->log(0, 'WARNING: channel "' . $params[$i]->getChannel() . '" has ' . 'updated its protocols, use "' . PEAR_RUNTYPE . ' channel-update ' . $params[$i]->getChannel() . '" to update');
}
} while (false);
if ($params[$i] && !isset($this->_options['downloadonly'])) {
if (isset($this->_options['packagingroot'])) {
$checkdir = $this->_prependPath($this->config->get('php_dir', null, $params[$i]->getChannel()), $this->_options['packagingroot']);
} else {
$checkdir = $this->config->get('php_dir', null, $params[$i]->getChannel());
}
while ($checkdir && $checkdir != '/' && !file_exists($checkdir)) {
$checkdir = dirname($checkdir);
}
if ($checkdir == '.') {
$checkdir = '/';
}
if (!is_writeable($checkdir)) {
return PEAR::raiseError('Cannot install, php_dir for channel "' . $params[$i]->getChannel() . '" is not writeable by the current user');
}
}
}
}
unset($channelschecked);
PEAR_Downloader_Package::removeDuplicates($params);
if (!count($params)) {
$a = array();
return $a;
}
if (!isset($this->_options['nodeps']) && !isset($this->_options['offline'])) {
$reverify = true;
while ($reverify) {
$reverify = false;
foreach ($params as $i => $param) {
//PHP Bug 40768 / PEAR Bug #10944
//Nested foreaches fail in PHP 5.2.1
key($params);
$ret = $params[$i]->detectDependencies($params);
if (PEAR::isError($ret)) {
$reverify = true;
$params[$i] = false;
PEAR_Downloader_Package::removeDuplicates($params);
if (!isset($this->_options['soft'])) {
$this->log(0, $ret->getMessage());
}
continue 2;
}
}
}
}
if (isset($this->_options['offline'])) {
$this->log(3, 'Skipping dependency download check, --offline specified');
}
if (!count($params)) {
$a = array();
return $a;
}
while (PEAR_Downloader_Package::mergeDependencies($params)) {
}
PEAR_Downloader_Package::removeDuplicates($params, true);
$errorparams = array();
if (PEAR_Downloader_Package::detectStupidDuplicates($params, $errorparams)) {
if (count($errorparams)) {
foreach ($errorparams as $param) {
$name = $this->_registry->parsedPackageNameToString($param->getParsedPackage());
$this->pushError('Duplicate package ' . $name . ' found', PEAR_INSTALLER_FAILED);
}
$a = array();
return $a;
}
}
PEAR_Downloader_Package::removeInstalled($params);
if (!count($params)) {
$this->pushError('No valid packages found', PEAR_INSTALLER_FAILED);
$a = array();
return $a;
}
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
$err = $this->analyzeDependencies($params);
PEAR::popErrorHandling();
if (!count($params)) {
$this->pushError('No valid packages found', PEAR_INSTALLER_FAILED);
$a = array();
return $a;
}
$ret = array();
$newparams = array();
if (isset($this->_options['pretend'])) {
return $params;
}
$somefailed = false;
foreach ($params as $i => $package) {
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$pf =& $params[$i]->download();
PEAR::staticPopErrorHandling();
if (PEAR::isError($pf)) {
if (!isset($this->_options['soft'])) {
$this->log(1, $pf->getMessage());
$this->log(0, 'Error: cannot download "' . $this->_registry->parsedPackageNameToString($package->getParsedPackage(), true) . '"');
}
$somefailed = true;
continue;
}
$newparams[] =& $params[$i];
$ret[] = array('file' => $pf->getArchiveFile(), 'info' => &$pf, 'pkg' => $pf->getPackage());
}
if ($somefailed) {
// remove params that did not download successfully
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
$err = $this->analyzeDependencies($newparams, true);
PEAR::popErrorHandling();
if (!count($newparams)) {
$this->pushError('Download failed', PEAR_INSTALLER_FAILED);
$a = array();
return $a;
}
}
$this->_downloadedPackages = $ret;
return $newparams;
}