ProcessFactory.php

Same filename in this branch
  1. 11.x core/modules/package_manager/tests/modules/fixture_manipulator/src/ProcessFactory.php

Namespace

Drupal\package_manager

File

core/modules/package_manager/src/ProcessFactory.php

View source
<?php

declare (strict_types=1);
namespace Drupal\package_manager;

use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\File\FileSystemInterface;
use PhpTuf\ComposerStager\API\Path\Value\PathInterface;
use PhpTuf\ComposerStager\API\Process\Factory\ProcessFactoryInterface;
use PhpTuf\ComposerStager\API\Process\Service\ProcessInterface;
// cspell:ignore BINDIR

/**
 * Defines a process factory which sets the COMPOSER_HOME environment variable.
 *
 * @internal
 *   This is an internal part of Package Manager and may be changed or removed
 *   at any time without warning. External code should not interact with this
 *   class.
 */
final class ProcessFactory implements ProcessFactoryInterface {
    public function __construct(FileSystemInterface $fileSystem, ConfigFactoryInterface $configFactory, ProcessFactoryInterface $decorated) {
    }
    
    /**
     * {@inheritdoc}
     */
    public function create(array $command, ?PathInterface $cwd = NULL, array $env = []) : ProcessInterface {
        $process = $this->decorated
            ->create($command, $cwd, $env);
        $env = $process->getEnv();
        if ($command && $this->isComposerCommand($command)) {
            $env['COMPOSER_HOME'] = $this->getComposerHomePath();
        }
        // Ensure that the current PHP installation is the first place that will be
        // searched when looking for the PHP interpreter.
        $env['PATH'] = static::getPhpDirectory() . ':' . getenv('PATH');
        $process->setEnv($env);
        return $process;
    }
    
    /**
     * Returns the directory which contains the PHP interpreter.
     *
     * @return string
     *   The path of the directory containing the PHP interpreter. If the server
     *   is running in a command-line interface, the directory portion of
     *   PHP_BINARY is returned; otherwise, the compile-time PHP_BINDIR is.
     *
     * @see php_sapi_name()
     * @see https://www.php.net/manual/en/reserved.constants.php
     */
    private static function getPhpDirectory() : string {
        if (PHP_SAPI === 'cli' || PHP_SAPI === 'cli-server') {
            return dirname(PHP_BINARY);
        }
        return PHP_BINDIR;
    }
    
    /**
     * Returns the path to use as the COMPOSER_HOME environment variable.
     *
     * @return string
     *   The path which should be used as COMPOSER_HOME.
     */
    private function getComposerHomePath() : string {
        $home_path = $this->fileSystem
            ->getTempDirectory();
        $home_path .= '/package_manager_composer_home-';
        $home_path .= $this->configFactory
            ->get('system.site')
            ->get('uuid');
        $this->fileSystem
            ->prepareDirectory($home_path, FileSystemInterface::CREATE_DIRECTORY | FileSystemInterface::MODIFY_PERMISSIONS);
        return $home_path;
    }
    
    /**
     * Determines if a command is running Composer.
     *
     * @param string[] $command
     *   The command parts.
     *
     * @return bool
     *   TRUE if the command is running Composer, FALSE otherwise.
     */
    private function isComposerCommand(array $command) : bool {
        $executable = $command[0];
        $executable_parts = explode('/', $executable);
        $file = array_pop($executable_parts);
        return str_starts_with($file, 'composer');
    }

}

Classes

Title Deprecated Summary
ProcessFactory Defines a process factory which sets the COMPOSER_HOME environment variable.

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