InstalledPackage.php
Namespace
Drupal\package_managerFile
-
core/
modules/ package_manager/ src/ InstalledPackage.php
View source
<?php
declare (strict_types=1);
namespace Drupal\package_manager;
use Drupal\Component\Serialization\Yaml;
/**
* A value object that represents an installed Composer package.
*/
final class InstalledPackage {
/**
* Constructs an InstalledPackage object.
*
* @param string $name
* The package name.
* @param string $version
* The package version.
* @param string|null $path
* The package path, or NULL if the package type is `metapackage`.
* @param string $type
* The package type.
*/
private function __construct(string $name, string $version, ?string $path, string $type) {
}
/**
* Create an installed package object from an array.
*
* @param array $data
* The package data.
*
* @return static
*/
public static function createFromArray(array $data) : static {
$path = isset($data['path']) ? realpath($data['path']) : NULL;
// Fall back to `library`.
// @see https://getcomposer.org/doc/04-schema.md#type
$type = $data['type'] ?? 'library';
assert(($type === 'metapackage') === is_null($path), 'Metapackage install path must be NULL.');
return new static($data['name'], $data['version'], $path, $type);
}
/**
* Returns the Drupal project name for this package.
*
* This assumes that drupal.org adds a `project` key to every `.info.yml` file
* in the package, regardless of where they are in the package's directory
* structure. The package name is irrelevant except for checking that the
* vendor is `drupal`. For example, if the project key in the info file were
* `my_module`, and the package name were `drupal/whatever`, and this method
* would return `my_module`.
*
* @return string|null
* The name of the Drupal project installed by this package, or NULL if:
* - The package type is not one of `drupal-module`, `drupal-theme`, or
* `drupal-profile`.
* - The package's vendor is not `drupal`.
* - The project name could not otherwise be determined.
*
* @throws \UnexpectedValueException
* Thrown if the same project name exists in more than one package.
*/
public function getProjectName() : ?string {
// Only consider packages which are packaged by drupal.org and will be
// known to the core Update module.
$drupal_package_types = [
'drupal-module',
'drupal-theme',
'drupal-profile',
];
if ($this->path && str_starts_with($this->name, 'drupal/') && in_array($this->type, $drupal_package_types, TRUE)) {
return $this->scanForProjectName();
}
return NULL;
}
/**
* Scans a given path to determine the Drupal project name.
*
* The path will be scanned recursively for `.info.yml` files containing a
* `project` key.
*
* @return string|null
* The name of the project, as declared in the first found `.info.yml` which
* contains a `project` key, or NULL if none was found.
*/
private function scanForProjectName() : ?string {
$iterator = new \RecursiveDirectoryIterator($this->path);
$iterator = new \RecursiveIteratorIterator($iterator);
$iterator = new \RegexIterator($iterator, '/.+\\.info\\.yml$/', \RegexIterator::GET_MATCH);
foreach ($iterator as $match) {
$info = file_get_contents($match[0]);
$info = Yaml::decode($info);
if (!empty($info['project'])) {
return $info['project'];
}
}
return NULL;
}
}
Classes
Title | Deprecated | Summary |
---|---|---|
InstalledPackage | A value object that represents an installed Composer package. |
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.