diff --git a/dictionary.txt b/dictionary.txt index ad242b1dbe48ca398515a0c4b87d280b1344c546..0ccd8f9ed65c2dcaf8afee687cee4548d3000289 100644 --- a/dictionary.txt +++ b/dictionary.txt @@ -11,3 +11,4 @@ filedate unshallow hhvm tmpdir +proc_open diff --git a/package_manager/package_manager.module b/package_manager/package_manager.module index 55ca66e5d1aa144f392ec7072e7d1a71dbe0571f..4847f83dbced52fc17606f19473c8e11a7617418 100644 --- a/package_manager/package_manager.module +++ b/package_manager/package_manager.module @@ -51,6 +51,9 @@ function package_manager_help($route_name, RouteMatchInterface $route_match) { $output .= '<h3 id="package-manager-faq">' . t('FAQ') . '</h3>'; $output .= '<h4 id="package-manager-composer-related-faq">' . t('FAQs related to Composer') . '</h4>'; $output .= '<ul>'; + $output .= ' <li>' . t('What if it says the <code>proc_open()</code> function is disabled on your PHP installation?'); + $output .= ' <p>' . t('Ask your system administrator to remove <code>proc_open()</code> from the <a href=":url">disable_functions</a> setting in <code>php.ini</code>.', [':url' => 'https://www.php.net/manual/en/ini.core.php#ini.disable-functions']) . '</p>'; + $output .= ' </li>'; $output .= ' <li>' . t('What if it says the <code>composer</code> executable cannot be found?'); $output .= ' <p>' . t("If the <code>composer</code> executable's path cannot be automatically determined, it can be explicitly set by adding the following line to <code>settings.php</code>:") . '</p>'; $output .= " <pre><code>\$config['package_manager.settings']['executables']['composer'] = '/full/path/to/composer.phar';</code></pre>"; diff --git a/package_manager/src/Validator/ComposerValidator.php b/package_manager/src/Validator/ComposerValidator.php index e4aa6ced612943e75ca5bafcfd58648fd014254b..bb686a457d32cda8d5de496f1a67c51606563255 100644 --- a/package_manager/src/Validator/ComposerValidator.php +++ b/package_manager/src/Validator/ComposerValidator.php @@ -46,6 +46,19 @@ final class ComposerValidator implements EventSubscriberInterface { * Validates that the Composer executable is the correct version. */ public function validate(PreOperationStageEvent $event): void { + // If we can't stat processes, there's nothing else we can possibly do here. + // @see \Symfony\Component\Process\Process::__construct() + if (!\function_exists('proc_open')) { + $message = $this->t('Composer cannot be used because the <code>proc_open()</code> function is disabled.'); + if ($this->moduleHandler->moduleExists('help')) { + $message = $this->t('@message See <a href=":package-manager-help">the help page</a> for information on how to resolve the problem.', [ + ':package-manager-help' => self::getHelpUrl('package-manager-composer-related-faq'), + ]); + } + $event->addError([$message]); + return; + } + $messages = []; $dir = $event instanceof PreApplyEvent ? $event->stage->getStageDirectory()