You are here

class EnabledModulesSensorPlugin in Monitoring 8

Monitors installed modules.

Plugin annotation


@SensorPlugin(
  id = "monitoring_installed_modules",
  label = @Translation("Installed Modules"),
  description = @Translation("Monitors installed modules."),
  addable = FALSE
)

Hierarchy

Expanded class hierarchy of EnabledModulesSensorPlugin

File

src/Plugin/monitoring/SensorPlugin/EnabledModulesSensorPlugin.php, line 26
Contains \Drupal\monitoring\Plugin\monitoring\SensorPlugin\EnabledModulesSensorPlugin.

Namespace

Drupal\monitoring\Plugin\monitoring\SensorPlugin
View source
class EnabledModulesSensorPlugin extends SensorPluginBase {

  /**
   * {@inheritdoc}
   */
  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
    $form = parent::buildConfigurationForm($form, $form_state);

    // Run the sensor to current setting and display the update button if
    // sensor result is critical.
    $configured_modules = array_filter($this->sensorConfig
      ->getSetting('modules', NULL));

    // If the sensor is not configured, select installed modules.
    if (!$configured_modules) {
      $enabled_modules = Drupal::moduleHandler()
        ->getModuleList();

      // Reduce to the module name only.
      $configured_modules = array_combine(array_keys($enabled_modules), array_keys($enabled_modules));
    }
    else {

      // Run on a temporary sensor config id with some changes.

      /** @var \Drupal\monitoring\Entity\SensorConfig $run_config */
      $run_config = $this->sensorConfig
        ->createDuplicate();

      // Avoid name clashes in SensorManager / caching.
      $run_config->id = $this->sensorConfig
        ->id() . '_temp';

      // Force enabling the sensor for running.
      $run_config->status = TRUE;

      // Force no additional allowed to make differences visible in message.
      $run_config->settings['allow_additional'] = FALSE;

      /** @var \Drupal\monitoring\Result\SensorResult $result */
      $result = \Drupal::service('monitoring.sensor_runner')
        ->runSensors(array(
        $run_config
          ->id() => $run_config,
      ), TRUE)[$run_config
        ->id()];
      if ($result
        ->isCritical()) {
        $message = $result
          ->getMessage();

        // Display message and button to update selection.
        $form['update_modules']['message'] = array(
          '#type' => 'item',
          '#title' => t('Test run message'),
          '#markup' => $message,
        );
        $form['update_modules']['update'] = array(
          '#type' => 'submit',
          '#value' => t('Update module selection'),
          '#limit_validation_errors' => array(),
          '#submit' => array(
            array(
              $this,
              'updateModuleListSubmit',
            ),
          ),
          '#ajax' => array(
            'callback' => '::ajaxReplacePluginSpecificForm',
            'wrapper' => 'monitoring-sensor-plugin',
            'method' => 'replace',
          ),
        );
      }
    }
    $form['allow_additional'] = array(
      '#type' => 'checkbox',
      '#title' => t('Allow additional modules to be installed'),
      '#description' => t('If checked additionally installed modules will not be considered a critical state.'),
      '#default_value' => $this->sensorConfig
        ->getSetting('allow_additional'),
    );

