You are here

class W3CProcessor in W3C Validator 8

Processor for page validation.

Hierarchy

Expanded class hierarchy of W3CProcessor

4 files declare their use of W3CProcessor
W3CLogController.php in src/Controller/W3CLogController.php
W3CValidatorOperationConfirmForm.php in src/Form/W3CValidatorOperationConfirmForm.php
W3CValidatorOperationForm.php in src/Form/W3CValidatorOperationForm.php
W3cValidatorSettingsForm.php in src/Form/W3cValidatorSettingsForm.php
1 string reference to 'W3CProcessor'
w3c_validator.services.yml in ./w3c_validator.services.yml
w3c_validator.services.yml
1 service uses W3CProcessor
w3c.processor in ./w3c_validator.services.yml
Drupal\w3c_validator\W3CProcessor

File

src/W3CProcessor.php, line 20

Namespace

Drupal\w3c_validator
View source
class W3CProcessor {
  use StringTranslationTrait;
  use DependencySerializationTrait;

  /**
   * A W3cTokenManager instance.
   *
   * @var \Drupal\w3c_validator\W3CTokenManager
   */
  protected $w3cTokenManager;

  /**
   * The database connection.
   *
   * @var \Drupal\Core\Database\Connection
   */
  protected $connection;

  /**
   * The configuration factory.
   *
   * @var \Drupal\Core\Config\ConfigFactoryInterface
   */
  protected $configFactory;

  /**
   * The access manager.
   *
   * @var \Drupal\Core\Access\AccessManagerInterface
   */
  protected $accessManager;

  /**
   * The current user.
   *
   * @var \Drupal\Core\Session\AccountInterface
   */
  protected $currentUser;

  /**
   * A logger instance.
   *
   * @var \Psr\Log\LoggerInterface
   */
  protected $logger;

  /**
   * The module configurations.
   *
   * @var array
   */
  protected $moduleSettings;

  /**
   * Constructs a W3CSubscriber object.
   *
   * @param \Drupal\w3c_validator\W3CTokenManager $w3c_token_manager
   *   The form builder service.
   * @param \Drupal\Core\Database\Connection $connection
   *   The database connection.
   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
   *   The configuration factory.
   * @param \Drupal\Core\Access\AccessManagerInterface $access_manager
   *   The access manager interface.
   * @param \Drupal\Core\Session\AccountInterface $current_user
   *   The current user.
   * @param \Psr\Log\LoggerInterface $logger
   *   A logger instance.
   */
  public function __construct(W3CTokenManager $w3c_token_manager, Connection $connection, ConfigFactoryInterface $config_factory, AccessManagerInterface $access_manager, AccountInterface $current_user, LoggerInterface $logger) {
    $this->w3cTokenManager = $w3c_token_manager;
    $this->connection = $connection;
    $this->configFactory = $config_factory;
    $this->accessManager = $access_manager;
    $this->currentUser = $current_user;
    $this->logger = $logger;
  }

  /**
   * Get W3C configured validator URL.
   *
   * @return string
   *   The validator URL.
   */
  public function getValidatorUrl() {
    $config_url = $this
      ->moduleSettings()
      ->get('validator_url');
    return empty($config_url) ? Validator::DEFAULT_VALIDATOR_URL : $config_url;
  }

  /**
   * Find all pages URL to validate in the site.
   *
   * Currently, this method returns :
   *     - frontpage
   *  - nodes.
   *
   * @return array
   *   List of pages to validate.
   * @todo return other pages.
   */
  public function findAllPages() {
    $all_site_pages = [];

    // Add frontpage to list.
    $site_frontpage = $this->configFactory
      ->get('system.site')
      ->get('page.front');
    $all_site_pages[$site_frontpage] = [
      'route' => '<front>',
      'url' => $site_frontpage,
      'title' => $this
        ->t('Frontpage'),
    ];

    // Add all nodes.
    $query = $this->connection
      ->select('node_field_data', 'n');
    $query
      ->fields('n', [
      'nid',
      'title',
    ]);
    $query
      ->addExpression("CONCAT('entity.node.canonical', '')", 'route');
    $query
      ->addExpression("CONCAT('node/', n.nid)", 'url');
    $nodes = $query
      ->execute()
      ->fetchAllAssoc('url', \PDO::FETCH_ASSOC);
    $all_site_pages = array_merge($all_site_pages, $nodes);

    // All route names.
    if ($this
      ->moduleSettings()
      ->get('admin_pages')) {
      $query = $this->connection
        ->select('router', 'r');
      $query
        ->addField('r', 'pattern_outline', 'url');
      $query
        ->addField('r', 'name', 'title');
      $query
        ->addField('r', 'name', 'route');
      $query
        ->condition('pattern_outline', '%\\%%', 'NOT LIKE');
      $query
        ->condition('pattern_outline', '%<%', 'NOT LIKE');
      $paths = $query
        ->execute()
        ->fetchAllAssoc('url', \PDO::FETCH_ASSOC);
      $all_site_pages = array_merge($all_site_pages, $paths);
    }
    return $all_site_pages;
  }

  /**
   * Find all already validated pages and their validation result.
   *
   * @return array
   *   The result of page validation.
   */
  public function findAllValidatedPages() {
    $db_result = $this->connection
      ->select('w3c_validator', 'w')
      ->fields('w')
      ->execute();
    return $db_result
      ->fetchAllAssoc('uri', \PDO::FETCH_BOTH);
  }

