function InfoParserDynamic::parse

Same name and namespace in other branches
  1. 11.x core/lib/Drupal/Core/Extension/InfoParserDynamic.php \Drupal\Core\Extension\InfoParserDynamic::parse()
1 method overrides InfoParserDynamic::parse()
InfoParser::parse in core/lib/Drupal/Core/Extension/InfoParser.php
Parses Drupal module, theme and profile .info.yml files.

File

core/lib/Drupal/Core/Extension/InfoParserDynamic.php, line 44

Class

InfoParserDynamic
Parses dynamic .info.yml files that might change during the page request.

Namespace

Drupal\Core\Extension

Code

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) {
        // Core extensions do not need to specify core compatibility: they are
        // by definition compatible so a sensible default is used. Core
        // modules are allowed to provide these for testing purposes.
        $parsed_info['core_version_requirement'] = \Drupal::VERSION;
      }
      elseif (isset($parsed_info['package']) && $parsed_info['package'] === 'Testing') {
        // Modules in the testing package are exempt as well. This makes it
        // easier for contrib to use test modules.
        $parsed_info['core_version_requirement'] = \Drupal::VERSION;
      }
      elseif (!isset($parsed_info['core'])) {
        // Non-core extensions must specify core compatibility.
        throw new InfoParserException("The 'core_version_requirement' key must be present 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 the 'core_version_requirement' constraint does not satisfy any
      // Drupal 8 versions before 8.7.7 then 'core' cannot be set or it will
      // effectively support all versions of Drupal 8 because
      // 'core_version_requirement' will be ignored in previous versions.
      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);
      }
      // 'core_version_requirement' can not be used to specify Drupal 8
      // versions before 8.7.7 because these versions do not use the
      // 'core_version_requirement' key. Do not throw the exception if the
      // constraint also is satisfied by 8.0.0-alpha1 to allow constraints
      // such as '^8' or '^8 || ^9'.
      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}");
      }
    }
    if (isset($parsed_info['core']) && $parsed_info['core'] !== '8.x') {
      throw new InfoParserException("'core: {$parsed_info['core']}' is not supported. Use 'core_version_requirement' to specify core compatibility. Only 'core: 8.x' is supported to provide backwards compatibility for Drupal 8 when needed in {$filename}");
    }
    // Determine if the extension is compatible with the current version of
    // Drupal core.
    $core_version_constraint = $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;
    }
    $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;
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.