View source
<?php
namespace Drupal\composer_manager;
class PackageManager implements PackageManagerInterface {
protected $root;
protected $packages = [];
public function __construct($root) {
$this->root = $root;
}
public function getCorePackage() {
if (!isset($this->packages['core'])) {
$this->packages['core'] = JsonFile::read($this->root . '/core/composer.json');
}
return $this->packages['core'];
}
public function getExtensionPackages() {
if (!isset($this->packages['extension'])) {
$listing = new ExtensionDiscovery($this->root);
$profiles = $listing
->scan('profile');
$profile_directories = array_map(function ($profile) {
return $profile
->getPath();
}, $profiles);
$listing
->setProfileDirectories($profile_directories);
$modules = $listing
->scan('module');
$extensions = $profiles + $modules;
$installed_packages = $this
->getInstalledPackages();
$installed_packages = array_map(function ($package) {
return $package['name'];
}, $installed_packages);
$this->packages['extension'] = [];
foreach ($extensions as $extension_name => $extension) {
$filename = $this->root . '/' . $extension
->getPath() . '/composer.json';
if (is_readable($filename)) {
$extension_package = JsonFile::read($filename);
if (empty($extension_package['name'])) {
continue;
}
if (empty($extension_package['require']) && empty($extension_package['require-dev'])) {
continue;
}
if (in_array($extension_package['name'], $installed_packages)) {
continue;
}
$extension_package['extra']['path'] = $extension
->getPath() . '/composer.json';
$this->packages['extension'][$extension_name] = $extension_package;
}
}
}
return $this->packages['extension'];
}
public function getInstalledPackages() {
if (!isset($this->packages['installed'])) {
$this->packages['installed'] = JsonFile::read($this->root . '/vendor/composer/installed.json');
}
return $this->packages['installed'];
}
public function getRequiredPackages() {
if (!isset($this->packages['required'])) {
$merged_extension_package = $this
->buildMergedExtensionPackage();
$packages = [];
foreach ($merged_extension_package['require'] as $package_name => $constraint) {
if (substr($package_name, 0, 7) != 'drupal/') {
$packages[$package_name] = [
'constraint' => $constraint,
];
}
}
foreach ($this
->getInstalledPackages() as $package) {
$package_name = $package['name'];
if (!isset($packages[$package_name])) {
continue;
}
$packages[$package_name] += [
'description' => !empty($package['description']) ? $package['description'] : '',
'homepage' => !empty($package['homepage']) ? $package['homepage'] : '',
'require' => !empty($package['require']) ? $package['require'] : [],
'version' => $package['version'],
];
if ($package['version'] == 'dev-master') {
$packages[$package_name]['version'] .= '#' . $package['source']['reference'];
}
}
$this->packages['required'] = $this
->processRequiredPackages($packages);
}
return $this->packages['required'];
}
protected function processRequiredPackages(array $packages) {
foreach ($packages as $package_name => $package) {
$packages[$package_name] += [
'constraint' => '',
'description' => '',
'homepage' => '',
'require' => [],
'required_by' => [],
'version' => '',
];
ksort($packages[$package_name]);
}
ksort($packages);
$extension_packages = $this
->getExtensionPackages();
foreach ($packages as $package_name => $package) {
foreach ($extension_packages as $extension_name => $extension_package) {
if (isset($extension_package['require'][$package_name])) {
$packages[$package_name]['required_by'] = [
$extension_package['name'],
];
break;
}
}
}
return $packages;
}
public function needsComposerUpdate() {
$needs_update = FALSE;
foreach ($this
->getRequiredPackages() as $package) {
if (empty($package['version']) || empty($package['required_by'])) {
$needs_update = TRUE;
break;
}
}
return $needs_update;
}
public function rebuildRootPackage() {
$root_package = JsonFile::read($this->root . '/composer.json');
$core_requirement = $root_package['replace']['drupal/core'];
$root_package['replace'] = [
'drupal/core' => $core_requirement,
];
$root_package['repositories'] = [];
$root_package['extra']['merge-plugin']['include'] = [
'core/composer.json',
];
foreach ($this
->getExtensionPackages() as $extension_package) {
$version = '8.*';
if (isset($extension_package['extra']['branch-alias']['dev-master'])) {
$version = $extension_package['extra']['branch-alias']['dev-master'];
}
$root_package['replace'][$extension_package['name']] = $version;
}
$root_package['repositories'][] = [
'type' => 'composer',
'url' => 'https://packagist.drupal-composer.org',
];
foreach ($this
->getExtensionPackages() as $extension_package) {
$root_package['extra']['merge-plugin']['include'][] = $extension_package['extra']['path'];
}
JsonFile::write($this->root . '/composer.json', $root_package);
}
protected function buildMergedExtensionPackage() {
$package = [
'require' => [],
'require-dev' => [],
];
$keys = array_keys($package);
foreach ($this
->getExtensionPackages() as $extension_package) {
foreach ($keys as $key) {
if (isset($extension_package[$key])) {
$package[$key] = array_merge($extension_package[$key], $package[$key]);
}
}
}
$package['require'] = $this
->filterPlatformPackages($package['require']);
$package['require-dev'] = $this
->filterPlatformPackages($package['require-dev']);
return $package;
}
protected function filterPlatformPackages($requirements) {
foreach ($requirements as $package => $constraint) {
if (strpos($package, '/') === FALSE) {
unset($requirements[$package]);
}
}
return $requirements;
}
}