Skip to main content
Drupal API
User account menu
  • Log in

Breadcrumb

  1. Drupal Core 11.1.x

Plugin.php

Same filename in this branch
  1. 11.1.x vendor/dealerdirect/phpcodesniffer-composer-installer/src/Plugin.php
  2. 11.1.x vendor/php-http/discovery/src/Composer/Plugin.php
  3. 11.1.x vendor/composer/installers/src/Composer/Installers/Plugin.php
  4. 11.1.x vendor/tbachert/spi/src/Composer/Plugin.php
  5. 11.1.x composer/Plugin/Scaffold/Plugin.php
  6. 11.1.x core/lib/Drupal/Component/Annotation/Plugin.php
  7. 11.1.x core/lib/Drupal/Component/Plugin/Attribute/Plugin.php

Namespace

PHPStan\ExtensionInstaller

File

vendor/phpstan/extension-installer/src/Plugin.php

View source
<?php

declare (strict_types=1);
namespace PHPStan\ExtensionInstaller;

use Composer\Composer;
use Composer\EventDispatcher\EventSubscriberInterface;
use Composer\IO\IOInterface;
use Composer\Plugin\PluginInterface;
use Composer\Script\Event;
use Composer\Script\ScriptEvents;
use Composer\Semver\Constraint\ConstraintInterface;
use Composer\Semver\Constraint\MultiConstraint;
use Composer\Semver\Intervals;
use Composer\Util\Filesystem;
use function array_key_exists;
use function array_keys;
use function class_exists;
use function count;
use function dirname;
use function file_exists;
use function file_put_contents;
use function getcwd;
use function in_array;
use function is_file;
use function ksort;
use function md5;
use function md5_file;
use function sort;
use function sprintf;
use function strpos;
use function var_export;
use const DIRECTORY_SEPARATOR;
final class Plugin implements PluginInterface, EventSubscriberInterface {
    
    /** @var string */
    private static $generatedFileTemplate = <<<'PHP'
<?php declare(strict_types = 1);

namespace PHPStan\ExtensionInstaller;

/**
 * This class is generated by phpstan/extension-installer.
 * @internal
 */
final class GeneratedConfig
{

	public const EXTENSIONS = %s;

	public const NOT_INSTALLED = %s;

	/** @var string|null */
	public const PHPSTAN_VERSION_CONSTRAINT = %s;

	private function __construct()
	{
	}

}

PHP;
    public function activate(Composer $composer, IOInterface $io) : void {
        // noop
    }
    public function deactivate(Composer $composer, IOInterface $io) : void {
        // noop
    }
    public function uninstall(Composer $composer, IOInterface $io) : void {
        // noop
    }
    
