sgd_dashboard-1.0.0-beta1/src/Plugin/SgdCompanion/SgdCompanionPhpStatus.php

src/Plugin/SgdCompanion/SgdCompanionPhpStatus.php
<?php

namespace Drupal\sgd_dashboard\Plugin\SgdCompanion;

use Drupal\sgd_dashboard\SgdCompanionPluginBase;

/**
 * Provides a SGD Companion plugin.
 *
 * @SgdCompanion(
 *   id = "sgd_companion_php_status",
 * )
 */
class SgdCompanionPhpStatus extends SgdCompanionPluginBase {

  /**
   * {@inheritdoc}
   */
  public function canProcessStatus($statusData) : bool {

    // If the Site Guardian API Companion module 'PHP status' is installed on
    // the site we should have data from it.
    // Just checking for the existance of 'sgd_php_extensions' is enough.
    if (array_key_exists('sgd_php_extensions', $statusData)) {
      return TRUE;
    }
    else {
      return FALSE;
    }
  }

  /**
   * {@inheritdoc}
   */
  public function saveStatus($websiteData, $statusData, $enabledProjects = NULL) : bool {

    if ($this->canProcessStatus($statusData)) {

      // Following values are provided by the PHP status companion module.
      $phpData = [
        'php_post_max_size'       => $statusData['php_post_max_size'],
        'php_upload_max_filesize' => $statusData['php_upload_max_filesize'],
        'php_realpath_cache_size' => $statusData['php_realpath_cache_size'],
        'php_realpath_cache_ttl'  => $statusData['php_realpath_cache_ttl'],
        'php_max_execution_time'  => $statusData['php_max_execution_time'],
        'php_display_errors'      => $statusData['php_display_errors'],
        'php_error_reporting'     => $statusData['php_error_reporting'],
        'php_log_errors'          => $statusData['php_log_errors'],
        'php_error_log'           => $statusData['php_error_log'],
        'php_short_open_tag'      => $statusData['php_short_open_tag'],
        'php_max_input_vars'      => $statusData['php_max_input_vars'],
        'sgd_php_extensions'      => $statusData['sgd_php_extensions'],
      ];

      // Add the PHP settings that are provided by the core API module to the
      // saved data.
      // This means they will also display on the PHP data page for each
      // website.
      $phpData += [
        'php_version' => $statusData['php'],
        'php_memory_limit' => $statusData['php_memory_limit'],
        'php_apcu_caching' => $statusData['php_apcu_enabled'],
        'php_opcache' => $statusData['php_opcache'],
      ];

      // Serialize the data and save the field.
      $websiteData->set('data_php_status', serialize($phpData));

    }
    else {
      $websiteData->set('data_php_status', NULL);
    }

    return TRUE;
  }

  /**
   * {@inheritdoc}
   */
  public function getStatusDefaults() : array {
    return [];
  }

  /**
   * {@inheritdoc}
   */
  public function getStatus($websiteData) : array | NULL {

    if ($dataSerialized = $websiteData->get('data_php_status')->value) {

      $data = unserialize($dataSerialized, ['allowed_classes' => FALSE]);

      // Here is the opertunity to massage/transform any data we got from the
      // website status.
      // Do it here rather than when saving so we retain all info received.
      $data['php_version']['title'] = $this->t('PHP version');
      $data['php_version']['value'] = strtok($this->getValueOrDefault($data['php_version'] ?? NULL), '(');

    }
    else {
      $data = NULL;
    }

    return $data;
  }

  /**
   * {@inheritdoc}
   */
  public function getBuildElements($websiteData) : array | NULL {

    if ($data = $this->getStatus($websiteData)) {

      $elements = [];

      $validation = $this->validate($data);

      foreach ($data as $key => $value) {
        if ($key != 'sgd_php_extensions') {
          $elements[$key] = [
            'title' => $value['title'],
            'value' => $value['value'],
            'status' => $validation[$key] ?? NULL,
          ];
        }
      }

      return $elements;
    }

    return NULL;
  }

