archivesspace-8.x-1.x-dev/src/Plugin/Action/UpdateResourceDescriptionFile.php

src/Plugin/Action/UpdateResourceDescriptionFile.php
<?php

namespace Drupal\archivesspace\Plugin\Action;

use Drupal\archivesspace\ArchivesSpaceUtils;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Action\ConfigurableActionBase;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\File\FileSystemInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Utility\Token;
use Drupal\media\Entity\Media;
use Drupal\media\MediaInterface;
use Drupal\node\NodeInterface;
use GuzzleHttp\Exception\ServerException;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Updates a Resource Description media & file.
 *
 * @Action(
 *   id = "update_as_resource_description_file",
 *   label = @Translation("Update ArchivesSpace Resource Description File"),
 *   type = "node",
 * )
 */
class UpdateResourceDescriptionFile extends ConfigurableActionBase implements ContainerFactoryPluginInterface {

  /**
   * ArchivesSpace Utils.
   *
   * @var \Drupal\archivesspace\ArchivesSpaceUtils
   */
  protected $utils;

  /**
   * The entity type manager.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * The token service.
   *
   * @var \Drupal\Core\Utility\Token
   */
  protected $token;

  /**
   * Constructs a UpdateResourceDescriptionFile object.
   *
   * @param array $configuration
   *   A configuration array containing information about the plugin instance.
   * @param string $plugin_id
   *   The plugin ID for the plugin instance.
   * @param mixed $plugin_definition
   *   The plugin implementation definition.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager.
   * @param \Drupal\Core\Utility\Token $token
   *   The token service.
   * @param \Drupal\archivesspace\ArchivesSpaceUtils $utils
   *   ArchivesSpace utilities for requesting resource description files.
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager, Token $token, ArchivesSpaceUtils $utils) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
    $this->entityTypeManager = $entity_type_manager;
    $this->utils = $utils;
    $this->token = $token;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static($configuration, $plugin_id, $plugin_definition, $container->get('entity_type.manager'), $container->get('token'), $container->get('archivesspace.utils'));
  }

  /**
   * {@inheritdoc}
   */
  public function execute($node = NULL) {
    if ($node instanceof NodeInterface) {

      // Get the configured description media reference field.
      $field_id = $this->configuration['resource_description_field'];

      /** @var \Drupal\node\NodeInterface $node */
      if (!$node->hasField($field_id)) {
        throw new \RuntimeException("Resource description field $field_id not found on node {$node->id()}.");
      }

      // Build the intended file path, from config.
      $directory = $this->configuration['filesystem'] . $this->configuration['path'] . '/';
      \Drupal::service('file_system')->prepareDirectory($directory, FileSystemInterface::CREATE_DIRECTORY | FileSystemInterface::MODIFY_PERMISSIONS);
      // Sanitize the name based on the configured token value because who knows
      // *what* we will be handed, especially if they have HTML titles.
      $new_name = preg_replace(
        '/\-+/', '-',
        preg_replace(
          '/[^a-zA-Z0-9_-]+/', '',
          str_replace(
            [' ', '/'], '-',
             $this->token->replace(
               $this->configuration['filename_pattern'],
               ['node' => $node]
             )
           )
         )
       );
      $path = $directory . $new_name . '.' . $this->configuration['file_type'];
      try {
        // Call for the new file and save it.
        $stream = $this->utils->getResourceDescription($node->id(), $this->configuration['file_type']);
        $file = \Drupal::service('file.repository')->writeData($stream->getContents(), $path, FileSystemInterface::EXISTS_REPLACE);
      }
      catch (ServerException $se) {
        throw new \Exception("Failed to retrieve resource description from ArchivesSpace: " . $se->getMessage());
      }
      if (!$file) {
        throw new \Exception("Aborting Resource Description; failed to create or update '$path'.");
      }
      // Create or Update the media with the file.
      // Yes, we still need to update the media because the file path may
      // have changed.
      $media_file_field = 'field_media_' . $this->configuration['media_document_type'];
      $resource_description_media = $node->get($field_id)->entity;
      if (!$resource_description_media instanceof MediaInterface) {
        $resource_description_media = Media::create([
          'bundle' => $this->configuration['media_document_type'],
          'uid' => \Drupal::currentUser()->id(),
          $media_file_field => [
            'target_id' => $file->id(),
          ],
        ]);
        $node->set($field_id, $resource_description_media);
        $node->save();
      }
      else {
        $resource_description_media->set($media_file_field, $file);
        // Drupal doesn't see the media field set to the file as a change,
        // so we force the changed time update.
        $resource_description_media->setChangedTime(time());
        $resource_description_media->save();
      }
      \Drupal::entityTypeManager()->getStorage('node')->resetCache([$node->id()]);
    }
  }