  /**
   * Validates all flagged pages in the limit of the number given.
   */
  public function validateAllPages(&$context) {
    $token = NULL;
    $user = NULL;
    $query_options = [];

    // Retrieve all pages to validate.
    $pages_to_validate = $this
      ->findAllPages();
    $context['message'] = $this
      ->t('Validating all pages ...');
    $context['sandbox']['max'] = count($pages_to_validate);
    $context['sandbox']['progress'] = 0;
    $context['results']['failures'] = 0;
    $context['results']['current_id'] = 0;
    $context['results']['processed'] = 0;

    // If we are using the "validate as user" option.
    if ($this
      ->moduleSettings()
      ->get('use_token')) {

      // Retrieve token.
      $token = $this->w3cTokenManager
        ->createAccessToken($this->currentUser);

      // Add it to query options.
      $query_options['query'] = [
        'HTTP_W3C_VALIDATOR_TOKEN' => $token,
      ];

      // Get current user.
      $user = $this->currentUser;
    }
    else {
      $user = new AnonymousUserSession();
    }

    // Validate each page one by one.
    foreach ($pages_to_validate as $page) {

      // Set validation message.
      $context['message'] = $this
        ->t('Validation for page %title...', [
        '%title' => $page['title'],
      ]);

      // Check if validation user will be able to validate the page.
      if (!$this->accessManager
        ->checkNamedRoute($page['route'], [
        'node' => isset($page['nid']) ? $page['nid'] : '',
      ], $user)) {
        $this->logger
          ->debug($page['title'] . ' at ' . $page['url'] . ' is not accessible for validation.');

        // Update operation data.
        $context['results']['failures']++;
      }
      else {

        // Valdiate the page using the specified $query_options.
        $this
          ->validatePage($page, $query_options);
      }

      // Update operation data.
      $context['sandbox']['progress']++;
      $context['results']['current_id']++;
      $context['results']['processed']++;
    }

    // Rewoke token.
    $this->w3cTokenManager
      ->rewokeAccessToken($token);
    $context['finished'] = 1;
  }

  /**
   * This method is responsible for the validation of a single page.
   *
   * @param array $page
   *   This represents a page to validate.
   * @param array $query_options
   *   This is a custom array of options for the query.
   */
  public function validatePage(array $page, array $query_options = []) {

    // Build page query options.
    $query_options['absolute'] = TRUE;

    // Retrieve absolute URL.
    $uri = Url::fromUri('base:' . $page['url'], $query_options)
      ->toString();

    // Validate.
    $validator = new Validator($this
      ->getValidatorUrl());
    $result = $validator
      ->validateUrl($uri);

    // Save result.
    $this
      ->saveResult($result, $page['url']);
  }

  /**
   * Save a validation result in the database.
   *
   * @param \HtmlValidator\Response $result
   *   The validation result to store in DB.
   * @param string $key
   *   The unique key used for storage in DB. This is basically the page
   *   relative URL. pages to validate.
   */
  public function saveResult(Response $result, $key) {

    // Only if result is defined.
    if (isset($result) && isset($key)) {

      // Merge the result with eventual previous result for the same URI.
      $this->connection
        ->merge("w3c_validator")
        ->key('uri', rtrim($key, "/"))
        ->fields([
        'uri' => rtrim($key, "/"),
        'error_count' => count($result
          ->getErrors()),
        'errors' => serialize($result
          ->getErrors()),
        'warning_count' => count($result
          ->getWarnings()),
        'warnings' => serialize($result
          ->getWarnings()),
        'info_count' => count($result
          ->getMessages()),
        'infos' => serialize($result
          ->getMessages()),
        'need_validation' => 0,
        // @todo make it better
        'doctype' => '',
        'validity' => $result
          ->hasErrors() ? 0 : 1,
        // @todo make it better
        'charset' => '',
      ])
        ->execute();
    }
    else {

      // Merge the result with eventual previous result for the same URI.
      $this->connection
        ->merge("w3c_validator")
        ->key('uri', rtrim($key, "/"))
        ->fields([
        'need_validation' => TRUE,
      ])
        ->execute();
    }
  }

  /**
   * {@inheritDoc}
   *
   * @return array
   *   Returns the module configuration settings.
   */
  protected function moduleSettings() {
    if (!isset($this->moduleSettings)) {
      $this->moduleSettings = $this->configFactory
        ->get('w3c_validator.settings');
    }
    return $this->moduleSettings;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
DependencySerializationTrait::$_entityStorages protected property An array of entity type IDs keyed by the property name of their storages.
DependencySerializationTrait::$_serviceIds protected property An array of service IDs keyed by property name used for serialization.
DependencySerializationTrait::__sleep public function 1
DependencySerializationTrait::__wakeup public function 2
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.
W3CProcessor::$accessManager protected property The access manager.
W3CProcessor::$configFactory protected property The configuration factory.
W3CProcessor::$connection protected property The database connection.
W3CProcessor::$currentUser protected property The current user.
W3CProcessor::$logger protected property A logger instance.
W3CProcessor::$moduleSettings protected property The module configurations.
W3CProcessor::$w3cTokenManager protected property A W3cTokenManager instance.
W3CProcessor::findAllPages public function Find all pages URL to validate in the site.
W3CProcessor::findAllValidatedPages public function Find all already validated pages and their validation result.
W3CProcessor::getValidatorUrl public function Get W3C configured validator URL.
W3CProcessor::moduleSettings protected function
W3CProcessor::saveResult public function Save a validation result in the database.
W3CProcessor::validateAllPages public function Validates all flagged pages in the limit of the number given.
W3CProcessor::validatePage public function This method is responsible for the validation of a single page.
W3CProcessor::__construct public function Constructs a W3CSubscriber object.