sgd_dashboard-1.0.0-beta1/src/Entity/SgdWebsiteData.php

src/Entity/SgdWebsiteData.php
<?php

declare(strict_types=1);

namespace Drupal\sgd_dashboard\Entity;

use Drupal\Core\Entity\ContentEntityBase;
use Drupal\Core\Entity\EntityChangedTrait;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Datetime\DrupalDateTime;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\sgd_dashboard\SgdWebsiteDataInterface;
use Drupal\user\EntityOwnerTrait;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\StringTranslation\TranslatableMarkup;

use Drupal\sgd_dashboard\Exception\EndOfLifeClientException;

/**
 * Defines the sgd website data entity class.
 *
 * @ContentEntityType(
 *   id = "sgd_website_data",
 *   label = @Translation("Site Guardian Dashboard Website data entity"),
 *   label_collection = @Translation("Site Guardian Dashboard Website data entities"),
 *   label_singular = @Translation("Site Guardian Dashboard website data entity"),
 *   label_plural = @Translation("Site Guardian Dashboard website data entities"),
 *   label_count = @PluralTranslation(
 *     singular = "@count Site Guardian Dashboard website data entity",
 *     plural = "@count Site Guardian Dashboard website data entities",
 *   ),
 *   handlers = {
 *     "list_builder" = "Drupal\sgd_dashboard\SgdWebsiteDataListBuilder",
 *     "views_data" = "Drupal\sgd_dashboard\SgdWebsiteDataEntityViewsData",
 *     "form" = {
 *       "add" = "Drupal\sgd_dashboard\Form\SgdWebsiteDataForm",
 *       "edit" = "Drupal\sgd_dashboard\Form\SgdWebsiteDataForm",
 *       "delete" = "Drupal\Core\Entity\ContentEntityDeleteForm",
 *       "delete-multiple-confirm" = "Drupal\Core\Entity\Form\DeleteMultipleForm",
 *     },
 *     "route_provider" = {
 *       "html" = "Drupal\sgd_dashboard\Routing\SgdWebsiteDataHtmlRouteProvider",
 *     },
 *   },
 *   base_table = "sgd_website_data",
 *   admin_permission = "administer sgd_website_data",
 *   entity_keys = {
 *     "id" = "id",
 *     "label" = "label",
 *     "uuid" = "uuid",
 *     "owner" = "uid",
 *   },
 *   links = {
 *     "collection" = "/admin/content/sgd-website-data",
 *     "add-form" = "/sgd-website-data/add",
 *     "canonical" = "/sgd-website-data/{sgd_website_data}",
 *     "edit-form" = "/sgd-website-data/{sgd_website_data}",
 *     "delete-form" = "/sgd-website-data/{sgd_website_data}/delete",
 *     "delete-multiple-form" = "/admin/content/sgd-website-data/delete-multiple",
 *   },
 * )
 */
class SgdWebsiteData extends ContentEntityBase implements SgdWebsiteDataInterface {

  use EntityChangedTrait;
  use EntityOwnerTrait;
  use StringTranslationTrait;

  /**
   * {@inheritdoc}
   */
  public function preSave(EntityStorageInterface $storage): void {
    parent::preSave($storage);
    if (!$this->getOwnerId()) {
      // If no owner has been set explicitly, make the anonymous user the owner.
      $this->setOwnerId(0);
    }
  }

