InfoParserDynamic.php in Drupal 8
File
core/lib/Drupal/Core/Extension/InfoParserDynamic.php
View source
<?php
namespace Drupal\Core\Extension;
use Composer\Semver\Semver;
use Drupal\Component\Serialization\Exception\InvalidDataTypeException;
use Drupal\Core\Serialization\Yaml;
class InfoParserDynamic implements InfoParserInterface {
protected $root;
const FIRST_CORE_VERSION_REQUIREMENT_SUPPORTED_VERSION = '8.7.7';
public function __construct(string $app_root = NULL) {
if ($app_root === NULL) {
$app_root = \Drupal::hasService('app.root') ? (string) \Drupal::service('app.root') : DRUPAL_ROOT;
}
$this->root = $app_root;
}
public function parse($filename) {
if (!file_exists($filename)) {
$parsed_info = [];
}
else {
try {
$parsed_info = Yaml::decode(file_get_contents($filename));
} catch (InvalidDataTypeException $e) {
throw new InfoParserException("Unable to parse {$filename} " . $e
->getMessage());
}
$missing_keys = array_diff($this
->getRequiredKeys(), array_keys($parsed_info));
if (!empty($missing_keys)) {
throw new InfoParserException('Missing required keys (' . implode(', ', $missing_keys) . ') in ' . $filename);
}
if (!isset($parsed_info['core']) && !isset($parsed_info['core_version_requirement'])) {
if (strpos($filename, 'core/') === 0 || strpos($filename, $this->root . '/core/') === 0) {
$parsed_info['core_version_requirement'] = \Drupal::VERSION;
}
elseif (isset($parsed_info['package']) && $parsed_info['package'] === 'Testing') {
$parsed_info['core_version_requirement'] = \Drupal::VERSION;
}
else {
throw new InfoParserException("The 'core' or the 'core_version_requirement' key must be present in " . $filename);
}
}
if (isset($parsed_info['core']) && !preg_match("/^\\d\\.x\$/", $parsed_info['core'])) {
throw new InfoParserException("Invalid 'core' value \"{$parsed_info['core']}\" in " . $filename);
}
if (isset($parsed_info['core_version_requirement'])) {
try {
$supports_pre_core_version_requirement_version = static::isConstraintSatisfiedByPreviousVersion($parsed_info['core_version_requirement'], static::FIRST_CORE_VERSION_REQUIREMENT_SUPPORTED_VERSION);
} catch (\UnexpectedValueException $e) {
throw new InfoParserException("The 'core_version_requirement' constraint ({$parsed_info['core_version_requirement']}) is not a valid value in {$filename}");
}
if (!$supports_pre_core_version_requirement_version && isset($parsed_info['core'])) {
throw new InfoParserException("The 'core_version_requirement' constraint ({$parsed_info['core_version_requirement']}) requires the 'core' key not be set in " . $filename);
}
if ($supports_pre_core_version_requirement_version && !Semver::satisfies('8.0.0-alpha1', $parsed_info['core_version_requirement'])) {
throw new InfoParserException("The 'core_version_requirement' can not be used to specify compatibility for a specific version before " . static::FIRST_CORE_VERSION_REQUIREMENT_SUPPORTED_VERSION . " in {$filename}");
}
}
$core_version_constraint = isset($parsed_info['core_version_requirement']) ? $parsed_info['core_version_requirement'] : $parsed_info['core'];
$parsed_info['core_incompatible'] = !Semver::satisfies(\Drupal::VERSION, $core_version_constraint);
if (isset($parsed_info['version']) && $parsed_info['version'] === 'VERSION') {
$parsed_info['version'] = \Drupal::VERSION;
}
if ($parsed_info['type'] === 'profile' && isset($parsed_info['dependencies']) && !array_key_exists('install', $parsed_info)) {
global $install_state;
if (isset($install_state['parameters']['profile'])) {
$pattern = '@' . preg_quote(DIRECTORY_SEPARATOR . $install_state['parameters']['profile'] . '.info.yml') . '$@';
if (preg_match($pattern, $filename)) {
@trigger_error("The install profile {$filename} only implements a 'dependencies' key. As of Drupal 8.6.0 profile's support a new 'install' key for modules that should be installed but not depended on. See https://www.drupal.org/node/2952947.", E_USER_DEPRECATED);
}
}
$parsed_info['install'] = $parsed_info['dependencies'];
$parsed_info['dependencies'] = [];
}
}
return $parsed_info;
}
protected function getRequiredKeys() {
return [
'type',
'name',
];
}
protected static function isConstraintSatisfiedByPreviousVersion($constraint, $version) {
static $evaluated_constraints = [];
if (!isset($evaluated_constraints[$constraint][$version])) {
$evaluated_constraints[$constraint][$version] = FALSE;
foreach (static::getAllPreviousCoreVersions($version) as $previous_version) {
if (Semver::satisfies($previous_version, $constraint)) {
$evaluated_constraints[$constraint][$version] = TRUE;
break;
}
}
}
return $evaluated_constraints[$constraint][$version];
}
protected static function getAllPreviousCoreVersions($version) {
static $versions_lists = [];
if (empty($versions_lists[$version])) {
foreach (range(0, 7) as $minor) {
foreach (range(0, 27) as $patch) {
$patch_version = "8.{$minor}.{$patch}";
if ($patch_version === $version) {
$versions_lists[$version] = array_reverse($versions_lists[$version]);
return $versions_lists[$version];
}
if ($patch === 0) {
foreach ([
'alpha',
'beta',
'rc',
] as $prerelease) {
foreach (range(0, 16) as $prerelease_number) {
$versions_lists[$version][] = "{$patch_version}-{$prerelease}{$prerelease_number}";
}
}
}
$versions_lists[$version][] = $patch_version;
}
}
}
return $versions_lists[$version];
}
}
Classes
Name |
Description |
InfoParserDynamic |
Parses dynamic .info.yml files that might change during the page request. |