Skip to content

Commit c1af27b

Browse files
[DependencyInjection] Add ContainerBuilder::willBeAvailable() to help with conditional configuration
1 parent 7c18ff7 commit c1af27b

File tree

3 files changed

+31
-1
lines changed

3 files changed

+31
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ CHANGELOG
99
* Add support for loading autoconfiguration rules via the `#[Autoconfigure]` and `#[AutoconfigureTag]` attributes on PHP 8
1010
* Add autoconfigurable attributes
1111
* Add support for per-env configuration in loaders
12+
* Add `ContainerBuilder::willBeAvailable()` to help with conditional configuration
1213

1314
5.2.0
1415
-----

Compiler/AbstractRecursivePass.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ private function getExpressionLanguage(): ExpressionLanguage
198198
{
199199
if (null === $this->expressionLanguage) {
200200
if (!class_exists(ExpressionLanguage::class)) {
201-
throw new LogicException('Unable to use expressions as the Symfony ExpressionLanguage component is not installed.');
201+
throw new LogicException('Unable to use expressions as the Symfony ExpressionLanguage component is not installed. Try running "composer require symfony/expression-language".');
202202
}
203203

204204
$providers = $this->container->getExpressionLanguageProviders();

ContainerBuilder.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Component\DependencyInjection;
1313

14+
use Composer\InstalledVersions;
1415
use Psr\Container\ContainerInterface as PsrContainerInterface;
1516
use Symfony\Component\Config\Resource\ClassExistenceResource;
1617
use Symfony\Component\Config\Resource\ComposerResource;
@@ -1467,6 +1468,34 @@ public function log(CompilerPassInterface $pass, string $message)
14671468
$this->getCompiler()->log($pass, $this->resolveEnvPlaceholders($message));
14681469
}
14691470

1471+
/**
1472+
* Checks whether a class is available and will remain available in the "no-dev" mode of Composer.
1473+
*
1474+
* When parent packages are provided and if any of them is in dev-only mode,
1475+
* the class will be considered available even if it is also in dev-only mode.
1476+
*/
1477+
final public static function willBeAvailable(string $package, string $class, array $parentPackages): bool
1478+
{
1479+
if (!class_exists($class) && !interface_exists($class, false) && !trait_exists($class, false)) {
1480+
return false;
1481+
}
1482+
1483+
if (!class_exists(InstalledVersions::class) || !InstalledVersions::isInstalled($package) || InstalledVersions::isInstalled($package, false)) {
1484+
return true;
1485+
}
1486+
1487+
// the package is installed but in dev-mode only, check if this applies to one of the parent packages too
1488+
1489+
$rootPackage = InstalledVersions::getRootPackage()['name'] ?? '';
1490+
foreach ($parentPackages as $parentPackage) {
1491+
if ($rootPackage === $parentPackage || (InstalledVersions::isInstalled($parentPackage) && !InstalledVersions::isInstalled($parentPackage, false))) {
1492+
return true;
1493+
}
1494+
}
1495+
1496+
return false;
1497+
}
1498+
14701499
/**
14711500
* Gets removed binding ids.
14721501
*

0 commit comments

Comments
 (0)