  /**
   * {@inheritdoc}
   */
  public static function baseFieldDefinitions(EntityTypeInterface $entity_type): array {

    $fields = parent::baseFieldDefinitions($entity_type);

    $fields['label'] = BaseFieldDefinition::create('string')
      ->setLabel(t('Label'))
      ->setRequired(TRUE)
      ->setSetting('max_length', 255)
      ->setDisplayOptions('form', [
        'type' => 'string_textfield',
        'weight' => -5,
      ])
      ->setDisplayConfigurable('form', TRUE)
      ->setDisplayOptions('view', [
        'label' => 'hidden',
        'type' => 'string',
        'weight' => -5,
      ])
      ->setDisplayConfigurable('view', TRUE);

    $fields['contrib_secure'] = BaseFieldDefinition::create('boolean')
      ->setLabel(t('Contrib security'))
      ->setDescription(t('A boolean indicating whether all the contributed module versions in use are secure or not.'))
      ->setDefaultValue(FALSE)
      ->setSettings(['on_label' => 'Secure', 'off_label' => 'Not secure'])
      ->setDisplayOptions('view', [
        'label' => 'visible',
        'type' => 'boolean',
        'weight' => -4,
      ])
      ->setDisplayOptions('form', [
        'type' => 'boolean_checkbox',
        'weight' => -4,
      ])
      ->setDisplayConfigurable('view', TRUE);

    $fields['core_secure'] = BaseFieldDefinition::create('boolean')
      ->setLabel(t('Core security'))
      ->setDescription(t('A boolean indicating whether Drupal core is secure or not.'))
      ->setDefaultValue(FALSE)
      ->setSettings(['on_label' => 'Secure', 'off_label' => 'Not secure'])
      ->setDisplayOptions('view', [
        'label' => 'visible',
        'type' => 'boolean',
        'weight' => -3,
      ])
      ->setDisplayOptions('form', [
        'type' => 'boolean_checkbox',
        'weight' => -3,
      ])
      ->setDisplayConfigurable('view', TRUE);

    $fields['drupal_version'] = BaseFieldDefinition::create('string')
      ->setLabel(t('Drupal version'))
      ->setDescription(t('The string representation of the Drupal version.'))
      ->setSettings([
        'max_length' => 255,
        'text_processing' => 0,
      ])
      ->setDefaultValue('')
      ->setDisplayOptions('view', [
        'label' => 'above',
        'type' => 'string',
        'weight' => -2,
      ])
      ->setDisplayOptions('form', [
        'type' => 'string_textfield',
        'weight' => -2,
      ])
      ->setDisplayConfigurable('view', TRUE);

    $fields['php_version'] = BaseFieldDefinition::create('string')
      ->setLabel(t('PHP version'))
      ->setDescription(t('The string representation of the PHP version.'))
      ->setSettings([
        'max_length' => 255,
        'text_processing' => 0,
      ])
      ->setDefaultValue('')
      ->setDisplayOptions('view', [
        'label' => 'above',
        'type' => 'string',
        'weight' => -1,
      ])
      ->setDisplayOptions('form', [
        'type' => 'string_textfield',
        'weight' => -1,
      ])
      ->setDisplayConfigurable('view', TRUE);

    $fields['db_version'] = BaseFieldDefinition::create('string')
      ->setLabel(t('Database version'))
      ->setDescription(t('The string representation of the database version.'))
      ->setSettings([
        'max_length' => 255,
        'text_processing' => 0,
      ])
      ->setDefaultValue('')
      ->setDisplayOptions('view', [
        'label' => 'above',
        'type' => 'string',
        'weight' => 0,
      ])
      ->setDisplayOptions('form', [
        'type' => 'string_textfield',
        'weight' => 0,
      ])
      ->setDisplayConfigurable('view', TRUE);

    $fields['data_core'] = BaseFieldDefinition::create('string_long')
      ->setLabel(t('Core data'))
      ->setDescription(t('SGD Core data from site_guardian_api module.'))
      ->setRequired(TRUE)
      ->setDisplayOptions('view', [
        'label' => 'visible',
        'type' => 'basic_string',
        'weight' => 1,
      ])
      ->setDisplayOptions('form', [
        'type' => 'string_textarea',
        'weight' => 1,
        'settings' => ['rows' => 4],
      ])
      ->setDisplayConfigurable('view', TRUE);

    $fields['data_server_benchmarks'] = BaseFieldDefinition::create('string_long')
      ->setLabel(t('Server Benchmark data'))
      ->setDescription(t('Server Benchmark data from sgd_server_benchmarks module.'))
      ->setRequired(FALSE)
      ->setDisplayOptions('view', [
        'label' => 'visible',
        'type' => 'basic_string',
        'weight' => 2,
      ])
      ->setDisplayOptions('form', [
        'type' => 'string_textarea',
        'weight' => 2,
        'settings' => ['rows' => 4],
      ])
      ->setDisplayConfigurable('view', TRUE);

    $fields['data_php_status'] = BaseFieldDefinition::create('string_long')
      ->setLabel(t('PHP data'))
      ->setDescription(t('PHP data from sgd_php_status module.'))
      ->setRequired(FALSE)
      ->setDisplayOptions('view', [
        'label' => 'visible',
        'type' => 'basic_string',
        'weight' => 3,
      ])
      ->setDisplayOptions('form', [
        'type' => 'string_textarea',
        'weight' => 3,
        'settings' => ['rows' => 4],
      ])
      ->setDisplayConfigurable('view', TRUE);

    $fields['data_user_status'] = BaseFieldDefinition::create('string_long')
      ->setLabel(t('User data'))
      ->setDescription(t('User data from sgd_user_status module.'))
      ->setRequired(FALSE)
      ->setDisplayOptions('view', [
        'label' => 'visible',
        'type' => 'basic_string',
        'weight' => 4,
      ])
      ->setDisplayOptions('form', [
        'type' => 'string_textarea',
        'weight' => 4,
        'settings' => ['rows' => 4],
      ])
      ->setDisplayConfigurable('view', TRUE);

    $fields['data_watchdog_summary'] = BaseFieldDefinition::create('string_long')
      ->setLabel(t('Watchdog summary data'))
      ->setDescription(t('Watchdog summary data from sgd_watchdog_summary module.'))
      ->setRequired(FALSE)
      ->setDisplayOptions('view', [
        'label' => 'visible',
        'type' => 'basic_string',
        'weight' => 5,
      ])
      ->setDisplayOptions('form', [
        'type' => 'string_textarea',
        'weight' => 5,
        'settings' => ['rows' => 4],
      ])
      ->setDisplayConfigurable('view', TRUE);

    $fields['data_php_memory_usage'] = BaseFieldDefinition::create('string_long')
      ->setLabel(t('PHP Memory Usage data'))
      ->setDescription(t('PHP Memory Usage data from memory_profiler_plus module.'))
      ->setRequired(FALSE)
      ->setDisplayOptions('view', [
        'label' => 'visible',
        'type' => 'basic_string',
        'weight' => 5,
      ])
      ->setDisplayOptions('form', [
        'type' => 'string_textarea',
        'weight' => 5,
        'settings' => ['rows' => 4],
      ])
      ->setDisplayConfigurable('view', TRUE);

    $fields['status'] = BaseFieldDefinition::create('boolean')
      ->setLabel(t('Status'))
      ->setDefaultValue(TRUE)
      ->setSetting('on_label', 'Enabled')
      ->setDisplayOptions('form', [
        'type' => 'boolean_checkbox',
        'settings' => [
          'display_label' => FALSE,
        ],
        'weight' => 0,
      ])
      ->setDisplayConfigurable('form', TRUE)
      ->setDisplayOptions('view', [
        'type' => 'boolean',
        'label' => 'above',
        'weight' => 0,
        'settings' => [
          'format' => 'enabled-disabled',
        ],
      ])
      ->setDisplayConfigurable('view', TRUE);

    $fields['uid'] = BaseFieldDefinition::create('entity_reference')
      ->setLabel(t('Author'))
      ->setSetting('target_type', 'user')
      ->setDefaultValueCallback(self::class . '::getDefaultEntityOwner')
      ->setDisplayOptions('form', [
        'type' => 'entity_reference_autocomplete',
        'settings' => [
          'match_operator' => 'CONTAINS',
          'size' => 60,
          'placeholder' => '',
        ],
        'weight' => 15,
      ])
      ->setDisplayConfigurable('form', TRUE)
      ->setDisplayOptions('view', [
        'label' => 'above',
        'type' => 'author',
        'weight' => 15,
      ])
      ->setDisplayConfigurable('view', TRUE);

    $fields['created'] = BaseFieldDefinition::create('created')
      ->setLabel(t('Authored on'))
      ->setDescription(t('The time that the SGD Website data entity was created.'))
      ->setDisplayOptions('view', [
        'label' => 'above',
        'type' => 'timestamp',
        'weight' => 20,
      ])
      ->setDisplayConfigurable('form', TRUE)
      ->setDisplayOptions('form', [
        'type' => 'datetime_timestamp',
        'weight' => 20,
      ])
      ->setDisplayConfigurable('view', TRUE);

    $fields['changed'] = BaseFieldDefinition::create('changed')
      ->setLabel(t('Changed'))
      ->setDescription(t('The time that the SGD Website data entity was last edited.'));

    return $fields;
  }

