diff --git a/src/Composer/Command/ShowCommand.php b/src/Composer/Command/ShowCommand.php
index 9604bdc71..5cb3fa860 100644
--- a/src/Composer/Command/ShowCommand.php
+++ b/src/Composer/Command/ShowCommand.php
@@ -317,8 +317,8 @@ EOT
} else {
$type = 'available';
}
- if ($repo instanceof ComposerRepository && $repo->hasProviders()) {
- foreach ($repo->getProviderNames() as $name) {
+ if ($repo instanceof ComposerRepository) {
+ foreach ($repo->getPackageNames() as $name) {
if (!$packageFilter || preg_match($packageFilter, $name)) {
$packages[$type][$name] = $name;
}
diff --git a/src/Composer/Repository/ComposerRepository.php b/src/Composer/Repository/ComposerRepository.php
index 89b7c78f6..ff2895564 100644
--- a/src/Composer/Repository/ComposerRepository.php
+++ b/src/Composer/Repository/ComposerRepository.php
@@ -35,13 +35,13 @@ use Composer\Semver\Constraint\EmptyConstraint;
*/
class ComposerRepository extends ArrayRepository implements ConfigurableRepositoryInterface
{
- protected $config;
- protected $repoConfig;
- protected $options;
- protected $url;
- protected $baseUrl;
- protected $io;
- protected $httpDownloader;
+ private $config;
+ private $repoConfig;
+ private $options;
+ private $url;
+ private $baseUrl;
+ private $io;
+ private $httpDownloader;
protected $cache;
protected $notifyUrl;
protected $searchUrl;
@@ -49,14 +49,14 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
protected $providersUrl;
protected $lazyProvidersUrl;
protected $providerListing;
- protected $providers = array();
- protected $providersByUid = array();
+ private $providers = array();
+ private $providersByUid = array();
protected $loader;
- protected $rootAliases;
- protected $allowSslDowngrade = false;
- protected $eventDispatcher;
- protected $sourceMirrors;
- protected $distMirrors;
+ private $rootAliases;
+ private $allowSslDowngrade = false;
+ private $eventDispatcher;
+ private $sourceMirrors;
+ private $distMirrors;
private $degradedMode = false;
private $rootData;
private $hasPartialPackages;
@@ -134,28 +134,23 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
$constraint = $this->versionParser->parseConstraints($constraint);
}
- // TODO we need a new way for the repo to report this v2 protocol somehow
if ($this->lazyProvidersUrl) {
+ if ($this->hasPartialPackages() && isset($this->partialPackagesByName[$name])) {
+ return $this->filterPackages($this->whatProvides($name), $name, $constraint, true);
+ }
+
return $this->loadAsyncPackages(array($name => $constraint), function ($name, $stability) {
return true;
});
}
+
if (!$hasProviders) {
return parent::findPackage($name, $constraint);
}
foreach ($this->getProviderNames() as $providerName) {
if ($name === $providerName) {
- $packages = $this->whatProvides($providerName);
- foreach ($packages as $package) {
- if ($name === $package->getName()) {
- $pkgConstraint = new Constraint('==', $package->getVersion());
- if ($constraint->matches($pkgConstraint)) {
- return $package;
- }
- }
- }
- break;
+ return $this->filterPackages($this->whatProvides($providerName), $name, $constraint, true);
}
}
}
@@ -168,40 +163,58 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
// this call initializes loadRootServerFile which is needed for the rest below to work
$hasProviders = $this->hasProviders();
- // TODO we need a new way for the repo to report this v2 protocol somehow
- if ($this->lazyProvidersUrl) {
- return $this->loadAsyncPackages(array($name => $constraint ?: new EmptyConstraint()), function ($name, $stability) {
- return true;
- });
- }
- if (!$hasProviders) {
- return parent::findPackages($name, $constraint);
- }
-
- // normalize name
$name = strtolower($name);
-
if (null !== $constraint && !$constraint instanceof ConstraintInterface) {
$constraint = $this->versionParser->parseConstraints($constraint);
}
- $packages = array();
+ if ($this->lazyProvidersUrl) {
+ if ($this->hasPartialPackages() && isset($this->partialPackagesByName[$name])) {
+ return $this->filterPackages($this->whatProvides($name), $name, $constraint);
+ }
+
+ return $this->loadAsyncPackages(array($name => $constraint ?: new EmptyConstraint()), function ($name, $stability) {
+ return true;
+ });
+ }
+
+ if (!$hasProviders) {
+ return parent::findPackages($name, $constraint);
+ }
foreach ($this->getProviderNames() as $providerName) {
if ($name === $providerName) {
- $candidates = $this->whatProvides($providerName);
- foreach ($candidates as $package) {
- if ($name === $package->getName()) {
- $pkgConstraint = new Constraint('==', $package->getVersion());
- if (null === $constraint || $constraint->matches($pkgConstraint)) {
- $packages[] = $package;
- }
- }
- }
- break;
+ return $this->filterPackages($this->whatProvides($providerName), $name, $constraint);
}
}
+ return array();
+ }
+
+ private function filterPackages(array $packages, $name, $constraint = null, $returnFirstMatch = false)
+ {
+ $packages = array();
+
+ foreach ($packages as $package) {
+ // TODO this check can be removed once providers are only what really has that name anyway
+ if ($name !== $package->getName()) {
+ continue;
+ }
+
+ $pkgConstraint = new Constraint('==', $package->getVersion());
+ if (null === $constraint || $constraint->matches($pkgConstraint)) {
+ if ($returnFirstMatch) {
+ return $package;
+ }
+
+ $packages[] = $package;
+ }
+ }
+
+ if ($returnFirstMatch) {
+ return null;
+ }
+
return $packages;
}
@@ -214,39 +227,63 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
return parent::getPackages();
}
+ public function getPackageNames()
+ {
+ if ($this->hasProviders()) {
+ return $this->getProviderNames();
+ }
+
+ // TODO implement new list API endpoint for repos somehow?
+ // TODO add getPackageNames to the RepositoryInterface perhaps? With filtering capability embedded?
+
+ return $this->getPackages();
+ }
+
public function loadPackages(array $packageNameMap, $isPackageAcceptableCallable)
{
// this call initializes loadRootServerFile which is needed for the rest below to work
$hasProviders = $this->hasProviders();
- // TODO we need a new way for the repo to report this v2 protocol somehow
- if ($this->lazyProvidersUrl) {
- return $this->loadAsyncPackages($packageNameMap, $isPackageAcceptableCallable);
- }
- if (!$hasProviders) {
+ if (!$hasProviders && !$this->hasPartialPackages() && !$this->lazyProvidersUrl) {
return parent::loadPackages($packageNameMap, $isPackageAcceptableCallable);
}
$packages = array();
- foreach ($packageNameMap as $name => $constraint) {
- $matches = array();
- $candidates = $this->whatProvides($name, false, $isPackageAcceptableCallable);
- foreach ($candidates as $candidate) {
- if ($candidate->getName() === $name && (!$constraint || $constraint->matches(new Constraint('==', $candidate->getVersion())))) {
- $matches[spl_object_hash($candidate)] = $candidate;
- if ($candidate instanceof AliasPackage && !isset($matches[spl_object_hash($candidate->getAliasOf())])) {
- $matches[spl_object_hash($candidate->getAliasOf())] = $candidate->getAliasOf();
- }
+
+ if ($hasProviders || $this->hasPartialPackages()) {
+ foreach ($packageNameMap as $name => $constraint) {
+ $matches = array();
+
+ if (!$hasProviders && !isset($this->partialPackagesByName[$name])) {
+ continue;
}
- }
- foreach ($candidates as $candidate) {
- if ($candidate instanceof AliasPackage) {
- if (isset($result[spl_object_hash($candidate->getAliasOf())])) {
+
+ $candidates = $this->whatProvides($name, $isPackageAcceptableCallable);
+ foreach ($candidates as $candidate) {
+ if ($candidate->getName() === $name && (!$constraint || $constraint->matches(new Constraint('==', $candidate->getVersion())))) {
$matches[spl_object_hash($candidate)] = $candidate;
+ if ($candidate instanceof AliasPackage && !isset($matches[spl_object_hash($candidate->getAliasOf())])) {
+ $matches[spl_object_hash($candidate->getAliasOf())] = $candidate->getAliasOf();
+ }
}
}
+ foreach ($candidates as $candidate) {
+ if ($candidate instanceof AliasPackage) {
+ if (isset($result[spl_object_hash($candidate->getAliasOf())])) {
+ $matches[spl_object_hash($candidate)] = $candidate;
+ }
+ }
+ }
+ $packages = array_merge($packages, $matches);
+
+ unset($packageNameMap[$name]);
}
- $packages = array_merge($packages, $matches);
+
+ return $packages;
+ }
+
+ if ($this->lazyProvidersUrl) {
+ $packages = array_merge($packages, $this->loadAsyncPackages($packageNameMap, $isPackageAcceptableCallable));
}
return $packages;
@@ -295,7 +332,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
return parent::search($query, $mode);
}
- public function getProviderNames()
+ private function getProviderNames()
{
$this->loadRootServerFile();
@@ -315,7 +352,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
return array();
}
- protected function configurePackageTransportOptions(PackageInterface $package)
+ private function configurePackageTransportOptions(PackageInterface $package)
{
foreach ($package->getDistUrls() as $url) {
if (strpos($url, $this->baseUrl) === 0) {
@@ -326,7 +363,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
}
}
- public function hasProviders()
+ private function hasProviders()
{
$this->loadRootServerFile();
@@ -335,21 +372,16 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
/**
* @param string $name package name
- * @param bool $bypassFilters If set to true, this bypasses the stability filtering, and forces a recompute without cache
* @param callable $isPackageAcceptableCallable
* @return array|mixed
*/
- public function whatProvides($name, $bypassFilters = false, $isPackageAcceptableCallable = null)
+ private function whatProvides($name, $isPackageAcceptableCallable = null)
{
- if (isset($this->providers[$name]) && !$bypassFilters) {
+ if (isset($this->providers[$name])) {
return $this->providers[$name];
}
- if ($this->hasPartialPackages && null === $this->partialPackagesByName) {
- $this->initializePartialPackages();
- }
-
- if (!$this->hasPartialPackages || !isset($this->partialPackagesByName[$name])) {
+ if (!$this->hasPartialPackages() || !isset($this->partialPackagesByName[$name])) {
// skip platform packages, root package and composer-plugin-api
if (preg_match(PlatformRepository::PLATFORM_PACKAGE_REGEX, $name) || '__root__' === $name || 'composer-plugin-api' === $name) {
return array();
@@ -420,7 +452,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
foreach ($packages['packages'] as $versions) {
$versionsToLoad = array();
foreach ($versions as $version) {
- if (!$loadingPartialPackage && $this->hasPartialPackages && isset($this->partialPackagesByName[$version['name']])) {
+ if (!$loadingPartialPackage && $this->hasPartialPackages() && isset($this->partialPackagesByName[$version['name']])) {
continue;
}
@@ -441,7 +473,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
}
}
} else {
- if (!$bypassFilters && $isPackageAcceptableCallable && !call_user_func($isPackageAcceptableCallable, strtolower($version['name']), VersionParser::parseStability($version['version']))) {
+ if ($isPackageAcceptableCallable && !call_user_func($isPackageAcceptableCallable, strtolower($version['name']), VersionParser::parseStability($version['version']))) {
continue;
}
@@ -489,15 +521,6 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
$result = $this->providers[$name];
- // clean up the cache because otherwise using this puts the repo in an inconsistent state with a polluted unfiltered cache
- // which is likely not an issue but might cause hard to track behaviors depending on how the repo is used
- if ($bypassFilters) {
- foreach ($this->providers[$name] as $uid => $provider) {
- unset($this->providersByUid[$uid]);
- }
- unset($this->providers[$name]);
- }
-
return $result;
}
@@ -533,76 +556,76 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
$packages = array();
$repo = $this;
- // TODO what if not, then throw?
- if ($this->lazyProvidersUrl) {
- foreach ($packageNames as $name => $constraint) {
- $name = strtolower($name);
+ if (!$this->lazyProvidersUrl) {
+ throw new \LogicException('loadAsyncPackages only supports v2 protocol composer repos with a metadata-url');
+ }
- // skip platform packages, root package and composer-plugin-api
- if (preg_match(PlatformRepository::PLATFORM_PACKAGE_REGEX, $name) || '__root__' === $name || 'composer-plugin-api' === $name) {
- continue;
- }
+ foreach ($packageNames as $name => $constraint) {
+ $name = strtolower($name);
- $url = str_replace('%package%', $name, $this->lazyProvidersUrl);
- $cacheKey = 'provider-'.strtr($name, '/', '$').'.json';
+ // skip platform packages, root package and composer-plugin-api
+ if (preg_match(PlatformRepository::PLATFORM_PACKAGE_REGEX, $name) || '__root__' === $name || 'composer-plugin-api' === $name) {
+ continue;
+ }
- $lastModified = null;
- if ($contents = $this->cache->read($cacheKey)) {
- $contents = json_decode($contents, true);
- $lastModified = isset($contents['last-modified']) ? $contents['last-modified'] : null;
- }
+ $url = str_replace('%package%', $name, $this->lazyProvidersUrl);
+ $cacheKey = 'provider-'.strtr($name, '/', '$').'.json';
- $this->asyncFetchFile($url, $cacheKey, $lastModified)
- ->then(function ($response) use (&$packages, $contents, $name, $constraint, $repo, $isPackageAcceptableCallable) {
- static $uniqKeys = array('version', 'version_normalized', 'source', 'dist', 'time');
+ $lastModified = null;
+ if ($contents = $this->cache->read($cacheKey)) {
+ $contents = json_decode($contents, true);
+ $lastModified = isset($contents['last-modified']) ? $contents['last-modified'] : null;
+ }
- if (true === $response) {
- $response = $contents;
- }
+ $this->asyncFetchFile($url, $cacheKey, $lastModified)
+ ->then(function ($response) use (&$packages, $contents, $name, $constraint, $repo, $isPackageAcceptableCallable) {
+ static $uniqKeys = array('version', 'version_normalized', 'source', 'dist', 'time');
- if (!isset($response['packages'][$name])) {
- return;
- }
+ if (true === $response) {
+ $response = $contents;
+ }
- $versionsToLoad = array();
- foreach ($response['packages'][$name] as $version) {
- if (isset($version['version_normalizeds'])) {
- foreach ($version['version_normalizeds'] as $index => $normalizedVersion) {
- if (!$repo->isVersionAcceptable($isPackageAcceptableCallable, $constraint, $name, $normalizedVersion)) {
- foreach ($uniqKeys as $key) {
- unset($version[$key.'s'][$index]);
- }
+ if (!isset($response['packages'][$name])) {
+ return;
+ }
+
+ $versionsToLoad = array();
+ foreach ($response['packages'][$name] as $version) {
+ if (isset($version['version_normalizeds'])) {
+ foreach ($version['version_normalizeds'] as $index => $normalizedVersion) {
+ if (!$repo->isVersionAcceptable($isPackageAcceptableCallable, $constraint, $name, $normalizedVersion)) {
+ foreach ($uniqKeys as $key) {
+ unset($version[$key.'s'][$index]);
}
}
- if (count($version['version_normalizeds'])) {
- $versionsToLoad[] = $version;
- }
- } else {
- if (!isset($version['version_normalized'])) {
- $version['version_normalized'] = $repo->versionParser->normalize($version['version']);
- }
+ }
+ if (count($version['version_normalizeds'])) {
+ $versionsToLoad[] = $version;
+ }
+ } else {
+ if (!isset($version['version_normalized'])) {
+ $version['version_normalized'] = $repo->versionParser->normalize($version['version']);
+ }
- if ($repo->isVersionAcceptable($isPackageAcceptableCallable, $constraint, $name, $version['version_normalized'])) {
- $versionsToLoad[] = $version;
- }
+ if ($repo->isVersionAcceptable($isPackageAcceptableCallable, $constraint, $name, $version['version_normalized'])) {
+ $versionsToLoad[] = $version;
}
}
+ }
- $loadedPackages = $repo->createPackages($versionsToLoad, 'Composer\Package\CompletePackage');
- foreach ($loadedPackages as $package) {
- $package->setRepository($repo);
+ $loadedPackages = $repo->createPackages($versionsToLoad, 'Composer\Package\CompletePackage');
+ foreach ($loadedPackages as $package) {
+ $package->setRepository($repo);
- $packages[spl_object_hash($package)] = $package;
- if ($package instanceof AliasPackage && !isset($packages[spl_object_hash($package->getAliasOf())])) {
- $packages[spl_object_hash($package->getAliasOf())] = $package->getAliasOf();
- }
+ $packages[spl_object_hash($package)] = $package;
+ if ($package instanceof AliasPackage && !isset($packages[spl_object_hash($package->getAliasOf())])) {
+ $packages[spl_object_hash($package->getAliasOf())] = $package->getAliasOf();
}
- }, function ($e) {
- // TODO use ->done() above instead with react/promise 2.0
- var_dump('Uncaught Ex', $e->getMessage());
- throw $e;
- });
- }
+ }
+ }, function ($e) {
+ // TODO use ->done() above instead with react/promise 2.0
+ throw $e;
+ });
}
$this->httpDownloader->wait();
@@ -684,12 +707,13 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
}
// metadata-url indiates V2 repo protocol so it takes over from all the V1 types
- // V2 only has lazyProviders and no ability to process anything else, plus support for async loading
+ // V2 only has lazyProviders and possibly partial packages, but no ability to process anything else,
+ // V2 also supports async loading
if (!empty($data['metadata-url'])) {
$this->lazyProvidersUrl = $this->canonicalizeUrl($data['metadata-url']);
$this->providersUrl = null;
$this->hasProviders = false;
- $this->hasPartialPackages = false;
+ $this->hasPartialPackages = !empty($data['packages']) && is_array($data['packages']);
$this->allowSslDowngrade = false;
unset($data['providers-url'], $data['providers'], $data['providers-includes']);
}
@@ -711,7 +735,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
return $this->rootData = $data;
}
- protected function canonicalizeUrl($url)
+ private function canonicalizeUrl($url)
{
if ('/' === $url[0]) {
return preg_replace('{(https?://[^/]+).*}i', '$1' . $url, $this->url);
@@ -720,14 +744,23 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
return $url;
}
- protected function loadDataFromServer()
+ private function loadDataFromServer()
{
$data = $this->loadRootServerFile();
return $this->loadIncludes($data);
}
- protected function loadProviderListings($data)
+ private function hasPartialPackages()
+ {
+ if ($this->hasPartialPackages && null === $this->partialPackagesByName) {
+ $this->initializePartialPackages();
+ }
+
+ return $this->hasPartialPackages;
+ }
+
+ private function loadProviderListings($data)
{
if (isset($data['providers'])) {
if (!is_array($this->providerListing)) {
@@ -752,7 +785,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
}
}
- protected function loadIncludes($data)
+ private function loadIncludes($data)
{
$packages = array();
@@ -924,7 +957,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
return $data;
}
- protected function fetchFileIfLastModified($filename, $cacheKey, $lastModifiedTime)
+ private function fetchFileIfLastModified($filename, $cacheKey, $lastModifiedTime)
{
$retries = 3;
while ($retries--) {
@@ -990,7 +1023,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
}
}
- protected function asyncFetchFile($filename, $cacheKey, $lastModifiedTime = null)
+ private function asyncFetchFile($filename, $cacheKey, $lastModifiedTime = null)
{
$retries = 3;
$httpDownloader = $this->httpDownloader;
@@ -1039,7 +1072,6 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
};
$reject = function ($e) use (&$retries, $httpDownloader, $filename, $options, &$reject, $accept, $io, $url, $cache, &$degradedMode) {
- var_dump('Caught8', $e->getMessage());
if ($e instanceof TransportException && $e->getStatusCode() === 404) {
return false;
}
diff --git a/src/Composer/Util/Http/CurlDownloader.php b/src/Composer/Util/Http/CurlDownloader.php
index 2528b9e3f..1ff8393c9 100644
--- a/src/Composer/Util/Http/CurlDownloader.php
+++ b/src/Composer/Util/Http/CurlDownloader.php
@@ -211,132 +211,127 @@ class CurlDownloader
}
$active = true;
- try {
- $this->checkCurlResult(curl_multi_exec($this->multiHandle, $active));
- if (-1 === curl_multi_select($this->multiHandle, $this->selectTimeout)) {
- // sleep in case select returns -1 as it can happen on old php versions or some platforms where curl does not manage to do the select
- usleep(150);
+ $this->checkCurlResult(curl_multi_exec($this->multiHandle, $active));
+ if (-1 === curl_multi_select($this->multiHandle, $this->selectTimeout)) {
+ // sleep in case select returns -1 as it can happen on old php versions or some platforms where curl does not manage to do the select
+ usleep(150);
+ }
+
+ while ($progress = curl_multi_info_read($this->multiHandle)) {
+ $curlHandle = $progress['handle'];
+ $i = (int) $curlHandle;
+ if (!isset($this->jobs[$i])) {
+ continue;
}
+ $progress = array_diff_key(curl_getinfo($curlHandle), self::$timeInfo);
+ $job = $this->jobs[$i];
+ unset($this->jobs[$i]);
+ curl_multi_remove_handle($this->multiHandle, $curlHandle);
+ $error = curl_error($curlHandle);
+ $errno = curl_errno($curlHandle);
+ curl_close($curlHandle);
- while ($progress = curl_multi_info_read($this->multiHandle)) {
- $curlHandle = $progress['handle'];
- $i = (int) $curlHandle;
- if (!isset($this->jobs[$i])) {
- continue;
+ $headers = null;
+ $statusCode = null;
+ $response = null;
+ try {
+// TODO progress
+ //$this->onProgress($curlHandle, $job['callback'], $progress, $job['progress']);
+ if (CURLE_OK !== $errno) {
+ throw new TransportException($error);
}
- $progress = array_diff_key(curl_getinfo($curlHandle), self::$timeInfo);
- $job = $this->jobs[$i];
- unset($this->jobs[$i]);
- curl_multi_remove_handle($this->multiHandle, $curlHandle);
- $error = curl_error($curlHandle);
- $errno = curl_errno($curlHandle);
- curl_close($curlHandle);
- $headers = null;
- $statusCode = null;
- $response = null;
- try {
-// TODO progress
- //$this->onProgress($curlHandle, $job['callback'], $progress, $job['progress']);
- if (CURLE_OK !== $errno) {
- throw new TransportException($error);
- }
+ $statusCode = $progress['http_code'];
+ rewind($job['headerHandle']);
+ $headers = explode("\r\n", rtrim(stream_get_contents($job['headerHandle'])));
+ fclose($job['headerHandle']);
- $statusCode = $progress['http_code'];
- rewind($job['headerHandle']);
- $headers = explode("\r\n", rtrim(stream_get_contents($job['headerHandle'])));
- fclose($job['headerHandle']);
+ // prepare response object
+ if ($job['filename']) {
+ fclose($job['bodyHandle']);
+ $response = new Response(array('url' => $progress['url']), $statusCode, $headers, $job['filename'].'~');
+ $this->io->writeError('['.$statusCode.'] '.$progress['url'], true, IOInterface::DEBUG);
+ } else {
+ rewind($job['bodyHandle']);
+ $contents = stream_get_contents($job['bodyHandle']);
+ fclose($job['bodyHandle']);
+ $response = new Response(array('url' => $progress['url']), $statusCode, $headers, $contents);
+ $this->io->writeError('['.$statusCode.'] '.$progress['url'], true, IOInterface::DEBUG);
+ }
- // prepare response object
- if ($job['filename']) {
- fclose($job['bodyHandle']);
- $response = new Response(array('url' => $progress['url']), $statusCode, $headers, $job['filename'].'~');
- $this->io->writeError('['.$statusCode.'] '.$progress['url'], true, IOInterface::DEBUG);
- } else {
- rewind($job['bodyHandle']);
- $contents = stream_get_contents($job['bodyHandle']);
- fclose($job['bodyHandle']);
- $response = new Response(array('url' => $progress['url']), $statusCode, $headers, $contents);
- $this->io->writeError('['.$statusCode.'] '.$progress['url'], true, IOInterface::DEBUG);
- }
-
- $result = $this->isAuthenticatedRetryNeeded($job, $response);
- if ($result['retry']) {
- if ($job['filename']) {
- @unlink($job['filename'].'~');
- }
-
- $this->restartJob($job, $job['url'], array('storeAuth' => $result['storeAuth']));
- continue;
- }
-
- // handle 3xx redirects, 304 Not Modified is excluded
- if ($statusCode >= 300 && $statusCode <= 399 && $statusCode !== 304 && $job['attributes']['redirects'] < $this->maxRedirects) {
- $location = $this->handleRedirect($job, $response);
- if ($location) {
- $this->restartJob($job, $location, array('redirects' => $job['attributes']['redirects'] + 1));
- continue;
- }
- }
-
- // fail 4xx and 5xx responses and capture the response
- if ($statusCode >= 400 && $statusCode <= 599) {
- throw $this->failResponse($job, $response, $response->getStatusMessage());
-// TODO progress
-// $this->io->overwriteError("Downloading (failed)", false);
- }
-
- if ($job['attributes']['storeAuth']) {
- $this->authHelper->storeAuth($job['origin'], $job['attributes']['storeAuth']);
- }
-
- // resolve promise
- if ($job['filename']) {
- rename($job['filename'].'~', $job['filename']);
- call_user_func($job['resolve'], true);
- } else {
- call_user_func($job['resolve'], $response);
- }
- } catch (\Exception $e) {
- if ($e instanceof TransportException && $headers) {
- $e->setHeaders($headers);
- $e->setStatusCode($statusCode);
- }
- if ($e instanceof TransportException && $response) {
- $e->setResponse($response->getBody());
- }
-
- if (is_resource($job['headerHandle'])) {
- fclose($job['headerHandle']);
- }
- if (is_resource($job['bodyHandle'])) {
- fclose($job['bodyHandle']);
- }
+ $result = $this->isAuthenticatedRetryNeeded($job, $response);
+ if ($result['retry']) {
if ($job['filename']) {
@unlink($job['filename'].'~');
}
- call_user_func($job['reject'], $e);
- }
- }
- foreach ($this->jobs as $i => $curlHandle) {
- if (!isset($this->jobs[$i])) {
+ $this->restartJob($job, $job['url'], array('storeAuth' => $result['storeAuth']));
continue;
}
- $curlHandle = $this->jobs[$i]['curlHandle'];
- $progress = array_diff_key(curl_getinfo($curlHandle), self::$timeInfo);
- if ($this->jobs[$i]['progress'] !== $progress) {
- $previousProgress = $this->jobs[$i]['progress'];
- $this->jobs[$i]['progress'] = $progress;
-
- // TODO
- //$this->onProgress($curlHandle, $this->jobs[$i]['callback'], $progress, $previousProgress);
+ // handle 3xx redirects, 304 Not Modified is excluded
+ if ($statusCode >= 300 && $statusCode <= 399 && $statusCode !== 304 && $job['attributes']['redirects'] < $this->maxRedirects) {
+ $location = $this->handleRedirect($job, $response);
+ if ($location) {
+ $this->restartJob($job, $location, array('redirects' => $job['attributes']['redirects'] + 1));
+ continue;
+ }
}
+
+ // fail 4xx and 5xx responses and capture the response
+ if ($statusCode >= 400 && $statusCode <= 599) {
+ throw $this->failResponse($job, $response, $response->getStatusMessage());
+// TODO progress
+// $this->io->overwriteError("Downloading (failed)", false);
+ }
+
+ if ($job['attributes']['storeAuth']) {
+ $this->authHelper->storeAuth($job['origin'], $job['attributes']['storeAuth']);
+ }
+
+ // resolve promise
+ if ($job['filename']) {
+ rename($job['filename'].'~', $job['filename']);
+ call_user_func($job['resolve'], true);
+ } else {
+ call_user_func($job['resolve'], $response);
+ }
+ } catch (\Exception $e) {
+ if ($e instanceof TransportException && $headers) {
+ $e->setHeaders($headers);
+ $e->setStatusCode($statusCode);
+ }
+ if ($e instanceof TransportException && $response) {
+ $e->setResponse($response->getBody());
+ }
+
+ if (is_resource($job['headerHandle'])) {
+ fclose($job['headerHandle']);
+ }
+ if (is_resource($job['bodyHandle'])) {
+ fclose($job['bodyHandle']);
+ }
+ if ($job['filename']) {
+ @unlink($job['filename'].'~');
+ }
+ call_user_func($job['reject'], $e);
+ }
+ }
+
+ foreach ($this->jobs as $i => $curlHandle) {
+ if (!isset($this->jobs[$i])) {
+ continue;
+ }
+ $curlHandle = $this->jobs[$i]['curlHandle'];
+ $progress = array_diff_key(curl_getinfo($curlHandle), self::$timeInfo);
+
+ if ($this->jobs[$i]['progress'] !== $progress) {
+ $previousProgress = $this->jobs[$i]['progress'];
+ $this->jobs[$i]['progress'] = $progress;
+
+ // TODO
+ //$this->onProgress($curlHandle, $this->jobs[$i]['callback'], $progress, $previousProgress);
}
- } catch (\Exception $e) {
- // TODO
- var_dump('Caught2', get_class($e), $e->getMessage(), $e);die;
}
}
diff --git a/tests/Composer/Test/Repository/ComposerRepositoryTest.php b/tests/Composer/Test/Repository/ComposerRepositoryTest.php
index 3594de101..552c767a5 100644
--- a/tests/Composer/Test/Repository/ComposerRepositoryTest.php
+++ b/tests/Composer/Test/Repository/ComposerRepositoryTest.php
@@ -153,7 +153,9 @@ class ComposerRepositoryTest extends TestCase
),
));
- $packages = $repo->whatProvides('a', false, array($this, 'isPackageAcceptableReturnTrue'));
+ $reflMethod = new \ReflectionMethod($repo, 'whatProvides');
+ $reflMethod->setAccessible(true);
+ $packages = $reflMethod->invoke($repo, 'a', array($this, 'isPackageAcceptableReturnTrue'));
$this->assertCount(7, $packages);
$this->assertEquals(array('1', '1-alias', '2', '2-alias', '2-root', '3', '3-root'), array_keys($packages));