class InfoParserDynamic

Same name in other branches
  1. 9 core/lib/Drupal/Core/Extension/InfoParserDynamic.php \Drupal\Core\Extension\InfoParserDynamic
  2. 8.9.x core/lib/Drupal/Core/Extension/InfoParserDynamic.php \Drupal\Core\Extension\InfoParserDynamic
  3. 10 core/lib/Drupal/Core/Extension/InfoParserDynamic.php \Drupal\Core\Extension\InfoParserDynamic

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

Hierarchy

Expanded class hierarchy of InfoParserDynamic

2 files declare their use of InfoParserDynamic
InstallCommand.php in core/lib/Drupal/Core/Command/InstallCommand.php
UpdateUploadTest.php in core/modules/update/tests/src/Functional/UpdateUploadTest.php

File

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

Namespace

Drupal\Core\Extension
View source
class InfoParserDynamic implements InfoParserInterface {
    
    /**
     * InfoParserDynamic constructor.
     *
     * @param string $root
     *   The root directory of the Drupal installation.
     */
    public function __construct(string $root) {
    }
    
    /**
     * {@inheritdoc}
     */
    public function parse($filename) {
        if (!file_exists($filename)) {
            throw new InfoParserException("Unable to parse {$filename} as it does not exist");
        }
        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 (str_starts_with($filename, 'core/') || str_starts_with($filename, $this->root . '/core/')) {
                // 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;
            }
            else {
                // Non-core extensions must specify core compatibility.
                throw new InfoParserException("The 'core_version_requirement' key must be present in " . $filename);
            }
        }
        // Determine if the extension is compatible with the current version of
        // Drupal core.
        try {
            $parsed_info['core_incompatible'] = !Semver::satisfies(\Drupal::VERSION, $parsed_info['core_version_requirement']);
        } catch (\UnexpectedValueException) {
            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;
    }
    
    /**
     * Returns an array of keys required to exist in .info.yml file.
     *
     * @return array
     *   An array of required keys.
     */
    protected function getRequiredKeys() {
        return [
            'type',
            'name',
        ];
    }

}

Members

Title Sort descending Modifiers Object type Summary Overriden Title Overrides
InfoParserDynamic::getRequiredKeys protected function Returns an array of keys required to exist in .info.yml file.
InfoParserDynamic::parse public function Overrides InfoParserInterface::parse 1
InfoParserDynamic::__construct public function InfoParserDynamic constructor. 1

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