    /**
     * @return array<string, string>
     */
    public static function getSubscribedEvents() : array {
        return [
            ScriptEvents::POST_INSTALL_CMD => 'process',
            ScriptEvents::POST_UPDATE_CMD => 'process',
        ];
    }
    public function process(Event $event) : void {
        $io = $event->getIO();
        if (!file_exists(__DIR__)) {
            $io->write('<info>phpstan/extension-installer:</info> Package not found (probably scheduled for removal); extensions installation skipped.');
            return;
        }
        $composer = $event->getComposer();
        $installationManager = $composer->getInstallationManager();
        $generatedConfigFilePath = __DIR__ . '/GeneratedConfig.php';
        $oldGeneratedConfigFileHash = null;
        if (is_file($generatedConfigFilePath)) {
            $oldGeneratedConfigFileHash = md5_file($generatedConfigFilePath);
        }
        $notInstalledPackages = [];
        $installedPackages = [];
        $ignoredPackages = [];
        $data = [];
        $fs = new Filesystem();
        $ignore = [];
        $packageExtra = $composer->getPackage()
            ->getExtra();
        if (isset($packageExtra['phpstan/extension-installer']['ignore'])) {
            $ignore = $packageExtra['phpstan/extension-installer']['ignore'];
        }
        $phpstanVersionConstraints = [];
        foreach ($composer->getRepositoryManager()
            ->getLocalRepository()
            ->getPackages() as $package) {
            if ($package->getType() !== 'phpstan-extension' && !isset($package->getExtra()['phpstan'])) {
                if (strpos($package->getName(), 'phpstan') !== false && !in_array($package->getName(), [
                    'phpstan/phpstan',
                    'phpstan/phpstan-shim',
                    'phpstan/phpdoc-parser',
                    'phpstan/extension-installer',
                ], true)) {
                    $notInstalledPackages[$package->getName()] = $package->getFullPrettyVersion();
                }
                continue;
            }
            if (in_array($package->getName(), $ignore, true)) {
                $ignoredPackages[] = $package->getName();
                continue;
            }
            $installPath = $installationManager->getInstallPath($package);
            if ($installPath === null) {
                continue;
            }
            $absoluteInstallPath = $fs->isAbsolutePath($installPath) ? $installPath : getcwd() . DIRECTORY_SEPARATOR . $installPath;
            $packageRequires = $package->getRequires();
            $phpstanConstraint = null;
            if (array_key_exists('phpstan/phpstan', $packageRequires)) {
                $phpstanConstraint = $packageRequires['phpstan/phpstan']->getConstraint();
                if ($phpstanConstraint->getLowerBound()
                    ->isZero()) {
                    continue;
                }
                if ($phpstanConstraint->getUpperBound()
                    ->isPositiveInfinity()) {
                    continue;
                }
                $phpstanVersionConstraints[] = $phpstanConstraint;
            }
            $data[$package->getName()] = [
                'install_path' => $absoluteInstallPath,
                'relative_install_path' => $fs->findShortestPath(dirname($generatedConfigFilePath), $absoluteInstallPath, true),
                'extra' => $package->getExtra()['phpstan'] ?? null,
                'version' => $package->getFullPrettyVersion(),
                'phpstanVersionConstraint' => $phpstanConstraint !== null ? $this->constraintIntoString($phpstanConstraint) : null,
            ];
            $installedPackages[$package->getName()] = true;
        }
        $phpstanVersionConstraint = null;
        if (count($phpstanVersionConstraints) > 0 && class_exists(Intervals::class)) {
            if (count($phpstanVersionConstraints) === 1) {
                $multiConstraint = $phpstanVersionConstraints[0];
            }
            else {
                $multiConstraint = new MultiConstraint($phpstanVersionConstraints);
            }
            $phpstanVersionConstraint = $this->constraintIntoString(Intervals::compactConstraint($multiConstraint));
        }
        ksort($data);
        ksort($installedPackages);
        ksort($notInstalledPackages);
        sort($ignoredPackages);
        $generatedConfigFileContents = sprintf(self::$generatedFileTemplate, var_export($data, true), var_export($notInstalledPackages, true), var_export($phpstanVersionConstraint, true));
        file_put_contents($generatedConfigFilePath, $generatedConfigFileContents);
        $io->write('<info>phpstan/extension-installer:</info> Extensions installed');
        if ($oldGeneratedConfigFileHash === md5($generatedConfigFileContents)) {
            return;
        }
        foreach (array_keys($installedPackages) as $name) {
            $io->write(sprintf('> <info>%s:</info> installed', $name));
        }
        foreach (array_keys($notInstalledPackages) as $name) {
            $io->write(sprintf('> <comment>%s:</comment> not supported', $name));
        }
        foreach ($ignoredPackages as $name) {
            $io->write(sprintf('> <comment>%s:</comment> ignored', $name));
        }
    }
    private function constraintIntoString(ConstraintInterface $constraint) : string {
        return sprintf('%s%s, %s%s', $constraint->getLowerBound()
            ->isInclusive() ? '>=' : '>', $constraint->getLowerBound()
            ->getVersion(), $constraint->getUpperBound()
            ->isInclusive() ? '<=' : '<', $constraint->getUpperBound()
            ->getVersion());
    }

}

Classes

Title Deprecated Summary
Plugin

API Navigation

  • Drupal Core 11.1.x
  • Topics
  • Classes
  • Functions
  • Constants
  • Globals
  • Files
  • Namespaces
  • Deprecated
  • Services
RSS feed
Powered by Drupal