monitoring-8.x-1.x-dev/src/Plugin/monitoring/SensorPlugin/RequirementsRecapSensorPlugin.php
src/Plugin/monitoring/SensorPlugin/RequirementsRecapSensorPlugin.php
<?php
namespace Drupal\monitoring\Plugin\monitoring\SensorPlugin;
use Drupal\Component\Utility\Html;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\monitoring\Attribute\SensorPlugin;
use Drupal\system\SystemManager;
use Drupal\monitoring\Entity\SensorConfig;
use Drupal\monitoring\Result\SensorResultInterface;
use Drupal\monitoring\SensorPlugin\ExtendedInfoSensorPluginInterface;
use Drupal\monitoring\SensorPlugin\SensorPluginBase;
/**
* Requirements recap sensor that gathers requirements checks by severity.
*/
#[SensorPlugin(
id: 'requirements_recap',
label: new TranslatableMarkup('Requirements Recap'),
addable: TRUE,
)]
class RequirementsRecapSensorPlugin extends SensorPluginBase implements ExtendedInfoSensorPluginInterface {
const REQUIREMENTS_RECAP_CACHE_ID = 'monitoring_requirements_recap_cache';
/**
* Sensor manager service.
*
* @var \Drupal\system\SystemManager
*/
protected $systemManager;
/**
* The cache object associated with the default bin.
*
* @var \Drupal\Core\Cache\CacheBackendInterface
*/
protected $cache;
/**
* {@inheritdoc}
*/
public function __construct(SensorConfig $sensor_config, $plugin_id, $plugin_definition) {
$this->systemManager = $this->getService('system.manager');
$this->cache = $this->getService('cache.default');
parent::__construct($sensor_config, $plugin_id, $plugin_definition);
}
/**
* {@inheritdoc}
*/
public function runSensor(SensorResultInterface $sensor_result): void {
$severity = (int) $this->sensorConfig->getSetting('severity');
$all_requirements = $this->getAllRequirements();
$disabled_requirements = $this->sensorConfig->getSetting('disabled_requirements', []);
$requirements = array_diff_key($all_requirements, array_flip($disabled_requirements));
$requirements = array_filter($requirements, function ($requirement) use ($severity) {
return isset($requirement['severity']) && $requirement['severity'] === $severity;
});
$sensor_result->requirements = $requirements;
$sensor_result->setValue(count($requirements));
if (count($requirements)) {
foreach ($requirements as $requirement) {
$value = isset($requirement['value']) ? strip_tags(Html::decodeEntities($requirement['value'])) : '';
$title = $requirement['title'] ? "{$requirement['title']}" : '';
$sensor_result->addStatusMessage(' @title@value', [
'@title' => $title,
'@value' => $value ? ": {$value}" : '',
]);
}
}
}
/**
* {@inheritdoc}
*/
public function resultVerbose(SensorResultInterface $result): array {
if (!$requirements = $result->requirements) {
return [];
}
$counter = 0;
$output['table'] = [
'#type' => 'table',
'#header' => [
'label' => [
'data' => $this->t('Label'),
],
'value' => [
'data' => $this->t('Value'),
],
'description' => [
'data' => $this->t('Description'),
],
],
];
$renderer = $this->getService('renderer');
foreach ($requirements as $requirement) {
$title = (string) $requirement['title'];
$value = isset($requirement['value']) ? (string) $requirement['value'] : '';
$description = $requirement['description'] ?? '';
$description = is_array($description) ? $description : ['#markup' => (string) $description];
$output['table'][$counter]['label'] = [
'#type' => 'item',
'#plain_text' => $title,
];
$output['table'][$counter]['value'] = [
'#type' => 'item',
'#plain_text' => Html::decodeEntities($value),
];
$output['table'][$counter]['description'] = [
'#type' => 'item',
'#markup' => Html::decodeEntities((string) $renderer->renderPlain($description)),
];
$counter++;
}
return $output;
}
/**
* {@inheritdoc}
*/
public function getDefaultConfiguration(): array {
$default_config = parent::getDefaultConfiguration();
$default_config['settings']['severity'] = SystemManager::REQUIREMENT_ERROR;
$default_config['category'] = $this->t('Requirements');
$default_config['value_label'] = $this->t('Errors in status report');
$default_config['description'] = $this->t('Number of errors in status report checks.');
$default_config['value_type'] = 'number';
$default_config['caching_time'] = 3600;
$default_config['thresholds'] = [
'type' => 'exceeds',
'critical' => 1,
];
$default_config['settings']['disabled_requirements'] = ['cron', 'update'];
return $default_config;
}
/**
* Adds UI for variables config object and key.
*/
public function buildConfigurationForm(array $form, FormStateInterface $form_state): array {
$form = parent::buildConfigurationForm($form, $form_state);
// Add weight to display config key before expected value.
$form['severity'] = [
'#type' => 'select',
'#default_value' => $this->sensorConfig->getSetting('severity') ?? SystemManager::REQUIREMENT_ERROR,
'#options' => $this->getSeverityOptions(),
'#title' => $this->t('Requirements Severity'),
'#description' => $this->t('Requirements of selected severity are checked in this sensor.'),
'#required' => TRUE,
'#weight' => -1,
];
$all_requirements = $this->getAllRequirementsList();
if ($disabled_requirements = $this->sensorConfig->getSetting('disabled_requirements')) {
$default_value = array_combine($disabled_requirements, $disabled_requirements);
}
$form['disabled_requirements'] = [
'#type' => 'checkboxes',
'#default_value' => $default_value ?? [],
'#options' => $all_requirements,
'#title' => $this->t('Requirements to ignore'),
'#description' => $this->t('Select requirements that should not be checked when this sensor is run.'),
'#weight' => 0,
];
return $form;
}
/**
* {@inheritdoc}
*/
public function submitConfigurationForm(array &$form, FormStateInterface $form_state): void {
$values = $form_state->getValues()['settings']['disabled_requirements'];
$disabled_requirements = array_values(array_filter($values ?? []));
$this->sensorConfig->settings['disabled_requirements'] = $disabled_requirements;
}
/**
* List of all requirements used of form options.
*
* @return array
* All requirements.
*/
protected function getAllRequirementsList(): array {
$all_requirements = $this->getAllRequirements();
$requirements_options = [];
foreach ($all_requirements as $id => $requirement) {
$requirements_options[$id] = (string) $requirement['title'];
}
return $requirements_options;
}
/**
* Get options for requirements severity.
*
* @return array
* Mapping of requirements severity constants to labels.
*/
protected function getSeverityOptions(): array {
return [
SystemManager::REQUIREMENT_ERROR => $this->t('Error'),
SystemManager::REQUIREMENT_WARNING => $this->t('Warning'),
SystemManager::REQUIREMENT_OK => $this->t('Ok'),
];
}
/**
* Get all requirements from cache or from system manager.
*
* @return array
* All requirements.
*/
protected function getAllRequirements(): array {
$all_requirements = $this->cache->get(self::REQUIREMENTS_RECAP_CACHE_ID);
if (!isset($all_requirements->data)) {
$all_requirements = $this->systemManager->listRequirements();
$caching_time = $this->sensorConfig->getCachingTime() ?? 0;
$this->cache->set(self::REQUIREMENTS_RECAP_CACHE_ID, $all_requirements, time() + $caching_time);
return $all_requirements;
}
return $all_requirements->data;
}
}