  /**
   * Validate data.
   *
   * Checks specific status items and for those where practicle returns a
   *  good/neutral/bad status that can be displayed on page or in a report.
   */
  private function validate(&$statusData): array {

    $validation = [];

    // Validate PHP variables.
    // Each validation is hard coded as it differs for each plugin.
    foreach ($statusData as $key => $status) {

      $phpVar = substr($key, 4);

      switch ($key) {

        case 'php_post_max_size':

          // Get the 'real' value from the value saved which could be an int or
          // in shorthand format.
          $intValue = $this->getShortHandValue($status['value']);

          if ($intValue < (10 * 1024 * 1024)) {
            $validation[$key] = [
              'class' => 'error',
              'text' => $this->t('Issue'),
              'message' => $this->t('post_max_size too low, &lt; 10M. Review and set appropriately.'),
            ];
          }
          elseif ($intValue < (25 * 1024 * 1024) || $intValue > (50 * 1024 * 1024)) {
            $validation[$key] = [
              'class' => 'warning',
              'text' => $this->t('Alert'),
              'message' => $this->t('post_max_size maybe too low, &lt; 25M, or too high &gt; 50M.'),
            ];
          }
          else {
            $validation[$key] = [
              'class' => 'ok',
              'text' => $this->t('OK'),
            ];
          }

          break;

        case 'php_upload_max_filesize':

          // Get the 'real' value from the value saved which could be an int or
          // in shorthand format.
          $intValue = $this->getShortHandValue($status['value']);

          if ($intValue < (2 * 1024 * 1024)) {
            $validation[$key] = [
              'class' => 'error',
              'text' => $this->t('Issue'),
              'message' => $this->t('upload_max_filesize to low, &lt; 2M. Review and set appropriately.'),
            ];
          }
          elseif ($intValue < (5 * 1024 * 1024) || $intValue > (20 * 1024 * 1024)) {
            $validation[$key] = [
              'class' => 'warning',
              'text' => $this->t('Alert'),
              'message' => $this->t('upload_max_filesize maybe too low, &lt; 5M, or too high &gt; 20M.'),
            ];
          }
          else {
            $validation[$key] = [
              'class' => 'ok',
              'text' => $this->t('OK'),
            ];
          }

          break;

        case 'php_realpath_cache_size':

          // Get the 'real' value from the value saved which could be an int or
          // in shorthand format.
          $intValue = $this->getShortHandValue($status['value']);

          if ($intValue < (64 * 1024)) {
            $validation[$key] = [
              'class' => 'error',
              'text' => $this->t('Issue'),
              'message' => $this->t('realpath_cache_size too low, &lt; 64K. Review and set appropriately.'),
            ];
          }
          else {
            $validation[$key] = [
              'class' => 'ok',
              'text' => $this->t('OK'),
            ];
          }

          break;

        case 'php_realpath_cache_ttl':

          $intValue = intval($status['value']);

          if ($intValue < 3600) {
            $validation[$key] = [
              'class' => 'error',
              'text' => $this->t('Issue'),
              'message' => $this->t('realpath_cache_ttl too  low, &lt; 3600. Review and set appropriately.'),
            ];
          }
          else {
            $validation[$key] = [
              'class' => 'ok',
              'text' => $this->t('OK'),
            ];
          }

          break;

        case 'php_display_errors':
        case 'php_display_startup_errors':

          if (in_array(strtolower($status['value']), ['1', 'yes', 'on', 'true'])) {
            $validation[$key] = [
              'class' => 'warning',
              'text' => $this->t('Alert'),
              'message' => $this->t('@phpvar is enabled. It is recommended it be off on production systems.', ['@phpvar' => $phpVar]),
            ];

          }
          else {
            $validation[$key] = [
              'class' => 'ok',
              'text' => $this->t('OK'),
            ];

            $statusData[$key]['value'] = 'False';
          }

          break;

        case 'php_log_errors':
        case 'php_html_errors':

          if (!in_array(strtolower($status['value']), ['1', 'yes', 'on', 'true'])) {
            $validation[$key] = [
              'class' => 'error',
              'text' => $this->t('Issue'),
              'message' => $this->t('@phpvar is disabled. It is recommended it be turned on.', ['@phpvar' => $phpVar]),
            ];

          }
          else {
            $validation[$key] = [
              'class' => 'ok',
              'text' => $this->t('OK'),
            ];
          }

          break;

        case 'php_error_reporting':

          if ($status['value'] != (E_ALL & ~E_STRICT & ~E_USER_DEPRECATED)) {
            $validation[$key] = [
              'class' => 'warning',
              'text' => $this->t('Alert'),
              'message' => $this->t('error_reporting is not set as recommended for production systems. Recommended value is E_ALL & ~E_STRICT & ~E_USER_DEPRECATED.'),
            ];
          }
          else {
            $validation[$key] = [
              'class' => 'ok',
              'text' => $this->t('OK'),
            ];
          }

          break;

        case 'php_apcu_caching':
        case 'php_opcache':

          $enabled = strtolower(strtok($status['value'], ' ()'));

          if ($enabled != 'enabled') {
            $validation[$key] = [
              'class' => 'warning',
              'text' => $this->t('Alert'),
              'message' => $this->t('@phpvar is not enabled.', ['@phpvar' => $phpVar]),
            ];
          }
          else {
            $validation[$key] = [
              'class' => 'ok',
              'text' => $this->t('OK'),
            ];
          }
          break;

        case 'php_max_execution_time':

          $intValue = intval($status['value']);

          if ($intValue < 30) {
            $validation[$key] = [
              'class' => 'warning',
              'text' => $this->t('Alert'),
              'message' => $this->t('max_execution_time too low, &lt; 30 seconds. Review and set appropriately.'),
            ];
          }
          else {
            $validation[$key] = [
              'class' => 'ok',
              'text' => $this->t('OK'),
            ];
          }

          break;

        case 'php_max_input_vars':

          $intValue = intval($status['value']);

          if ($intValue < 2000) {
            $validation[$key] = [
              'class' => 'warning',
              'text' => $this->t('Alert'),
              'message' => $this->t('max_input_vars too low, &lt; 2000. Review and set appropriately.'),
            ];
          }
          else {
            $validation[$key] = [
              'class' => 'ok',
              'text' => $this->t('OK'),
            ];
          }

          break;

        case 'php_memory_limit':

          // Get the 'real' value from the value saved which could be an int or
          // in shorthand format.
          $intValue = $this->getShortHandValue($status['value']);

          if ($intValue < 32 * 1024 * 1024) {
            $validation[$key] = [
              'class' => 'error',
              'text' => $this->t('Issue'),
              'message' => $this->t('memory_limit too low, &lt; 32M. Review and set appropriately.'),
            ];
          }
          elseif ($intValue > 100 * 1024 * 1024) {
            $validation[$key] = [
              'class' => 'warning',
              'text' => $this->t('Alert'),
              'message' => $this->t('memory_limit may be too high, &gt; 100M. Review and set appropriately.'),
            ];
          }
          else {
            $validation[$key] = [
              'class' => 'ok',
              'text' => $this->t('OK'),
            ];
          }

          break;

        case 'php_short_open_tag':

          if (filter_var($status['value'], FILTER_VALIDATE_BOOLEAN)) {
            $validation[$key] = [
              'class' => 'error',
              'text' => $this->t('Issue'),
              'message' => $this->t('Use of short tags is discouraged and is likely to depreciated at some point.'),
            ];
          }
          else {
            $validation[$key] = [
              'class' => 'ok',
              'text' => $this->t('OK'),
            ];
          }

          break;

      }
    }

    return $validation;
  }

  /**
   * Return a number from a PHP INI value that maybe in shorthand format.
   *
   * For example: 5M or 25K.
   */
  private function getShortHandValue($val) : int {

    switch (strtolower(substr(trim($val), -1))) {

      case 'k':
        return (int) $val * 1024;

      case 'm':
        return (int) $val * 1024 * 1024;

      case 'g':
        return (int) $val * 1024 * 1024 * 1024;

      default:
        return (int) $val;
    }
  }

}

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

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