mirror of
https://github.com/phpbb/phpbb.git
synced 2025-10-12 15:34:31 +02:00
[ticket/17541] Ensure highest compat. ver. ext is installed
PHPBB-17541
This commit is contained in:
@@ -587,8 +587,149 @@ class installer
|
||||
$lockFile->write([]);
|
||||
}
|
||||
|
||||
// First pass write: base file with requested packages as provided
|
||||
$json_file->write($ext_json_data);
|
||||
$this->ext_json_file_backup = $ext_json_file_backup;
|
||||
|
||||
// Second pass: resolve and pin the highest compatible versions for unconstrained requested packages
|
||||
try
|
||||
{
|
||||
// Build a list of requested packages without explicit constraints
|
||||
$unconstrained = [];
|
||||
foreach ($packages as $name => $constraint)
|
||||
{
|
||||
// The $packages array can be either ['vendor/package' => '^1.2'] or ['vendor/package'] (numeric keys).
|
||||
if (is_int($name))
|
||||
{
|
||||
// Numeric key means just a name
|
||||
$pkgName = $constraint;
|
||||
$unconstrained[$pkgName] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If constraint is empty or '*' treat as unconstrained
|
||||
if ($constraint === '' || $constraint === '*' || $constraint === null)
|
||||
{
|
||||
$unconstrained[$name] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($unconstrained))
|
||||
{
|
||||
// Load composer on the just-written file so repositories and core constraints are available
|
||||
$extComposer = $this->get_composer($this->get_composer_ext_json_filename());
|
||||
|
||||
/** @var ConstraintInterface $core_constraint */
|
||||
$core_constraint = $extComposer->getPackage()->getRequires()['phpbb/phpbb']->getConstraint();
|
||||
$core_stability = $extComposer->getPackage()->getMinimumStability();
|
||||
|
||||
// Resolve highest compatible versions for each unconstrained package
|
||||
$pins = $this->resolve_highest_versions(array_keys($unconstrained), $extComposer, $core_constraint, $core_stability);
|
||||
|
||||
if (!empty($pins))
|
||||
{
|
||||
// Merge pins into require section, overwriting unconstrained entries
|
||||
foreach ($pins as $pkg => $version)
|
||||
{
|
||||
$ext_json_data['require'][$pkg] = $version;
|
||||
}
|
||||
|
||||
// Rewrite composer-ext.json with pinned versions
|
||||
$json_file->write($ext_json_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (\Exception $e)
|
||||
{
|
||||
// If resolution fails for any reason, keep the first-pass file intact (Composer will still resolve).
|
||||
// Intentionally swallow to avoid breaking installation flow.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the highest compatible versions for the given package names
|
||||
* based on repositories and phpBB/PHP constraints from the provided Composer instance.
|
||||
*
|
||||
* @param array $packageNames list of package names to resolve
|
||||
* @param Composer|PartialComposer $composer Composer instance configured with repositories
|
||||
* @param ConstraintInterface $core_constraint phpBB version constraint
|
||||
* @param string $core_stability minimum stability
|
||||
* @return array [packageName => prettyVersion]
|
||||
*/
|
||||
private function resolve_highest_versions(array $packageNames, $composer, ConstraintInterface $core_constraint, $core_stability): array
|
||||
{
|
||||
$io = new NullIO();
|
||||
|
||||
$compatible_packages = [];
|
||||
$repositories = $composer->getRepositoryManager()->getRepositories();
|
||||
|
||||
foreach ($repositories as $repository)
|
||||
{
|
||||
try
|
||||
{
|
||||
if ($repository instanceof ComposerRepository)
|
||||
{
|
||||
foreach ($packageNames as $name)
|
||||
{
|
||||
$versions = $repository->findPackages($name);
|
||||
if (!empty($versions))
|
||||
{
|
||||
$compatible_packages = $this->get_compatible_versions($compatible_packages, $core_constraint, $core_stability, $name, $versions);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Preload and filter by name for non-composer repositories
|
||||
$byName = [];
|
||||
foreach ($repository->getPackages() as $pkg)
|
||||
{
|
||||
$n = $pkg->getName();
|
||||
if (in_array($n, $packageNames, true))
|
||||
{
|
||||
$byName[$n][] = $pkg;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($byName as $name => $versions)
|
||||
{
|
||||
$compatible_packages = $this->get_compatible_versions($compatible_packages, $core_constraint, $core_stability, $name, $versions);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (\Exception $e)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$pins = [];
|
||||
foreach ($packageNames as $name)
|
||||
{
|
||||
if (empty($compatible_packages[$name]))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$package_versions = $compatible_packages[$name];
|
||||
|
||||
// Sort descending by normalized version
|
||||
usort($package_versions, function ($a, $b) {
|
||||
return version_compare($b->getVersion(), $a->getVersion());
|
||||
});
|
||||
|
||||
$highest = $package_versions[0];
|
||||
if ($highest instanceof CompleteAliasPackage)
|
||||
{
|
||||
$highest = $highest->getAliasOf();
|
||||
}
|
||||
|
||||
// Pin to the resolved highest compatible version using its pretty version
|
||||
$pins[$name] = $highest->getPrettyVersion();
|
||||
}
|
||||
|
||||
return $pins;
|
||||
}
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user