You are here

class CoreRequirementsSensorPlugin in Monitoring 8

Monitors a specific module hook_requirements.

@SensorPlugin( id = "core_requirements", label = @Translation("Core Requirements"), description = @Translation("Monitors a specific module hook_requirements."), addable = FALSE )

@todo Shorten sensor message and add improved verbose output.

Hierarchy

Expanded class hierarchy of CoreRequirementsSensorPlugin

File

src/Plugin/monitoring/SensorPlugin/CoreRequirementsSensorPlugin.php, line 29
Contains \Drupal\monitoring\Plugin\monitoring\SensorPlugin\CoreRequirementsSensorPlugin.

Namespace

Drupal\monitoring\Plugin\monitoring\SensorPlugin
View source
class CoreRequirementsSensorPlugin extends SensorPluginBase implements ExtendedInfoSensorPluginInterface {
  use DependencyTrait;

  /**
   * Requirements from hook_requirements.
   *
   * @var array
   */
  protected $requirements;

  /**
   * {@inheritdoc}
   */
  protected $configurableValueType = FALSE;

  /**
   * {@inheritdoc}
   */
  public function resultVerbose(SensorResultInterface $result) {
    $output = [];
    $requirements = $this
      ->getRequirements($this->sensorConfig
      ->getSetting('module'));
    $excluded_keys = $this->sensorConfig
      ->getSetting('exclude_keys');
    if (empty($excluded_keys)) {
      $excluded_keys = array();
    }
    $rows = [];
    foreach ($requirements as $key => $value) {

      // Make sure all keys are present.
      $value += array(
        'severity' => NULL,
      );

      // Map column key.
      $row['key'] = $key;

      // Map column excluded.
      if (in_array($key, $excluded_keys)) {
        $row['excluded'] = 'Yes';
      }
      else {
        $row['excluded'] = '';
      }

      // Map column severity.
      $severity = $value['severity'];
      if ($severity == REQUIREMENT_ERROR) {
        $severity = 'Error';
      }
      elseif ($severity == REQUIREMENT_WARNING) {
        $severity = 'Warning';
      }
      else {
        $severity = 'OK';
      }
      $row['severity'] = $severity;

      // Map column message with title and description.
      $titles = [];
      if (isset($value['title'])) {
        $titles[] = $value['title'];
      }
      if (isset($value['value'])) {
        $titles[] = $value['value'];
      }
      $description = '';
      if (isset($value['description'])) {
        if (is_array($value['description'])) {

          // A few requirements such as cron attach a render array.
          $description = \Drupal::service('renderer')
            ->renderPlain($value['description']);
        }
        else {
          $description = $value['description'];
        }
      }
      $titles = array_map(function ($title) {
        if (is_array($title)) {
          $title = \Drupal::service('renderer')
            ->renderPlain($title);
        }
        return $title;
      }, $titles);
      $message = array(
        '#type' => 'item',
        '#title' => implode(' ', $titles),
        '#markup' => $description,
      );
      $row['message'] = \Drupal::service('renderer')
        ->renderPlain($message);

      // Map column actions.
      $row['actions'] = array();
      if (!in_array($key, $excluded_keys)) {
        $row['actions']['data'] = array(
          '#type' => 'link',
          '#title' => $this
            ->t('Ignore'),
          '#url' => Url::fromRoute('monitoring.requirements_sensor_ignore_key', array(
            'monitoring_sensor_config' => $this->sensorConfig
              ->id(),
            'key' => $key,
          )),
          '#access' => \Drupal::currentUser()
            ->hasPermission('administer monitoring'),
        );
      }
      else {
        $row['actions']['data'] = array(
          '#type' => 'link',
          '#title' => $this
            ->t('Unignore'),
          '#url' => Url::fromRoute('monitoring.requirements_sensor_unignore_key', array(
            'monitoring_sensor_config' => $this->sensorConfig
              ->id(),
            'key' => $key,
          )),
          '#access' => \Drupal::currentUser()
            ->hasPermission('administer monitoring'),
        );
      }
      $rows[] = array(
        'data' => $row,
      );
    }
    if (count($rows) > 0) {
      $header = [];
      $header['key'] = t('Key');
      $header['excluded'] = t('Excluded');
      $header['severity'] = t('Severity');
      $header['message'] = t('Message');
      $header['actions'] = t('Actions');
      $output['requirements'] = array(
        '#type' => 'verbose_table_result',
        '#header' => $header,
        '#rows' => $rows,
      );
    }
    return $output;
  }

  /**
   * {@inheritdoc}
   */
  public function runSensor(SensorResultInterface $result) {
    $requirements = $this
      ->getRequirements($this->sensorConfig
      ->getSetting('module'));

    // Ignore requirements that were explicitly excluded.
    foreach ($this->sensorConfig
      ->getSetting('exclude_keys', array()) as $exclude_key) {
      if (isset($requirements[$exclude_key])) {
        unset($requirements[$exclude_key]);
      }
    }
    $this
      ->processRequirements($result, $requirements);
  }

  /**
   * {@inheritdoc}
   */
  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
    $form = parent::buildConfigurationForm($form, $form_state);
    $form['exclude_keys'] = array(
      '#type' => 'textarea',
      '#title' => t('Keys to be excluded.'),
      '#description' => t('Seperate the keys by a new line.'),
    );
    if ($this->sensorConfig
      ->getSetting('exclude_keys')) {
      $form['exclude_keys']['#default_value'] = implode("\n", $this->sensorConfig
        ->getSetting('exclude_keys'));
    }
    return $form;
  }

  /**
   * Extracts the highest severity from the requirements array.
   *
   * Replacement for drupal_requirements_severity(), which ignores
   * the INFO severity, which results in those messages not being displayed.
   *
   * @param $requirements
   *   An array of requirements, in the same format as is returned by
   *   hook_requirements().
   *
   * @return
   *   The highest severity in the array.
   */
  protected function getHighestSeverity(&$requirements) {
    $severity = REQUIREMENT_INFO;
    foreach ($requirements as $requirement) {
      if (isset($requirement['severity'])) {
        $severity = max($severity, $requirement['severity']);
      }
    }
    return $severity;
  }

  /**
   * Executes the requirements hook of a module and returns the results.
   *
   * @param string $module
   *   Name of the module to return requirements for.
   *
   * @return array
   *   Array of requirements
   *
   * @throws \RuntimeException
   *   Thrown when the given module does not provide a requirements hook.
   */
  protected function getRequirements($module) {
    module_load_install($module);
    $function = $module . '_requirements';
    if (!function_exists($function)) {
      throw new \RuntimeException(new FormattableMarkup('Requirement function @function not found', array(
        '@function' => $function,
      )));
    }
    return (array) $function('runtime');
  }

  /**
   * Sets sensor result status and status messages for the given requirements.
   *
   * @param \Drupal\monitoring\Result\SensorResultInterface $result
   *   The result object to update.
   * @param array $requirements
   *   Array of requirements to process.
   */
  protected function processRequirements(SensorResultInterface $result, $requirements) {
    $severity = $this
      ->getHighestSeverity($requirements);
    if ($severity == REQUIREMENT_ERROR) {
      $result
        ->setStatus(SensorResultInterface::STATUS_CRITICAL);
    }
    elseif ($severity == REQUIREMENT_WARNING) {
      $result
        ->setStatus(SensorResultInterface::STATUS_WARNING);
    }
    else {
      $result
        ->setStatus(SensorResultInterface::STATUS_OK);
    }
    if (!empty($requirements)) {
      foreach ($requirements as $requirement) {

        // Skip if we do not have the highest requirements severity.
        if (!isset($requirement['severity']) || $requirement['severity'] != $severity) {
          continue;
        }
        if (!empty($requirement['title'])) {
          $result
            ->addStatusMessage($requirement['title']);
        }
        if (!empty($requirement['description'])) {
          $result
            ->addStatusMessage($requirement['description']);
        }
        if (!empty($requirement['value'])) {
          $result
            ->addStatusMessage($requirement['value']);
        }
      }
    }
    else {
      $result
        ->addStatusMessage('Requirements check OK');
    }
  }

  /**
   * {@inheritdoc}
   */
  public function calculateDependencies() {
    $module = $this->sensorConfig
      ->getSetting('module');
    $this
      ->addDependency('module', $module);
    return $this->dependencies;
  }

  /**
   * {@inheritdoc}
   */
  public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
    $keys = array_filter(explode("\n", $form_state
      ->getValue(array(
      'settings',
      'exclude_keys',
    ))));
    $keys = array_map('trim', $keys);
    $this->sensorConfig->settings['exclude_keys'] = $keys;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
