archivesspace-8.x-1.x-dev/src/Plugin/rest/resource/UpdateASResource.php

src/Plugin/rest/resource/UpdateASResource.php
<?php

namespace Drupal\archivesspace\Plugin\rest\resource;

use Drupal\archivesspace\ArchivesSpaceSession;
use Drupal\migrate\MigrateExecutable;
use Drupal\migrate\MigrateMessage;
use Drupal\migrate\Plugin\Migration;
use Drupal\migrate\Plugin\MigrationInterface;
use Drupal\rest\Plugin\ResourceBase;
use Drupal\rest\ResourceResponse;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;

/**
 * Provides an update endpoint for ArchivesSpace.
 *
 * @RestResource(
 *   id = "update_archivesspace_resource",
 *   label = @Translation("Update ArchivesSpace resource"),
 *   uri_paths = {
 *     "canonical" = "/archivesspace/update/{id}"
 *   }
 * )
 */
class UpdateASResource extends ResourceBase {

  /**
   * Responds to entity GET requests.
   *
   * @param string $id
   *   The resource id to update.
   *
   * @return \Drupal\rest\ResourceResponse
   *   HTTP Response.
   *
   * @throws \Symfony\Component\HttpKernel\Exception\BadRequestHttpException
   *   Thrown when no log entry was provided.
   */
  public function get($id) {
    $archives = new ArchivesSpaceSession();

    $response = $archives->request('GET', '/search', [
      'q' => $id,
      'fields[]' => 'identifier,uri',
      'type[]' => 'resource',
      'page' => '1',
      'page_size' => '1',
    ]);

    $result = $response['results'][0];

    if ($result['identifier'] !== $id) {
      throw new BadRequestHttpException('No ArchivesSpace resource was found for ' . $id);
    }

    $result2 = $archives->request('GET', $result["uri"] . "/tree");
    $uris = $this->getChildrenUris($result2);

    $this->utils = \Drupal::service('archivesspace.utils');

    $context = ['results' => []];
    $this->updateResource(1, $archives, $uris, $context);
    $this->updateResourceFinished(TRUE, $context['results'], []);

    $response = "success";
    return (new ResourceResponse($response))->addCacheableDependency([
      '#cache' => [
        'max-age' => 0,
      ],
    ]);
  }

  /**
   * Helper function to build a list of object uris from a tree.
   *
   * @param array $node
   *   Batch ID.
   *
   * @return array
   *   list of object URIs.
   */
  private function getChildrenUris(array $node) {
    $ans = [$node['record_uri']];

    foreach ($node['children'] as $child) {
      $ans = array_merge($ans, $this->getChildrenUris($child));
    }

    return $ans;
  }

  /**
   * Batch process callback.
   *
   * @param int $id
   *   Batch ID.
   * @param \Drupal\archivesspace\ArchivesSpaceSession $session
   *   Details of the operation.
   * @param array $parameters
   *   The operations' parameters.
   * @param object $context
   *   Context for operations.
   */
  public function updateResource($id, ArchivesSpaceSession $session, array $parameters, &$context) {
    // Get page number and query from operation details.
    // Issue query.
    // Group embedded data rows into migrations based on each's json_model.
    $migrations = [];

    foreach ($parameters as $uri) {
      $result = $session->request('GET', $uri);
      $context['message'] = "Processing resource.";

      if ($migration_id = $this->utils->getUriMigration($result['uri'])) {
        $migrations[$migration_id][] = $result;
      }
    }

    foreach ($migrations as $migration_id => $data) {
      $context['message'] = $this->t("Running migration '@migration' with @rows items.", [
        '@migration' => $migration_id,
        '@rows' => count($data),
      ]);
      // Load the relevant migration with the embedded data source.
      $migration = \Drupal::service('plugin.manager.migration')->createInstance($migration_id, [
        'source' => [
          'plugin' => 'embedded_data',
          'data_rows' => $data,
          'ids' => ['uri' => ['type' => 'string']],
        ],
      ]);
      if (!$migration) {
        $context['message'] = $this->t("Could not find a migration with the ID '@id'!", ['@id' => $migration_id]);
        return;
      }

      if ($migration->getStatus() != Migration::STATUS_IDLE) {
        $migration->setStatus(Migration::STATUS_IDLE);
      }

      // Force the migration for batches rather than fail
      // due to missed requirements.
      $migration->set('requirements', []);
      $migration->getIdMap()->prepareUpdate();
      $executable = new MigrateExecutable($migration, new MigrateMessage());

      $migration_result = $executable->import();

      if ($migration_result == MigrationInterface::RESULT_COMPLETED) {
        if (!array_key_exists('migration_counts', $context['results'])) {
          $context['results']['migration_counts'] = [];
        }
        if (!array_key_exists($migration_id, $context['results']['migration_counts'])) {
          $context['results']['migration_counts'][$migration_id] = 0;
        }
        $context['results']['migration_counts'][$migration_id] += count($data);
      }
      else {
        $result_msg = '';
        switch ($migration_result) {
          // Error messages pulled from the MigrationInterface API docs.
          case MigrationInterface::RESULT_DISABLED:
            $result_msg = "This migration is disabled, skipping.";
            break;

          case MigrationInterface::RESULT_FAILED:
            $result_msg = "The process had a fatal error.";
            break;

          case MigrationInterface::RESULT_INCOMPLETE:
            $result_msg = "The process has stopped itself (e.g., the memory limit is approaching).";
            break;

          case MigrationInterface::RESULT_SKIPPED:
            $result_msg = "Dependencies are unfulfilled - skip the process.";
            break;

          case MigrationInterface::RESULT_STOPPED:
            $result_msg = "The process was stopped externally (e.g., via drush migrate-stop).";
            break;
        }
        // Kill further processing.
        throw new \Exception("Migration $migration_id from page {$results['this_page']} failed to complete with the message: $result_msg");
      }
    }
  }

  /**
   * Batch finished callback.
   *
   * @param bool $success
   *   Success of the operation.
   * @param array $results
   *   Array of results for post processing.
   * @param array $operations
   *   Array of operations.
   */
  public function updateResourceFinished($success, array $results, array $operations) {
    if ($success) {
      // Report out migrations.
      if (!empty($results['migration_counts'])) {
        foreach ($results['migration_counts'] as $mid => $count) {
          \Drupal::messenger()->addMessage($this->t("Migration @mid processed @count items.", [
            '@mid' => $mid,
            '@count' => $count,
          ]));
        }
      }
      else {
        \Drupal::messenger()->addMessage($this->t("Warning: no migrations appear to have been run."));
      }

    }
    else {
      // An error occurred.
      // $operations contains the operations that remained unprocessed.
      $error_operation = reset($operations);
      \Drupal::messenger()->addMessage(
        $this->t('An error occurred while processing @operation with arguments : @args',
          [
            '@operation' => 'Update Page',
            '@args' => print_r($error_operation[1][2], TRUE),
          ]
        )
      );
    }
  }

}

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

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