  /**
   * Returns the parent website node Id of the website data entity.
   */
  public function getParentNodeId() {

    // Get the node id of the parent website node.
    $query = \Drupal::entityQuery('node')
      ->condition('type', 'website')
      ->condition('field_sgd_website_data', $this->id())
      ->accessCheck(FALSE);

    $results = $query->execute();

    return reset($results);
  }

  /**
   * Get the support status of the website's Drupal version.
   *
   * @return Drupal\Core\StringTranslation\TranslatableMarkup
   *   Drupal Version Status info as a string - 'ok', 'warning' or 'danger'.
   */
  public function getDrupalSupportStatus(): TranslatableMarkup {

    $product = 'drupal';
    $version = $this->get('drupal_version')->value;

    if (!empty($version) && (int) $version >= 8) {
      $cycle = implode('.', array_slice(explode('.', $version, 3), 0, 2, TRUE));
    }
    else {
      return $this->t('danger');
    }

    try {
      $eolClient = \Drupal::service('siteguardian.EndOfLifeClientService');
      $statusData = $eolClient->getSingleCycle($product, $cycle);
    }
    catch (EndOfLifeClientException $e) {
      \Drupal::logger('site_guardian')->error("Error getting endoflife.date status for %product: @error", [
        '%product' => ucfirst($product),
        '@error' => $e->getMessage(),
      ]);
      return $this->t('danger');
    }

    $now = time();

    if (!empty($statusData)) {

      $support = strtotime($statusData['support']);

      // If EOL is false then there is no EOL specified otherwise get the timestamp.
      $eol = $statusData['eol'] == FALSE ? FALSE : strtotime($statusData['eol']);

      if ($eol == FALSE || ($support >= $now && $eol >= $now)) {
        $status = $this->t('ok');
      }
      elseif ($support < $now && $eol >= $now) {
        $status = $this->t('warning');
      }
      else {
        $status = $this->t('danger');
      }
    }

    else {
      $status = $this->t('not-available');
    }

    return $status;
  }

