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;
public function __construct(string $app_root = NULL) {
if ($app_root === NULL) {
$app_root = \Drupal::hasService('kernel') ? \Drupal::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_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_version_requirement' key must be present in " . $filename);
}
}
try {
$parsed_info['core_incompatible'] = !Semver::satisfies(\Drupal::VERSION, $parsed_info['core_version_requirement']);
} catch (\UnexpectedValueException $exception) {
throw new InfoParserException("The 'core_version_requirement' constraint ({$parsed_info['core_version_requirement']}) is not a valid value in {$filename}");
}
if (isset($parsed_info['version']) && $parsed_info['version'] === 'VERSION') {
$parsed_info['version'] = \Drupal::VERSION;
}
$parsed_info += [
ExtensionLifecycle::LIFECYCLE_IDENTIFIER => ExtensionLifecycle::STABLE,
];
$lifecycle = $parsed_info[ExtensionLifecycle::LIFECYCLE_IDENTIFIER];
if (!ExtensionLifecycle::isValid($lifecycle)) {
$valid_values = [
ExtensionLifecycle::EXPERIMENTAL,
ExtensionLifecycle::STABLE,
ExtensionLifecycle::DEPRECATED,
ExtensionLifecycle::OBSOLETE,
];
throw new InfoParserException("'lifecycle: {$lifecycle}' is not valid in {$filename}. Valid values are: '" . implode("', '", $valid_values) . "'.");
}
if (in_array($lifecycle, [
ExtensionLifecycle::DEPRECATED,
ExtensionLifecycle::OBSOLETE,
], TRUE)) {
if (empty($parsed_info[ExtensionLifecycle::LIFECYCLE_LINK_IDENTIFIER])) {
throw new InfoParserException(sprintf("Extension %s (%s) has 'lifecycle: %s' but is missing a '%s' entry.", $parsed_info['name'], $filename, $lifecycle, ExtensionLifecycle::LIFECYCLE_LINK_IDENTIFIER));
}
if (!filter_var($parsed_info[ExtensionLifecycle::LIFECYCLE_LINK_IDENTIFIER], FILTER_VALIDATE_URL)) {
throw new InfoParserException(sprintf("Extension %s (%s) has a '%s' entry that is not a valid URL.", $parsed_info['name'], $filename, ExtensionLifecycle::LIFECYCLE_LINK_IDENTIFIER));
}
}
}
return $parsed_info;
}
protected function getRequiredKeys() {
return [
'type',
'name',
];
}
}