CoreRequirementsSensorPlugin::$configurableValueType protected property Allows plugins to control if the value type can be configured. Overrides SensorPluginBase::$configurableValueType
CoreRequirementsSensorPlugin::$requirements protected property Requirements from hook_requirements.
CoreRequirementsSensorPlugin::buildConfigurationForm public function Form constructor. Overrides SensorPluginBase::buildConfigurationForm
CoreRequirementsSensorPlugin::calculateDependencies public function Calculates dependencies for the configured plugin. Overrides SensorPluginBase::calculateDependencies
CoreRequirementsSensorPlugin::getHighestSeverity protected function Extracts the highest severity from the requirements array.
CoreRequirementsSensorPlugin::getRequirements protected function Executes the requirements hook of a module and returns the results.
CoreRequirementsSensorPlugin::processRequirements protected function Sets sensor result status and status messages for the given requirements.
CoreRequirementsSensorPlugin::resultVerbose public function Provide additional info about sensor call. Overrides ExtendedInfoSensorPluginInterface::resultVerbose
CoreRequirementsSensorPlugin::runSensor public function Runs the sensor, updating $sensor_result. Overrides SensorPluginInterface::runSensor
CoreRequirementsSensorPlugin::submitConfigurationForm public function Form submission handler. Overrides SensorPluginBase::submitConfigurationForm
DependencyTrait::$dependencies protected property The object's dependencies.
DependencyTrait::addDependencies protected function Adds multiple dependencies.
DependencyTrait::addDependency protected function Adds a dependency.
MessengerTrait::$messenger protected property The messenger. 29
MessengerTrait::messenger public function Gets the messenger. 29
MessengerTrait::setMessenger public function Sets the messenger.
SensorPluginBase::$pluginDefinition protected property The plugin implementation definition.
SensorPluginBase::$pluginId protected property The plugin_id.
SensorPluginBase::$sensorConfig protected property Current sensor config object.
SensorPluginBase::$services protected property
SensorPluginBase::addService public function Service setter. Overrides SensorPluginInterface::addService
SensorPluginBase::create public static function Creates an instance of the sensor with config. Overrides SensorPluginInterface::create 7
SensorPluginBase::getConfigurableValueType public function Configurable value type. Overrides SensorPluginInterface::getConfigurableValueType
SensorPluginBase::getDefaultConfiguration public function Default configuration for a sensor. Overrides SensorPluginInterface::getDefaultConfiguration 8
SensorPluginBase::getPluginDefinition public function Gets the definition of the plugin implementation. Overrides PluginInspectionInterface::getPluginDefinition
SensorPluginBase::getPluginId public function Gets the plugin_id of the plugin instance. Overrides PluginInspectionInterface::getPluginId
SensorPluginBase::getSensorId public function Gets sensor name (not the label). Overrides SensorPluginInterface::getSensorId
SensorPluginBase::getService public function @todo: Replace with injection Overrides SensorPluginInterface::getService
SensorPluginBase::isEnabled public function Determines if sensor is enabled. Overrides SensorPluginInterface::isEnabled
SensorPluginBase::validateConfigurationForm public function Form validation handler. Overrides PluginFormInterface::validateConfigurationForm 2
SensorPluginBase::__construct function Instantiates a sensor object. 8
StringTranslationTrait::$stringTranslation protected property The string translation service. 1
StringTranslationTrait::formatPlural protected function Formats a string containing a count of items.
StringTranslationTrait::getNumberOfPlurals protected function Returns the number of plurals supported by a given language.
StringTranslationTrait::getStringTranslation protected function Gets the string translation service.
StringTranslationTrait::setStringTranslation public function Sets the string translation service to use. 2
StringTranslationTrait::t protected function Translates a string to the current language or to a given language.