  /**
   * Get a string indicating the website's Drupal version's support status.
   *
   * @return Drupal\Core\StringTranslation\TranslatableMarkup
   *   A more user-friendly message about Drupal version support status.
   */
  public function getDrupalSupportStatusMessage(): TranslatableMarkup {

    $product = 'drupal';
    $version = $this->get('drupal_version')->value;

    if (!empty($version)) {
      $cycle = implode('.', array_slice(explode('.', $version, 3), 0, 2, TRUE));
    }
    else {
      return $this->t("Unable to determine Drupal version or support status.");
    }

    try {
      $eolClient = \Drupal::service('siteguardian.EndOfLifeClientService');
      $statusData = $eolClient->getSingleCycle($product, $cycle);
    }
    catch (EndOfLifeClientException $e) {
      \Drupal::logger('site_guardian')->error("Error getting endoflife.date status for %product: @error", [
        '%product' => ucfirst($product),
        '@error' => $e->getMessage(),
      ]);
      return $this->t("EndOfLife API was unavailable.");
    }

    if (!empty($statusData)) {
      $supported = (new DrupalDateTime($statusData['support'], 'UTC'))->format('l jS \of F Y');
      $eol = $statusData['eol'] ? (new DrupalDateTime($statusData['eol'], 'UTC'))->format('l jS \of F Y') : $this->t('unspecified date');
      $statusMessage = $this->t("Active support until :supported, Security support until :eol.", [
        ':supported' => $supported,
        ':eol' => $eol,
      ]);
    }

    else {
      $statusMessage = $this->t('Detailed status support info is not available for this version - please visit https://endoflife.date/drupal instead.');
    }

    return $statusMessage;
  }

