Install-time REQUIREMENT_ERROR messages set by drupal_check_module() are rather weird, if $requirement['value'] is given. See for example a requirement supplied by simpletest_requirements():
The testing framework requires the sites/simpletest directory to exist and be writable in order to run tests.
(Currently using Simpletest site directory version Missing)
This is, because drupal_check_module() infers that $requirement['value'] contains the currently used version of a particular requirement, while it may also contain a current value or (as in this case) state:
Current workarounds:
In system_requirements(), at one point this problem was recognized and a workaround used, see:
$requirements['file system']['value'] = t('Not writable');
[...]
if ($phase == 'runtime') {
$description = t('You may need to set the correct directory at the <a href=":admin-file-system">file system settings page</a> or change the current directory\'s permissions so that it is writable.', [':admin-file-system' => \Drupal::url('system.file_system_settings')]);
}
elseif ($phase == 'install') {
// For the installer UI, we need different wording. 'value' will
// be treated as version, so provide none there.
$description = t('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 <a href=":handbook_url">online handbook</a>.', [':handbook_url' => 'https://www.drupal.org/server-permissions']);
$requirements['file system']['value'] = '';
Also, the newer Media module is working around this miswording, wrapping the current value in the $requirement['description'], so $requirement['value'] isn't set.
While this works, it is not how the hook_requirement() was meant to be used, and custom workarounds lead to code bloat, all instead of getting the basic problem fixed.
Solution:
While we could add another flag or revamp the whole system (which will happen one day but not now), hook_requirements() is used in some more places, so we don't want to mess with it. A simpler solution would be a more generic wording for this particular kind of use-cases:
if (isset($requirement['value']) && $requirement['value']) {
- $message = t('@requirements_message (Currently using @item version @version)', ['@requirements_message' => $requirement['description'], '@item' => $requirement['title'], '@version' => $requirement['value']]);
+ $message = t('@requirements_message (Currently: @item = @version)', ['@requirements_message' => $requirement['description'], '@item' => $requirement['title'], '@version' => $requirement['value']]);
}
This is quite in line with what install_display_requirements() does:
if (isset($requirement['severity']) && $requirement['severity'] == REQUIREMENT_ERROR) {
$failures[] = $requirement['title'] . ': ' . $requirement['value'] . "\n\n" . $requirement['description'];
}
and would yield perfectly acceptable messages like:
while also working fine with actual version numbers, such as another install requirement in system_requirements():