sgd_dashboard-1.0.0-beta1/sgd_dashboard.module

sgd_dashboard.module
<?php

/**
 * @file
 * Module for the implementation of common hooks and general helper functions.
 */

use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Markup;
use Drupal\Core\Url;
use Drupal\Node\NodeInterface;
use Drupal\sgd_dashboard\Entity\Bundle\WebsiteBundle;
use Drupal\views\ViewExecutable;
use Drupal\views\Plugin\views\query\QueryPluginBase;

/**
 * Implements hook_theme().
 *
 * {@inheritDoc}
 */
function sgd_dashboard_theme($existing, $type, $theme, $path) {

  return [
    'sgd_php_data' => [
      'variables' => [
        'data' => NULL,
      ],
    ],
    'sgd_user_data' => [
      'variables' => [
        'data' => NULL,
      ],
    ],
    'sgd_benchmark_data' => [
      'variables' => [
        'data' => NULL,
      ],
    ],
    'sgd_watchdog_summary' => [
      'variables' => [
        'data' => NULL,
      ],
    ],
    'sgd_core_data' => [
      'variables' => [
        'status' => NULL,
        'exposed_form' => NULL,
        'project_list' => NULL,
      ],
      'template' => 'sgd-core-data',
    ],
  ];
}

/**
 * Implements hook_toolbar_alter().
 */
function sgd_dashboard_toolbar_alter(&$items) {
  $items['administration']['#attached']['library'][] = 'sgd_dashboard/sgd_dashboard';
}

/**
 * Implements hook_entity_operation().
 *
 * Adds the 'refresh' operation to website nodes in views/lists.
 *
 * {@inheritdoc}
 */
function sgd_dashboard_entity_operation(EntityInterface $entity) {

  $operations = [];

  // If it's website node.
  if ($entity->getEntityTypeId() == 'node' && $entity->bundle() == 'website') {

    /** @var \Drupal\sgd_dashboard\Entity\Bundle\WebsiteBundle $website */
    $website = $entity;

    // Add a 'Refresh' operation if user has permission.
    if (\Drupal::currentUser()->hasPermission('refresh websites')) {

      $destination = Url::fromUserInput(\Drupal::destination()->get());

      $operations['refresh'] = [
        'title' => t('Refresh'),
        'url' => Url::fromRoute('entity.node.refresh_website',
          [
            'node' => $website->id(),
          ],
          [
            'query' => [
              'destination' => Url::fromRoute($destination->getRouteName(), $destination->getRouteParameters())->toString(),
            ],
          ],
        ),
        'weight' => -1,
      ];
    }

    // Add a 'Visit site' operation.
    $uri = $website->getBaseUrl();

    $operations['site_link'] = [
      'title' => t('Visit site'),
      'url' => Url::fromUri($uri),
      'weight' => -2,
    ];

  }

  // Add link to project on Drupal.org for enabled project entities.
  elseif ($entity->getEntityTypeId() == 'sgd_enabled_project') {

    $uri = 'https://www.drupal.org/project/' . $entity->get('name')->value;

    $operations['drupal_project_link'] = [
      'title' => t('Visit on Drupal.org'),
      'url' => Url::fromUri($uri),
      'weight' => -2,
    ];

  }

  return $operations;
}

/**
 * Implements hook_ENTITY_TYPE_insert().
 *
 * {@inheritdoc}
 */
function sgd_dashboard_node_insert(NodeInterface $node): void {

  if ($node->bundle() == 'website') {

    // Create a website data entity for the website.
    $websiteData = \Drupal::entityTypeManager()->getStorage('sgd_website_data')->create([
      'label' => $node->getTitle(),
      'uid' => '1',
      'status' => 1,
    ]);

    $websiteData->save();

    // Update the website node with the website data entity ID.
    $node->set('field_sgd_website_data', [
      'entity' => $websiteData,
      'target_id' => $websiteData->id(),
    ]);

    $node->save();

    // Create the cron job for the website.
    $cronService = \Drupal::service('siteguardian.CronService');

    $cronService->addCronJob($node);
  }
}

/**
 * Implements hook_ENTITY_TYPE_update().
 *
 * {@inheritdoc}
 */