    // Get current list of available modules.
    // @todo find a faster solution? If that happens we can drop caching the
    //   result for 1 hour.
    $modules = \Drupal::service('extension.list.module')
      ->getList();
    uasort($modules, 'system_sort_modules_by_info_name');
    $visible_modules = array();
    $visible_default_value = array();
    $hidden_modules = array();
    $hidden_default_value = array();
    foreach ($modules as $module => $module_data) {

      // Skip profiles.
      if (strpos(drupal_get_path('module', $module), 'profiles') === 0) {
        continue;
      }

      // As we also include hidden modules, some might have no name at all,
      // make sure it is set.
      if (!isset($module_data->info['name'])) {
        $module_data->info['name'] = '- No name -';
      }
      if (!empty($module_data->info['hidden'])) {
        $hidden_modules[$module] = $module_data->info['name'] . ' (' . $module . ')';
        if (!empty($configured_modules[$module])) {
          $hidden_default_value[$module] = $configured_modules[$module];
        }
      }
      else {
        $visible_modules[$module] = $module_data->info['name'] . ' (' . $module . ')';
        if (!empty($configured_modules[$module])) {
          $visible_default_value[$module] = $configured_modules[$module];
        }
      }
    }
    $form['modules'] = array(
      '#type' => 'checkboxes',
      '#options' => $visible_modules,
      '#title' => t('Modules expected to be installed'),
      '#description' => t('Check all modules that are supposed to be installed.'),
      '#default_value' => $visible_default_value,
    );
    $form['extended'] = array(
      '#type' => 'details',
      '#title' => 'Extended',
      '#open' => count($hidden_default_value) ? TRUE : FALSE,
    );
    $form['extended']['modules_hidden'] = array(
      '#type' => 'checkboxes',
      '#options' => $hidden_modules,
      '#title' => t('Hidden modules expected to be installed'),
      '#default_value' => $hidden_default_value,
      '#description' => t('Check all modules that are supposed to be installed.'),
    );
    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
    $sensor_config = $form_state
      ->getFormObject()
      ->getEntity();
    parent::submitConfigurationForm($form, $form_state);
    $modules = $form_state
      ->getValue(array(
      'settings',
      'modules',
    ));
    $hidden_modules = $form_state
      ->getValue(array(
      'settings',
      'extended',
      'modules_hidden',
    ));
    $modules = array_merge(array_filter($modules), array_filter($hidden_modules));
    $sensor_config->settings['modules'] = $modules;
    unset($sensor_config->settings['extended']);
    unset($sensor_config->settings['update_modules']);
  }

  /**
   * {@inheritdoc}
   */
  public function runSensor(SensorResultInterface $result) {

    // Load the info from the system table to display the label.
    $result
      ->setExpectedValue(0);
    $delta = 0;
    $modules = \Drupal::service('extension.list.module')
      ->getList();
    $names = array();
    foreach ($modules as $name => $module) {
      $names[$name] = $module->info['name'];
    }
    $monitoring_installed_modules = array();

    // Filter out install profile.
    foreach (array_keys(Drupal::moduleHandler()
      ->getModuleList()) as $module) {
      $path_parts = explode('/', drupal_get_path('module', $module));
      if ($path_parts[0] != 'profiles') {
        $monitoring_installed_modules[$module] = $module;
      }
    }
    $expected_modules = array_filter($this->sensorConfig
      ->getSetting('modules'));

    // If there are no expected modules, the sensor is not configured, so init
    // the expected modules list as currently installed modules.
    if (empty($expected_modules)) {
      $expected_modules = $monitoring_installed_modules;
      $this->sensorConfig->settings['modules'] = $monitoring_installed_modules;
      $this->sensorConfig
        ->save();
    }

    // Check for modules not being installed but expected.
    $non_installed_modules = array_diff($expected_modules, $monitoring_installed_modules);
    if (!empty($non_installed_modules)) {
      $delta += count($non_installed_modules);
      $non_installed_modules_info = array();
      foreach ($non_installed_modules as $non_installed_module) {
        if (isset($names[$non_installed_module])) {
          $non_installed_modules_info[] = $names[$non_installed_module] . ' (' . $non_installed_module . ')';
        }
        else {
          $non_installed_modules_info[] = new FormattableMarkup('@module_name (unknown)', array(
            '@module_name' => $non_installed_module,
          ));
        }
      }
      $result
        ->addStatusMessage('Following modules are expected to be installed: @modules', array(
        '@modules' => implode(', ', $non_installed_modules_info),
      ));
    }

    // In case we do not allow additional modules check for modules installed
    // but not expected.
    $unexpected_modules = array_diff($monitoring_installed_modules, $expected_modules);
    if (!$this->sensorConfig
      ->getSetting('allow_additional') && !empty($unexpected_modules)) {
      $delta += count($unexpected_modules);
      $unexpected_modules_info = array();
      foreach ($unexpected_modules as $unexpected_module) {
        $unexpected_modules_info[] = $names[$unexpected_module] . ' (' . $unexpected_module . ')';
      }
      $result
        ->addStatusMessage('Following modules are NOT expected to be installed: @modules', array(
        '@modules' => implode(', ', $unexpected_modules_info),
      ));
    }
    $result
      ->setValue($delta);
  }

  /**
   * Updates the module selection and override user input.
   */
  public function updateModuleListSubmit(array &$form, FormStateInterface $form_state) {

    // Get the installed module list.
    $enabled_modules = Drupal::moduleHandler()
      ->getModuleList();

    // Reduce to the module name only.
    $default_value = array_combine(array_keys($enabled_modules), array_keys($enabled_modules));

    // Override the current input values to the default configuration.
    $user_input = $form_state
      ->getUserInput();
    $user_input['settings']['modules'] = $default_value;
    $form_state
      ->setUserInput($user_input);
    $entity = $form_state
      ->getFormObject()
      ->getEntity();
    $entity->settings['modules'] = $default_value;
    $form_state
      ->setRebuild(TRUE);
    $this
      ->messenger()
      ->addMessage(t('Module list updateed, Save to confirm.'));
  }

}

Members

Namesort descending Modifiers Type Description Overrides
EnabledModulesSensorPlugin::buildConfigurationForm public function Form constructor. Overrides SensorPluginBase::buildConfigurationForm
EnabledModulesSensorPlugin::runSensor public function Runs the sensor, updating $sensor_result. Overrides SensorPluginInterface::runSensor
EnabledModulesSensorPlugin::submitConfigurationForm public function Form submission handler. Overrides SensorPluginBase::submitConfigurationForm
EnabledModulesSensorPlugin::updateModuleListSubmit public function Updates the module selection and override user input.
MessengerTrait::$messenger protected property The messenger. 29
MessengerTrait::messenger public function Gets the messenger. 29
MessengerTrait::setMessenger public function Sets the messenger.
SensorPluginBase::$configurableValueType protected property Allows plugins to control if the value type can be configured. 6
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::calculateDependencies public function Calculates dependencies for the configured plugin. Overrides SensorPluginInterface::calculateDependencies 4
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.