@ -61,7 +61,11 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
private $rootData;
private $rootData;
private $hasPartialPackages;
private $hasPartialPackages;
private $partialPackagesByName;
private $partialPackagesByName;
private $versionParser;
/**
* TODO v3 should make this private once we can drop PHP 5.3 support
* @private
*/
public $versionParser;
public function __construct(array $repoConfig, IOInterface $io, Config $config, HttpDownloader $httpDownloader, EventDispatcher $eventDispatcher = null)
public function __construct(array $repoConfig, IOInterface $io, Config $config, HttpDownloader $httpDownloader, EventDispatcher $eventDispatcher = null)
{
{
@ -414,6 +418,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
$this->providers[$name] = array();
$this->providers[$name] = array();
foreach ($packages['packages'] as $versions) {
foreach ($packages['packages'] as $versions) {
$versionsToLoad = array();
foreach ($versions as $version) {
foreach ($versions as $version) {
if (!$loadingPartialPackage & & $this->hasPartialPackages & & isset($this->partialPackagesByName[$version['name']])) {
if (!$loadingPartialPackage & & $this->hasPartialPackages & & isset($this->partialPackagesByName[$version['name']])) {
continue;
continue;
@ -440,40 +445,44 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
continue;
continue;
}
}
// load acceptable packages in the providers
$versionsToLoad[] = $version;
$package = $this->createPackage($version, 'Composer\Package\CompletePackage');
}
$package->setRepository($this);
}
if ($package instanceof AliasPackage) {
// load acceptable packages in the providers
$aliased = $package->getAliasOf();
$loadedPackages = $this->createPackages($versionsToLoad, 'Composer\Package\CompletePackage');
$aliased->setRepository($this);
foreach ($loadedPackages as $package) {
$package->setRepository($this);
$this->providers[$name][$version['uid']] = $aliased;
if ($package instanceof AliasPackage) {
$this->providers[$name][$version['uid'].'-alias'] = $package;
$aliased = $package->getAliasOf();
$aliased->setRepository($this);
// override provider with its alias so it can be expanded in the if block above
$this->providers[$name][$version['uid']] = $aliased;
$this->providersByUid[$version['uid']] = $package;
$this->providers[$name][$version['uid'].'-alias'] = $package;
} else {
$this->providers[$name][$version['uid']] = $package;
$this->providersByUid[$version['uid']] = $package;
}
// handle root package aliases
// override provider with its alias so it can be expanded in the if block above
unset($rootAliasData);
$this->providersByUid[$version['uid']] = $package;
} else {
$this->providers[$name][$version['uid']] = $package;
$this->providersByUid[$version['uid']] = $package;
}
if (isset($this->rootAliases[$package->getName()][$package->getVersion()])) {
// handle root package aliases
$rootAliasData = $this->rootAliases[$package->getName()][$package->getVersion()];
unset($rootAliasData);
} elseif ($package instanceof AliasPackage & & isset($this->rootAliases[$package->getName()][$package->getAliasOf()->getVersion()])) {
$rootAliasData = $this->rootAliases[$package->getName()][$package->getAliasOf()->getVersion()];
}
if (isset($rootAliasData)) {
if (isset($this->rootAliases[$package->getName()][$package->getVersion()])) {
$alias = $this->createAliasPackage($package, $rootAliasData['alias_normalized'], $rootAliasData['alias']);
$rootAliasData = $this->rootAliases[$package->getName()][$package->getVersion()];
$alias->setRepository($this);
} elseif ($package instanceof AliasPackage & & isset($this->rootAliases[$package->getName()][$package->getAliasOf()->getVersion()])) {
$rootAliasData = $this->rootAliases[$package->getName()][$package->getAliasOf()->getVersion()];
}
$this->providers[$name][$version['uid'].'-root'] = $alias;
if (isset($rootAliasData)) {
$this->providersByUid[$version['uid'].'-root'] = $alias;
$alias = $this->createAliasPackage($package, $rootAliasData['alias_normalized'], $rootAliasData['alias']);
}
$alias->setRepository($this);
$this->providers[$name][$version['uid'].'-root'] = $alias;
$this->providersByUid[$version['uid'].'-root'] = $alias;
}
}
}
}
}
}
@ -501,8 +510,8 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
$repoData = $this->loadDataFromServer();
$repoData = $this->loadDataFromServer();
foreach ($repoData as $package) {
foreach ($this->createPackages($ repoData, 'Composer\Package\CompletePackage') as $package) {
$this->addPackage($this->createPackage($ package, 'Composer\Package\CompletePackage') );
$this->addPackage($package);
}
}
}
}
@ -545,6 +554,8 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
$this->asyncFetchFile($url, $cacheKey, $lastModified)
$this->asyncFetchFile($url, $cacheKey, $lastModified)
->then(function ($response) use (& $packages, $contents, $name, $constraint, $repo, $isPackageAcceptableCallable) {
->then(function ($response) use (& $packages, $contents, $name, $constraint, $repo, $isPackageAcceptableCallable) {
static $uniqKeys = array('version', 'version_normalized', 'source', 'dist', 'time');
if (true === $response) {
if (true === $response) {
$response = $contents;
$response = $contents;
}
}
@ -553,24 +564,37 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
return;
return;
}
}
$uniqKeys = array('version', 'version_normalized', 'source', 'dist', 'time' );
$versionsToLoad = array( );
foreach ($response['packages'][$name] as $version) {
foreach ($response['packages'][$name] as $version) {
if (isset($version['versions'])) {
if (isset($version['version_normalizeds'])) {
$baseVersion = $version;
foreach ($version['version_normalizeds'] as $index => $normalizedVersion) {
foreach ($uniqKeys as $key) {
if (!$repo->isVersionAcceptable($isPackageAcceptableCallable, $constraint, $name, $normalizedVersion)) {
unset($baseVersion[$key.'s']);
foreach ($uniqKeys as $key) {
}
unset($version[$key.'s'][$index]);
}
foreach ($version['versions'] as $index => $dummy) {
$unpackedVersion = $baseVersion;
foreach ($uniqKeys as $key) {
$unpackedVersion[$key] = $version[$key.'s'][$index];
}
}
}
$repo->createPackageIfAcceptable($packages, $isPackageAcceptableCallable, $unpackedVersion, $constraint);
if (count($version['version_normalizeds'])) {
$versionsToLoad[] = $version;
}
}
} else {
} else {
$repo->createPackageIfAcceptable($packages, $isPackageAcceptableCallable, $version, $constraint);
if (!isset($version['version_normalized'])) {
$version['version_normalized'] = $repo->versionParser->normalize($version['version']);
}
if ($repo->isVersionAcceptable($isPackageAcceptableCallable, $constraint, $name, $version['version_normalized'])) {
$versionsToLoad[] = $version;
}
}
}
$loadedPackages = $this->createPackages($versionsToLoad, 'Composer\Package\CompletePackage');
foreach ($loadedPackages as $package) {
$package->setRepository($this);
$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) {
}, function ($e) {
@ -592,27 +616,17 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
*
*
* @private
* @private
*/
*/
public function createPackageIfAcceptable(& $packages, $isPackageAcceptableCallable, $version, $constraint )
public function isVersionAcceptable($isPackageAcceptableCallable, $constraint, $name, $versionNormalized )
{
{
if (!call_user_func($isPackageAcceptableCallable, strtolower($version['name']), VersionParser::parseStability($version['version'] ))) {
if (!call_user_func($isPackageAcceptableCallable, strtolower($name), VersionParser::parseStability($versionNormalized ))) {
return;
return false ;
}
}
if (isset($version['version_normalized']) & & $constraint & & !$constraint->matches(new Constraint('==', $version['version_normalized'] ))) {
if ($constraint & & !$constraint->matches(new Constraint('==', $versionNormalized ))) {
return;
return false ;
}
}
// load acceptable packages in the providers
return true;
$package = $this->createPackage($version, 'Composer\Package\CompletePackage');
$package->setRepository($this);
// if there was no version_normalized, then we need to check now for the constraint
if (!$constraint || isset($version['version_normalized']) || $constraint->matches(new Constraint('==', $package->getVersion()))) {
$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();
}
}
}
}
protected function loadRootServerFile()
protected function loadRootServerFile()
@ -775,23 +789,37 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
return $packages;
return $packages;
}
}
protected function createPackage(array $data, $class = 'Composer\Package\CompletePackage')
/**
* TODO v3 should make this private once we can drop PHP 5.3 support
*
* @private
*/
public function createPackages(array $packages, $class = 'Composer\Package\CompletePackage')
{
{
if (!$packages) {
return;
}
try {
try {
if (!isset($data['notification-url'])) {
foreach ($packages as & $data) {
$data['notification-url'] = $this->notifyUrl;
if (!isset($data['notification-url'])) {
$data['notification-url'] = $this->notifyUrl;
}
}
}
$package = $this->loader->load($data, $class);
$packages = $this->loader->loadPackages($packages, $class);
if (isset($this->sourceMirrors[$package->getSourceType()])) {
$package->setSourceMirrors($this->sourceMirrors[$package->getSourceType()]);
foreach ($packages as $package) {
if (isset($this->sourceMirrors[$package->getSourceType()])) {
$package->setSourceMirrors($this->sourceMirrors[$package->getSourceType()]);
}
$package->setDistMirrors($this->distMirrors);
$this->configurePackageTransportOptions($package);
}
}
$package->setDistMirrors($this->distMirrors);
$this->configurePackageTransportOptions($package);
return $package;
return $packages;
} catch (\Exception $e) {
} catch (\Exception $e) {
throw new \RuntimeException('Could not load package '.(isset($data['name']) ? $data['name'] : json_encode($data )).' in '.$this->url.': ['.get_class($e).'] '.$e->getMessage(), 0, $e);
throw new \RuntimeException('Could not load packages '.(isset($packages[0]['name']) ? $packages[0]['name'] : json_encode($packages )).' in '.$this->url.': ['.get_class($e).'] '.$e->getMessage(), 0, $e);
}
}
}
}