function sgd_dashboard_node_update(NodeInterface $node): void {

  if ($node->bundle() == 'website') {

    $dataService = \Drupal::service('siteguardian.DataService');
    $cronService = \Drupal::service('siteguardian.CronService');

    // Update the website data storage node name.
    $dataService->updateWebsiteDataName($node);

    // Update the Cron job.
    if (!$cronService->updateCronJob($node)) {
      $cronService->addCronJob($node);
    }
  }
}

/**
 * Implements hook_ENTITY_TYPE_delete().
 *
 * {@inheritdoc}
 */
function sgd_dashboard_node_delete(NodeInterface $node): void {

  if ($node->bundle() == 'website') {

    $dataService = \Drupal::service('siteguardian.DataService');
    $cronService = \Drupal::service('siteguardian.CronService');

    // Delete the cron job.
    $cronService->deleteCronJob($node);

    // Delete the website data entity for the website.
    $dataService->deleteWebsiteData($node);

    // Delete all enabled project storage entities for the website.
    $dataService->deleteProjects($node);
  }
}

/**
 * Implements hook_form_views_exposed_form_alter().
 *
 * Redirects the projects by name exposed form to the layout page containing
 * the view.
 *
 * {@inheritdoc}
 */
function sgd_dashboard_form_views_exposed_form_alter(array &$form, FormStateInterface $form_state): void {

  // Redirect to website projects page.
  if ($form['#id'] == 'views-exposed-form-website-projects-projects-by-name') {
    $url = Url::fromRoute('sgd_dashboard.projects', []);
    $form['#action'] = $url->toString();
  }

  if ($form['#id'] == 'views-exposed-form-website-projects-projects-by-name' ||
      $form['#id'] == 'views-exposed-form-website-projects-projects-by-website-and-name') {

    $form['exact_match'] = [
      '#type' => 'radios',
      '#title' => t('Exact match'),
      '#description' => t('Only show projects whose title or machine name exactly match the search term.'),
      '#weight' => 1,
      '#options' => ['yes' => 'Yes', 'no' => 'No'],
      '#default_value' => 'yes',
    ];

    if (empty($form_state->getUserInput()['name'])) {
      $form['exact_match']['#attributes'] = ['data-bef-auto-submit-exclude' => ''];
    }

    // Set the order of the fields.
    $form['name']['#weight'] = 0;
    $form['exact_match']['#weight'] = 1;
    $form['sg_pr_status']['#weight'] = 2;
  }
}

/**
 * Implements hook_views_query_alter().
 *
 * Modify the view filter values.
 *
 * {@inheritdoc}
 */
function sgd_dashboard_views_query_alter(ViewExecutable $view, QueryPluginBase $query) {

  // If the website projects view and either of the displays.
  if ($view->id() == 'website_projects' && ($view->current_display == 'projects_by_name' || $view->current_display == 'projects_by_website_and_name')) {

    $queryOptions = \Drupal::request()->query->all();

    $searchValue = $queryOptions['name'] ?? NULL;
    $exactMatch = $queryOptions['exact_match'] ?? NULL;

    // Only the 'Name' field is exposed in the view so we need to add the
    // search condition to the 'title' field as well.
    $query->where[2]['conditions'][1] = [
      'field' => 'sgd_enabled_project.title',
      'value' => $query->where[2]['conditions'][0]["value"],
      'operator' => 'REGEXP',
    ];

    // If 'name' (the search value) has value and we are doing an exact match
    // search then we want to exact match search both the title and the machine
    // name fields so we need the regex to force exact match on both.
    if (!empty($searchValue)) {
      if (($exactMatch == 'yes')) {
        $query->where[2]['conditions'][0]["value"] = '(?:^|\W)' . $searchValue . '(?:$|\W)';
        $query->where[2]['conditions'][1]["value"] = '(?:^|\W)' . $searchValue . '(?:$|\W)';
      }
    }
    else {
      $query->where[2]['conditions'][0]["value"] = '(?:^|\W).*(?:$|\W)';
      $query->where[2]['conditions'][1]["value"] = '(?:^|\W).*(?:$|\W)';
    }

    // If the search value requests a status of 'Unsupported' then
    // we need to make sure the query searches for states 2 or 3.
    // As well as for any other status selected.
    $statusValues = $queryOptions['sg_pr_status'] ?? NULL;

    if (is_array($statusValues)) {

      // If 3 is  selected then add 4 to the search condition.
      if (!empty($statusValues["3"])) {
        $query->where[2]['conditions'][] = [
          "field" => '"sgd_enabled_project.status_id"',
          "value" => '2',
          "operator" => '=',
        ];
      }
    }
  }
}