  /**
   * Get the support status of PHP for the website.
   *
   * @return Drupal\Core\StringTranslation\TranslatableMarkup
   *   PHP Status info as a string 'ok', 'warning', 'danger'
   */
  public function getPhpSupportStatus(): TranslatableMarkup {

    $product = 'php';
    $version = $this->get('php_version')->value;

    if (!empty($version)) {
      $cycle = implode('.', array_slice(explode('.', $version, 3), 0, 2, TRUE));
    }
    else {
      return $this->t('danger');
    }

    // Get the PHP version support status.
    try {
      $eolClient = \Drupal::service('siteguardian.EndOfLifeClientService');
      $statusData = $eolClient->getSingleCycle($product, $cycle);
    }

    // If the API had an exception then we need to handle it.
    catch (EndOfLifeClientException $e) {

      \Drupal::logger('site_guardian')->error("Error getting PHP endoflife status for %product: @error", [
        '%product' => $product,
        '@error' => $e->getMessage(),
      ]);

      // We couldn't find out the status so we'll go nuclear and say everything
      // is bad.
      return $this->t('danger');
    }

    // Work out what to return - ok, warning or none.
    $now = time();

    $support = strtotime($statusData['support']);
    $eol = strtotime($statusData['eol']);

    // If has both active and security support the 'ok'.
    if ($support >= $now && $eol >= $now) {
      $status = $this->t('ok');
    }

    // If no active support but still have security support then 'warning'.
    elseif ($support < $now && $eol >= $now) {
      $status = $this->t('warning');
    }

    // Anything else is 'danger'.
    else {
      $status = $this->t('danger');
    }

    return $status;
  }

  /**
   * Return a string message indicating the support status of the PHP version.
   *
   * @return Drupal\Core\StringTranslation\TranslatableMarkup
   *   A more user-friendly message about PHP version support status.
   */
  public function getPhpSupportStatusMessage(): TranslatableMarkup {

    $product = 'php';

    $version = $this->get('php_version')->value;

    if (!empty($version)) {
      $cycle = implode('.', array_slice(explode('.', $version, 3), 0, 2, TRUE));
    }
    else {
      return $this->t("Unable to determine PHP version or support status.");
    }

    // Get the PHP version support status.
    try {
      $eolClient = \Drupal::service('siteguardian.EndOfLifeClientService');
      $statusData = $eolClient->getSingleCycle($product, $cycle);
    }

    // If the API had an exception then we need to handle it.
    catch (EndOfLifeClientException $e) {

      \Drupal::logger('site_guardian')->error("Error getting PHP endoflife status for %product: @error", [
        '%product' => $product,
        '@error' => $e->getMessage(),
      ]);

      // We couldn't find out the status so we'll go nuclear and say everything
      // is bad.
      return $this->t('EndofLife API was unavailable.');
    }

    // Now we have the product cycle info we can build a descriptive string.
    $supported = (new DrupalDateTime($statusData['support'], 'UTC'))->format('l jS \of F Y');
    $eol = (new DrupalDateTime($statusData['eol'], 'UTC'))->format('l jS \of F Y');

    return $this->t("Active support until :supported, Security support until :eol.", [
      ':supported' => $supported,
      ':eol' => $eol,
    ]);
  }

  /**
   * Get the support status of the Database for the website.
   *
   * @return Drupal\Core\StringTranslation\TranslatableMarkup
   *   DB Status info as a string 'ok', 'warning', 'danger'
   */
  public function getDbSupportStatus(): TranslatableMarkup {

    // Now try to figure out what we are using so we can ask API for
    // appropriate info.
    $dbVersionString = $this->get('db_version')->value;

    if (!empty($dbVersionString)) {
      ['product' => $product, 'cycle' => $cycle] = $this->getDbProductAndCycle($dbVersionString);
    }
    else {
      return $this->t('danger');
    }

    // Get the DB version support status.
    try {
      $eolClient = \Drupal::service('siteguardian.EndOfLifeClientService');
      $statusData = $eolClient->getSingleCycle($product, $cycle);
    }

    // If the API had an exception then we need to handle it.
    catch (EndOfLifeClientException $e) {

      \Drupal::logger('site_guardian')->error("Error getting DB endoflife status for %product: @error", [
        '%product' => $product,
        '@error' => $e->getMessage(),
      ]);

      // We couldn't find out the status so we'll go nuclear and say everything
      // is bad.
      return $this->t('danger');
    }

    // Work out what to return - ok, warning or none. If no eol status then
    // return danger.
    if (!empty($statusData['eol'])) {

      $now = time();

      switch ($product) {

        case 'mariadb':

          $eol = strtotime($statusData['eol']);

          if ($eol < $now) {
            $status = $this->t('danger');
          }
          elseif ($eol < $now + (60 * 60 * 24 * 30 * 3)) {
            $status = $this->t('warning');
          }
          else {
            $status = $this->t('ok');
          }
          break;

        case 'mysql':

          $eol = strtotime($statusData['eol']);

          if ($eol < $now) {
            $status = $this->t('danger');
          }
          elseif ($eol < $now + (60 * 60 * 24 * 30 * 3)) {
            $status = $this->t('warning');
          }
          else {
            $status = $this->t('ok');
          }
          break;
      }

      return $status;
    }

    else {
      return $this->t('danger');
    }
  }

  /**
   * Return a string message inidcating the support status of the DB version.
   *
   * @return Drupal\Core\StringTranslation\TranslatableMarkup
   *   A more user-friendly message about DB version support status.
   */
  public function getDbSupportStatusMessage(): TranslatableMarkup {

    // Now try to figure out what we are using so we can ask API for
    // appropriate info.
    $dbVersionString = $this->get('db_version')->value;

    if (!empty($dbVersionString)) {
      ['product' => $product, 'cycle' => $cycle] = $this->getDbProductAndCycle($dbVersionString);
    }
    else {
      return $this->t("Unable to determine DB version or support status.");
    }

    // Get the DB version support status.
    try {
      $eolClient = \Drupal::service('siteguardian.EndOfLifeClientService');
      $statusData = $eolClient->getSingleCycle($product, $cycle);
    }

    // If the API had an exception then we need to handle it.
    catch (EndOfLifeClientException $e) {
      \Drupal::logger('site_guardian')->error("Error getting DB endoflife status for %product: @error", [
        '%product' => $product,
        '@error' => $e->getMessage(),
      ]);

      // We couldn't find out the status so we'll go nuclear and say everything
      // is bad.
      return $this->t('EndofLife API was unavailable for :product.', [':product' => $product]);
    }

    // Now we have the product cycle info we can build a descriptive string.
    if (!empty($statusData['eol'])) {

      $eol = (new DrupalDateTime($statusData['eol'], 'UTC'))->format('l jS \of F Y');

      // If eol date is in future.
      if (strtotime($statusData['eol']) > time()) {
        return $this->t("Support ends on :eol.", [':eol' => $eol]);
      }
      else {
        return $this->t("Support ended on :eol.", [':eol' => $eol]);
      }
    }
    else {
      return $this->t("No end of life information available.");
    }
  }

  /**
   * Return the support cycle of the DB version.
   *
   * This is parsed from the version returned from the DB and is
   * not an exact science as there are no standards.
   */
  private function getDbProductAndCycle($versionString): array {

    // If the version contains 'MariaDB' then we know its Maria DB.
    if (stripos($versionString, 'mariadb') !== FALSE) {
      $product = 'mariadb';
      preg_match('/^(\d+\.\d+\.\d+)/', $versionString, $matches);
      $cycle = implode('.', array_slice(explode('.', $matches[1], 3), 0, 2, TRUE));
    }

    // If the version contains 'PostgreSQL' then we know its Maria DB.
    elseif (stripos($versionString, 'PostgreSQL') !== FALSE) {
      $product = 'postgresql';
      preg_match('/\b(\d+\.\d+)\b/', $versionString, $matches);
      $cycle = $matches[1];
    }

    // If the version contains 'Microsoft' then we know its Microsoft.
    elseif (stripos($versionString, 'Microsoft') !== FALSE) {
      $product = 'mssqlserver';
      preg_match('/\b(\d+\.\d+\.\d+\.\d+)\b/', $versionString, $matches);
      $cycle = $matches[1];
    }

    // Otherwise assume Mysql.
    else {
      $product = 'mysql';
      preg_match('/^(\d+\.\d+\.\d+)/', $versionString, $matches);
      $cycle = implode('.', array_slice(explode('.', $matches[1], 3), 0, 2, TRUE));
    }

    return ['product' => $product, 'cycle' => $cycle];
  }

}

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

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