  /**
   * {@inheritdoc}
   */
  public function defaultConfiguration() {
    return [
      'filesystem' => 'public://',
      'path' => 'finding-aids',
      'filename_pattern' => '[node:title]',
      'file_type' => 'pdf',
      'resource_description_field' => 'field_printable_pdf',
      'media_document_type' => 'document',
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {

    $form['filesystem'] = [
      '#type' => 'textfield',
      '#title' => $this->t('File System'),
      '#default_value' => $this->configuration['filesystem'],
      '#required' => TRUE,
      '#description' => $this->t('The filesystem used to store the resource description files. Usually set to "public://" unless you need to restrict access to them, in which case you would use "private://".'),
    ];
    $form['path'] = [
      '#type' => 'textfield',
      '#title' => $this->t('File Path'),
      '#default_value' => $this->configuration['path'],
      '#required' => TRUE,
      '#description' => $this->t('Which directory the files should be stored (if any).'),
    ];
    $form['filename_pattern'] = [
      '#type' => 'textfield',
      '#title' => $this->t('File System'),
      '#default_value' => $this->configuration['filename_pattern'],
      '#required' => TRUE,
      '#description' => $this->t('The filename the system should use. Please include a token, such as "[node:id]" to ensure the filename is unique to avoid overwritting other resource description files.'),
    ];
    $form['file_type'] = [
      '#type' => 'textfield',
      '#title' => $this->t('File System'),
      '#default_value' => $this->configuration['file_type'],
      '#required' => TRUE,
      '#description' => $this->t('The type of resource description to create/update. "pdf" for PDFs and "xml" for EAD.'),
    ];
    $form['resource_description_field'] = [
      '#type' => 'textfield',
      '#title' => $this->t('File System'),
      '#default_value' => $this->configuration['resource_description_field'],
      '#required' => TRUE,
      '#description' => $this->t('Which field on the Archival Resource content type stores resource description media.'),
    ];
    $form['media_document_type'] = [
      '#type' => 'textfield',
      '#title' => $this->t('File System'),
      '#default_value' => $this->configuration['media_document_type'],
      '#required' => TRUE,
      '#description' => $this->t('The type of Media used to store the resource description file. "document" should be used for PDFs and "file" should be used for xml (EAD).'),
    ];

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
    $this->configuration['filesystem'] = $form_state->getValue('filesystem');
    $this->configuration['path'] = $form_state->getValue('path');
    $this->configuration['filename_pattern'] = $form_state->getValue('filename_pattern');
    $this->configuration['file_type'] = $form_state->getValue('file_type');
    $this->configuration['resource_description_field'] = $form_state->getValue('resource_description_field');
    $this->configuration['media_document_type'] = $form_state->getValue('media_document_type');
  }

  /**
   * {@inheritdoc}
   */
  public function access($object, ?AccountInterface $account = NULL, $return_as_object = FALSE) {
    $result = AccessResult::allowed();
    return $return_as_object ? $result : $result->isAllowed();
  }

}

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

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