/**
 * Implements hook_preprocess_HOOK().
 *
 * {@inheritdoc }
 */
function sgd_dashboard_preprocess_views_view_field(array &$variables): void {

  $modulePath = \Drupal::service('extension.list.module')->getPath('sgd_dashboard');

  $view_field = $variables['field']->field;

  if ($view_field == 'core_secure' || $view_field == 'contrib_secure') {

    /** @var \Drupal\sgd_dashboard\Entity\Bundle\WebsiteBundle $website */
    $website = $variables['row']->_entity;

    // Get tim ewhen site was last checked.
    $lastChecked = $website->field_site_last_checked->value;

    if (!empty($website->field_site_last_checked->value)) {

      $security_status = $variables['field']->getValue($variables['row']);
      $classes = $security_status ? "status-5" : "status-1";
      $security_status_message = $security_status ? t("Secure") : t("Not secure");

      $variables['output'] = Markup::create('<span class="' . $classes . ' ">' . $security_status_message . '</span>');
    }

    // Never been successfully scanned so status is unknown.
    else {
      $classes = "status-1";
      $security_status_message = t("Unknown");
  
      $variables['output'] = Markup::create('<span class="' . $classes . ' ">' . $security_status_message . '</span>');
    }
  }

  elseif ($view_field == 'status_id') {

    $status_id = $variables['field']->getValue($variables['row']);

    $status_str = match($status_id) {
      '5' => t('Up-to-date'),
      '4' => t('Updates available'),
      '3' => t('Unsupported'),
      '2' => t('Unsupported'),
      '1' => t('Security updates'),
      '' => t('Features made'),
      '-1' => t('Unknown'),
      '-2' => t('Unknown'),
      '-3' => t('Unknown'),
      '-4' => t('Unknown'),
    };

    $classes = "status-$status_id";

    $variables['output'] = Markup::create('<span class="' . $classes . ' ">' . $status_str . '</span>');
  }

  elseif ($view_field == 'drupal_version') {

    /** @var \Drupal\sgd_dashboard\Entity\Bundle\WebsiteBundle $website */
    $website = $variables['row']->_entity;

    $drupal_version_support_status = $website->getDataEntity()->getDrupalSupportStatus();
    $drupal_version_support_status_message = $website->getDataEntity()->getDrupalSupportStatusMessage();

    $eol_hourglass_colour = '';
    if (!empty($drupal_version_support_status)) {
      $eol_hourglass_colour = match($drupal_version_support_status->render()) {
        'danger' => 'red',
        'warning' => 'yellow',
        'ok' => 'green',
      };
    }

    $eol_hourglass_image = '<img src="/' . $modulePath . '/assets/hourglass-' . $eol_hourglass_colour . '-192x192.png" title="' . $drupal_version_support_status_message . '" class="eol-icon"/>';

    $drupal_version = $variables['field']->getValue($variables['row']);

    $version_output = !empty($drupal_version) ? $drupal_version : t('n/a');

    $variables['output'] = Markup::create($eol_hourglass_image . '<span class="drupal-version-support-status">' . $version_output . '</span>');
  }

  elseif ($view_field == 'php_version') {

    /** @var \Drupal\sgd_dashboard\Entity\Bundle\WebsiteBundle $website */
    $website = $variables['row']->_entity;

    $php_status = $website->getDataEntity()->getPhpSupportStatus();
    $php_status_message = $website->getDataEntity()->getPhpSupportStatusMessage();

    $eol_hourglass_colour = match($php_status->render()) {
      'danger' => 'red',
      'warning' => 'yellow',
      'ok' => 'green',
    };

    $eol_hourglass_image = '<img src="/' . $modulePath . '/assets/hourglass-' . $eol_hourglass_colour . '-192x192.png" title="' . $php_status_message . '" class="eol-icon"/>';

    $output = (!empty($variables['output'])) ? $variables['output']->__toString() : t('n/a');

    $variables['output'] = Markup::create($eol_hourglass_image . '<span class="php-security-support-status">' . $output . '</span>');
  }

  elseif ($view_field == 'db_version') {

    /** @var \Drupal\sgd_dashboard\Entity\Bundle\WebsiteBundle $website */
    $website = $variables['row']->_entity;

    $db_status = $website->getDataEntity()->getDbSupportStatus();
    $db_status_message = $website->getDataEntity()->getDbSupportStatusMessage();

    $eol_hourglass_colour = match($db_status->render()) {
      'danger' => 'red',
      'warning' => 'yellow',
      'ok' => 'green',
    };

    $eol_hourglass_image = '<img src="/' . $modulePath . '/assets/hourglass-' . $eol_hourglass_colour . '-192x192.png" title="' . $db_status_message . '" class="eol-icon"/>';

    $output = (!empty($variables['output'])) ? $variables['output']->__toString() : t('n/a');

    $variables['output'] = Markup::create($eol_hourglass_image . '<span class="db-version-support-status">' . $output . '</span>');
  }

  elseif ($view_field == 'field_site_last_checked') {

    /** @var \Drupal\sgd_dashboard\Entity\Bundle\WebsiteBundle $website */
    $website = $variables['row']->_entity;

    // Get values we need and work out delta.
    $lastChecked = $website->field_site_last_checked->value;
    $now = time();
    $delta = $now - $lastChecked;

    // Workout status class value.
    // If last checked more than 7 days ago then error.
    if ($lastChecked < $now - (60 * 60 * 24 * 7)) {
      $status = 'danger';
    }

    // If last checked more than a day ago then warning.
    elseif ($lastChecked < $now - (60 * 60 * 24)) {
      $status = 'warning';
    }

    // All good.
    else {
      $status = 'ok';
    }

    $classes = "status-last-checked-$status";

    // Workout the tooltip/status message.
    $lastCheckedDate = date("l jS \of F Y \a\\t H:i:s", $website->field_site_last_checked->value);

    $statusMessage = t("Website last checked on @date.", ['@date' => $lastCheckedDate]);

    // If less than a minute ago.
    if ($delta < 60) {
      $output = t('< 1 minute ago');
    }

    // If delta less than 1 hour then show mins since run.
    elseif ($delta < (60 * 60)) {
      $output = t('@time minutes ago', ['@time' => round($delta / 60, 0, PHP_ROUND_HALF_DOWN)]);
    }

    // If delta less than 1 day then show hours since run.
    elseif ($delta < (60 * 60 * 24)) {
      $output = t('@time hours ago', ['@time' => round($delta / (60 * 60), 0, PHP_ROUND_HALF_DOWN)]);
    }

    // Otherwise show days since run.
    elseif ($lastChecked > 0) {
      $output = t('@time days ago', ['@time' => round($delta / (60 * 60 * 24), 0, PHP_ROUND_HALF_DOWN)]);
    }

    else {
      $statusMessage = t("Website has never been checked.");
      $output = t('Never');
    }

    // Build the final output for the view field.
    $variables['output'] = Markup::create('<span class="' . $classes . ' " title="' . $statusMessage . '">' . $output . '</span>');
  }
}

/**
 * Implements hook_views_pre_render().
 */
function sgd_dashboard_views_pre_render(ViewExecutable $view) {

  if (isset($view)) {

    if ($view->storage->id() == 'websites' || $view->storage->id() == 'website_projects') {
      $view->element['#attached']['library'][] = 'sgd_dashboard/sgd_views';
    }
  }
}

/**
 * Implements hook_entity_bundle_info_alter().
 */
function sgd_dashboard_entity_bundle_info_alter(array &$bundles): void {

  if (isset($bundles['node']['website'])) {
    $bundles['node']['website']['class'] = WebsiteBundle::class;
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc