You are here

class ReadinessValidationManager in Automatic Updates 8.2

Defines a manager to run readiness validation.

Hierarchy

Expanded class hierarchy of ReadinessValidationManager

1 file declares its use of ReadinessValidationManager
UpdaterForm.php in src/Form/UpdaterForm.php
1 string reference to 'ReadinessValidationManager'
automatic_updates.services.yml in ./automatic_updates.services.yml
automatic_updates.services.yml
1 service uses ReadinessValidationManager
automatic_updates.readiness_validation_manager in ./automatic_updates.services.yml
Drupal\automatic_updates\Validation\ReadinessValidationManager

File

src/Validation/ReadinessValidationManager.php, line 17

Namespace

Drupal\automatic_updates\Validation
View source
class ReadinessValidationManager {

  /**
   * The key/value expirable storage.
   *
   * @var \Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface
   */
  protected $keyValueExpirable;

  /**
   * The time service.
   *
   * @var \Drupal\Component\Datetime\TimeInterface
   */
  protected $time;

  /**
   * The event dispatcher service.
   *
   * @var \Symfony\Component\EventDispatcher\EventDispatcherInterface
   */
  protected $eventDispatcher;

  /**
   * The number of hours to store results.
   *
   * @var int
   */
  protected $resultsTimeToLive;

  /**
   * The path locator service.
   *
   * @var \Drupal\automatic_updates\PathLocator
   */
  protected $pathLocator;

  /**
   * Constructs a ReadinessValidationManager.
   *
   * @param \Drupal\Core\KeyValueStore\KeyValueExpirableFactoryInterface $key_value_expirable_factory
   *   The key/value expirable factory.
   * @param \Drupal\Component\Datetime\TimeInterface $time
   *   The time service.
   * @param \Drupal\automatic_updates\PathLocator $path_locator
   *   The path locator service.
   * @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $dispatcher
   *   The event dispatcher service.
   * @param int $results_time_to_live
   *   The number of hours to store results.
   */
  public function __construct(KeyValueExpirableFactoryInterface $key_value_expirable_factory, TimeInterface $time, PathLocator $path_locator, EventDispatcherInterface $dispatcher, int $results_time_to_live) {
    $this->keyValueExpirable = $key_value_expirable_factory
      ->get('automatic_updates');
    $this->time = $time;
    $this->pathLocator = $path_locator;
    $this->eventDispatcher = $dispatcher;
    $this->resultsTimeToLive = $results_time_to_live;
  }

  /**
   * Dispatches the readiness check event and stores the results.
   *
   * @return $this
   */
  public function run() : self {
    $composer = ComposerUtility::createForDirectory($this->pathLocator
      ->getActiveDirectory());
    $recommender = new UpdateRecommender();
    $release = $recommender
      ->getRecommendedRelease(TRUE);
    if ($release) {
      $core_packages = $composer
        ->getCorePackageNames();

      // Update all core packages to the same version.
      $package_versions = array_fill(0, count($core_packages), $release
        ->getVersion());
      $package_versions = array_combine($core_packages, $package_versions);
    }
    else {
      $package_versions = [];
    }
    $event = new ReadinessCheckEvent($composer, $package_versions);
    $this->eventDispatcher
      ->dispatch($event, AutomaticUpdatesEvents::READINESS_CHECK);
    $results = $event
      ->getResults();
    $this->keyValueExpirable
      ->setWithExpire('readiness_validation_last_run', [
      'results' => $results,
      'listeners' => $this
        ->getListenersAsString(AutomaticUpdatesEvents::READINESS_CHECK),
    ], $this->resultsTimeToLive * 60 * 60);
    $this->keyValueExpirable
      ->set('readiness_check_timestamp', $this->time
      ->getRequestTime());
    return $this;
  }

  /**
   * Gets all the listeners for a specific event as single string.
   *
   * @return string
   *   The listeners as a string.
   */
  protected function getListenersAsString(string $event_name) : string {
    $listeners = $this->eventDispatcher
      ->getListeners($event_name);
    $string = '';
    foreach ($listeners as $listener) {

      /** @var object $object */
      $object = $listener[0];
      $method = $listener[1];
      $string .= '-' . get_class($object) . '::' . $method;
    }
    return $string;
  }

  /**
   * Dispatches the readiness check event if there no stored valid results.
   *
   * @return $this
   *
   * @see self::getResults()
   * @see self::getStoredValidResults()
   */
  public function runIfNoStoredResults() : self {
    if ($this
      ->getResults() === NULL) {
      $this
        ->run();
    }
    return $this;
  }

  /**
   * Gets the validation results from the last run.
   *
   * @param int|null $severity
   *   (optional) The severity for the results to return. Should be one of the
   *   SystemManager::REQUIREMENT_* constants.
   *
   * @return \Drupal\automatic_updates\Validation\ValidationResult[]|
   *   The validation result objects or NULL if no results are
   *   available or if the stored results are no longer valid.
   *
   * @see self::getStoredValidResults()
   */
  public function getResults(?int $severity = NULL) : ?array {
    $results = $this
      ->getStoredValidResults();
    if ($results !== NULL) {
      if ($severity !== NULL) {
        $results = array_filter($results, function ($result) use ($severity) {
          return $result
            ->getSeverity() === $severity;
        });
      }
      return $results;
    }
    return NULL;
  }

  /**
   * Gets stored valid results, if any.
   *
   * The stored results are considered valid if the current listeners for the
   * readiness check event are the same as the last time the event was
   * dispatched.
   *
   * @return \Drupal\automatic_updates\Validation\ValidationResult[]|null
   *   The stored results if available and still valid, otherwise null.
   */
  protected function getStoredValidResults() : ?array {
    $last_run = $this->keyValueExpirable
      ->get('readiness_validation_last_run');

    // If the listeners have not changed return the results.
    if ($last_run && $last_run['listeners'] === $this
      ->getListenersAsString(AutomaticUpdatesEvents::READINESS_CHECK)) {
      return $last_run['results'];
    }
    return NULL;
  }

  /**
   * Gets the timestamp of the last run.
   *
   * @return int|null
   *   The timestamp of the last completed run, or NULL if no run has
   *   been completed.
   */
  public function getLastRunTime() : ?int {
    return $this->keyValueExpirable
      ->get('readiness_check_timestamp');
  }

}

Members

Namesort descending Modifiers Type Description Overrides
ReadinessValidationManager::$eventDispatcher protected property The event dispatcher service.
ReadinessValidationManager::$keyValueExpirable protected property The key/value expirable storage.
ReadinessValidationManager::$pathLocator protected property The path locator service.
ReadinessValidationManager::$resultsTimeToLive protected property The number of hours to store results.
ReadinessValidationManager::$time protected property The time service.
ReadinessValidationManager::getLastRunTime public function Gets the timestamp of the last run.
ReadinessValidationManager::getListenersAsString protected function Gets all the listeners for a specific event as single string.
ReadinessValidationManager::getResults public function Gets the validation results from the last run.
ReadinessValidationManager::getStoredValidResults protected function Gets stored valid results, if any.
ReadinessValidationManager::run public function Dispatches the readiness check event and stores the results.
ReadinessValidationManager::runIfNoStoredResults public function Dispatches the readiness check event if there no stored valid results.
ReadinessValidationManager::__construct public function Constructs a ReadinessValidationManager.