Problem/Motivation
I was running a site install via drupal console, with some folder permission issues. I was supposed to see an error message. But instead of the clear error message, I ran into an exception message with it.
OS: Windows 10 (1809 / 10.0.17763.678) on WSL with Ubuntu 18.04 LTS
PHP: 7.2.21-1+ubuntu18.04.1+deb.sury.org+1 (cli) (built: Aug 7 2019 09:53:51) ( NTS )
drupal/console: 1.9.3
The install command:
vendor/bin/drupal site:install ...
The message (pt-BR locale):
Starting Drupal 8 install process
[ERROR] Sistema de arquivos: Gravável (método de download público)
Array
[ERROR] <em class="placeholder">Notice</em>: Array to string conversion in <em
class="placeholder">install_display_requirements()</em> (line <em class="placeholder">2283</em> of <em
class="placeholder">core/includes/install.core.inc</em>). <pre
class="backtrace">install_display_requirements(Array, Array) (Line: 1088)
install_verify_requirements(Array) (Line: 702)
install_run_task(Array, Array) (Line: 577)
install_run_tasks(Array, NULL) (Line: 118)
install_drupal(Object, Array) (Line: 583)
Drupal\Console\Command\Site\InstallCommand->runInstaller(Array, 'default') (Line: 466)
Drupal\Console\Command\Site\InstallCommand->execute(Object, Object) (Line: 255)
Symfony\Component\Console\Command\Command->run(Object, Object) (Line: 981)
Symfony\Component\Console\Application->doRunCommand(Object, Object, Object) (Line: 254)
Symfony\Component\Console\Application->doRun(Object, Object) (Line: 188)
Drupal\Console\Core\Application->doRun(Object, Object) (Line: 64)
Drupal\Console\Application->doRun(Object, Object) (Line: 147)
Symfony\Component\Console\Application->run() (Line: 89)
require('/mnt/c/g/gl/zoiosilva/plataforma-estude/vendor/drupal/console/bin/drupal.php') (Line: 4)
</pre>
And, investigating through the code, I came onto this line in core/includes/install.core.inc:L2283:
$failures[] = $requirement['title'] . ': ' . $requirement['value'] . "\n\n" . $requirement['description'];
And found out that the $requirement['description'] came from here: core/modules/system/system.install:L686, in the system_requirements function.
So, the problem is that $requirement['description'] is expecting something directly convertible to a string, like a Drupal\Core\StringTranslation\TranslatableMarkup object, but found an array instead.
I attached the $requirement value printed via print_r in case it is usefull.
Proposed resolution
Well, the $requirement['description'] value is an array, which is an inline_template type. So, to the message to be properly shown, I suggest using the Drupal\Core\Render\Element\InlineTemplate::preRenderInlineTemplate method to render the error message properly.
Well, I tried that, and the error message ended up being shown much more properly (again, in pt-BR):
Starting Drupal 8 install process
[ERROR] Sistema de arquivos: Gravável (método de download público)
Não há permissões de escrita na pasta sites/default/files. An automated attempt to create this directory
failed, possibly due to a permissions problem. To proceed with the installation, either create the directory
and modify its permissions manually or ensure that the installer has the permissions to create it
automatically. For more information, see INSTALL.txt or the online handbook.
What I did was change this code (in core/includes/install.core.inc:L2276):
// Throw an exception showing any unmet requirements.
$failures = [];
foreach ($requirements as $requirement) {
// Skip warnings altogether for non-interactive installations; these
// proceed in a single request so there is no good opportunity (and no
// good method) to warn the user anyway.
if (isset($requirement['severity']) && $requirement['severity'] == REQUIREMENT_ERROR) {
$failures[] = $requirement['title'] . ': ' . $requirement['value'] . "\n\n" . $requirement['description'];
}
}
To this (omitting the use declaration on the top of the file):
// Throw an exception showing any unmet requirements.
$failures = [];
foreach ($requirements as $requirement) {
// Skip warnings altogether for non-interactive installations; these
// proceed in a single request so there is no good opportunity (and no
// good method) to warn the user anyway.
if (isset($requirement['severity']) && $requirement['severity'] == REQUIREMENT_ERROR) {
if (is_array($requirement['description']) && $requirement['description']['#type'] === 'inline_template') {
$requirement['description'] = InlineTemplate::preRenderInlineTemplate($requirement['description']);
$failures[] = $requirement['title'] . ': ' . $requirement['value'] . "\n\n" . $requirement['description']['#markup'];
}
else {
$failures[] = $requirement['title'] . ': ' . $requirement['value'] . "\n\n" . $requirement['description'];
}
}
}
Remaining tasks
(reviews needed, tests to be written or run, documentation to be written, etc.)
User interface changes
No user interface changes.
API changes
No API changes, just bug correction.
Data model changes
No data model changes.
* This is my first ever issue report. I hope I'm doing this properly enough.
| Comment | File | Size | Author |
|---|---|---|---|
| requirements_value.txt | 2.77 KB | zoiosilva |
Comments
Comment #4
matroskeen@zoiosilva, thanks so much for the report! It's very detailed, hence makes it easier to understand the issue.
Keep up the good work!
I added your issue as a reference to the older one: #2833864: Unmet installation requirements may contain render elements, where some better solutions have been already discussed. Feel free to review and click "Follow" to keep an eye on the progress.
In the meantime, I'm marking this one as a duplicate.
Thanks!
Comment #5
quietone commentedI reckon @Matroskeen meant to tag this