automatic_updates-8.x-2.x-dev/automatic_updates_extensions/src/BatchProcessor.php

automatic_updates_extensions/src/BatchProcessor.php
<?php

declare(strict_types=1);

namespace Drupal\automatic_updates_extensions;

use Drupal\Core\Url;
use Symfony\Component\HttpFoundation\RedirectResponse;

/**
 * A batch processor for updates.
 *
 * @internal
 *   This class is an internal part of the module's update handling and
 *   should not be used by external code.
 */
final class BatchProcessor {

  /**
   * The session key under which the stage ID is stored.
   *
   * @var string
   */
  public const STAGE_ID_SESSION_KEY = '_automatic_updates_extensions_stage_id';

  /**
   * Gets the update sandbox manager service.
   *
   * @return \Drupal\automatic_updates_extensions\ExtensionUpdateSandboxManager
   *   The update sandbox manager service.
   */
  private static function getSandboxManager(): ExtensionUpdateSandboxManager {
    return \Drupal::service(ExtensionUpdateSandboxManager::class);
  }

  /**
   * Records messages from a throwable, then re-throws it.
   *
   * @param \Throwable $error
   *   The caught exception.
   * @param array $context
   *   The current context of the batch job.
   *
   * @throws \Throwable
   *   The caught exception, which will always be re-thrown once its messages
   *   have been recorded.
   */
  private static function handleException(\Throwable $error, array &$context): void {
    $context['results']['errors'][] = $error->getMessage();
    throw $error;
  }

  /**
   * Calls the update stage's begin() method.
   *
   * @param string[] $project_versions
   *   The project versions to be staged in the update, keyed by package name.
   * @param array $context
   *   The current context of the batch job.
   *
   * @see \Drupal\automatic_updates_extensions\ExtensionUpdateSandboxManager::begin()
   */
  public static function begin(array $project_versions, array &$context): void {
    try {
      $stage_id = static::getSandboxManager()->begin($project_versions);
      \Drupal::service('session')->set(static::STAGE_ID_SESSION_KEY, $stage_id);
    }
    catch (\Throwable $e) {
      static::handleException($e, $context);
    }
  }

  /**
   * Calls the update stage's stage() method.
   *
   * @param array $context
   *   The current context of the batch job.
   *
   * @see \Drupal\automatic_updates\UpdateSandboxManager::stage()
   */
  public static function stage(array &$context): void {
    $stage_id = \Drupal::service('session')->get(static::STAGE_ID_SESSION_KEY);
    try {
      static::getSandboxManager()->claim($stage_id)->stage();
    }
    catch (\Throwable $e) {
      // If the stage was not already destroyed because of this exception
      // destroy it.
      if (!static::getSandboxManager()->isAvailable()) {
        static::clean($stage_id, $context);
      }
      static::handleException($e, $context);
    }
  }

  /**
   * Calls the update stage's apply() method.
   *
   * @param string $stage_id
   *   The stage ID.
   * @param array $context
   *   The current context of the batch job.
   *
   * @see \Drupal\automatic_updates_extensions\ExtensionUpdateSandboxManager::apply()
   */
  public static function commit(string $stage_id, array &$context): void {
    try {
      static::getSandboxManager()->claim($stage_id)->apply();
      // The batch system does not allow any single request to run for longer
      // than a second, so this will force the next operation to be done in a
      // new request. This helps keep the running code in as consistent a state
      // as possible.
      // @see \Drupal\package_manager\Stage::apply()
      // @see \Drupal\package_manager\Stage::postApply()
      // @todo See if there's a better way to ensure the post-apply tasks run
      //   in a new request in https://www.drupal.org/i/3293150.
      sleep(1);
    }
    catch (\Throwable $e) {
      static::handleException($e, $context);
    }
  }

  /**
   * Calls the update stage's postApply() method.
   *
   * @param string $stage_id
   *   The stage ID.
   * @param array $context
   *   The current context of the batch job.
   *
   * @see \Drupal\automatic_updates\UpdateSandboxManager::postApply()
   */
  public static function postApply(string $stage_id, array &$context): void {
    try {
      static::getSandboxManager()->claim($stage_id)->postApply();
    }
    catch (\Throwable $e) {
      static::handleException($e, $context);
    }
  }

  /**
   * Calls the update stage's destroy() method.
   *
   * @param string $stage_id
   *   The stage ID.
   * @param array $context
   *   The current context of the batch job.
   *
   * @see \Drupal\automatic_updates_extensions\ExtensionUpdateSandboxManager::destroy()
   */
  public static function clean(string $stage_id, array &$context): void {
    try {
      static::getSandboxManager()->claim($stage_id)->destroy();
    }
    catch (\Throwable $e) {
      static::handleException($e, $context);
    }
  }

  /**
   * Finishes the stage batch job.
   *
   * @param bool $success
   *   Indicate that the batch API tasks were all completed successfully.
   * @param array $results
   *   An array of all the results.
   * @param array $operations
   *   A list of the operations that had not been completed by the batch API.
   */
  public static function finishStage(bool $success, array $results, array $operations): ?RedirectResponse {
    if ($success) {
      $stage_id = \Drupal::service('session')->get(static::STAGE_ID_SESSION_KEY);
      $url = Url::fromRoute('automatic_updates_extension.confirmation_page', [
        'stage_id' => $stage_id,
      ]);
      return new RedirectResponse($url->setAbsolute()->toString());
    }
    static::handleBatchError($results);
    return NULL;
  }

  /**
   * Finishes the commit batch job.
   *
   * @param bool $success
   *   Indicate that the batch API tasks were all completed successfully.
   * @param array $results
   *   An array of all the results.
   * @param array $operations
   *   A list of the operations that had not been completed by the batch API.
   */
  public static function finishCommit(bool $success, array $results, array $operations): ?RedirectResponse {
    \Drupal::service('session')->remove(static::STAGE_ID_SESSION_KEY);

    if ($success) {
      $url = Url::fromRoute('automatic_updates.finish')
        ->setAbsolute()
        ->toString();
      return new RedirectResponse($url);
    }
    static::handleBatchError($results);
    return NULL;
  }

  /**
   * Handles a batch job that finished with errors.
   *
   * @param array $results
   *   The batch results.
   */
  private static function handleBatchError(array $results): void {
    if (isset($results['errors'])) {
      foreach ($results['errors'] as $error) {
        \Drupal::messenger()->addError($error);
      }
    }
    else {
      \Drupal::messenger()->addError("Update error");
    }
  }

}

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

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