pdf_to_imagefield-1.0.x-dev/src/PDFToImageBatchHelper.php

src/PDFToImageBatchHelper.php
<?php

namespace Drupal\pdf_to_imagefield;

use Drupal\Component\Render\PlainTextOutput;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\File\Exception\FileException;
use Drupal\Core\File\FileSystemInterface;
use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\Render\BubbleableMetadata;
use Drupal\Core\Utility\Token;
use Drupal\file\Entity\File;
use Drupal\file\FileInterface;
use Spatie\PdfToImage\Pdf;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\Mime\MimeTypeGuesserInterface;

/**
 * Provides helper class for batch.
 */
class PDFToImageBatchHelper {

  /**
   * The entity type manager.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface|null
   */
  protected static $entityTypeManager = NULL;

  /**
   * The file system service.
   *
   * @var \Drupal\Core\File\FileSystemInterface|null
   */
  protected static $fileSystem = NULL;

  /**
   * The token replacement instance.
   *
   * @var \Drupal\Core\Utility\Token|null
   */
  protected static $token = NULL;

  /**
   * The Drupal messenger service.
   *
   * @var \Drupal\Core\Messenger\MessengerInterface|null
   */
  protected static $messenger = NULL;

  /**
   * Retrieve entity type manager.
   *
   * @return \Drupal\Core\Entity\EntityTypeManagerInterface
   *   Entity manager interface.
   */
  protected static function getEntityTypeManager():EntityTypeManagerInterface {
    if (!self::$entityTypeManager) {
      self::$entityTypeManager = \Drupal::entityTypeManager();
    }
    return self::$entityTypeManager;
  }

  /**
   * Retrieve file system service.
   *
   * @return \Drupal\Core\File\FileSystemInterface
   *   File system.
   */
  protected static function getFileSystem():FileSystemInterface {
    if (!self::$fileSystem) {
      self::$fileSystem = \Drupal::service('file_system');
    }
    return self::$fileSystem;
  }

  /**
   * Retrieve token.
   *
   * @return \Drupal\Core\Utility\Token
   *   Token
   */
  protected static function getToken():Token {
    if (!self::$token) {
      self::$token = \Drupal::service('token');
    }
    return self::$token;
  }

  /**
   * Retrieve messenger.
   *
   * @return \Drupal\Core\Messenger\MessengerInterface
   *   Message interface
   */
  protected static function getMessenger():MessengerInterface {
    if (!self::$messenger) {
      self::$messenger = \Drupal::messenger();
    }
    return self::$messenger;
  }

  /**
   * Move non PDF files.
   */
  public static function moveNonPdfFiles(array $base_batch_data, array $files, &$context) {
    if (!isset($context['results']['files'])) {
      $context['results']['files'] = [];
    }
    $context['results']['params'] = $base_batch_data;
    $context['results']['files'] = array_merge($context['results']['files'], $files);
  }

  /**
   * Generate single page of PDF file.
   */
  public static function generateProcessPage(array $base_batch_data, FileInterface $pdf_file, Pdf $pdf, int $start, int $end, &$context) {
    if (!isset($context['results']['files'])) {
      $context['results']['files'] = [];
    }
    $context['results']['params'] = $base_batch_data;
    for ($page_number = $start; $page_number <= $end; $page_number++) {
      $file = self::generatePage($base_batch_data, $pdf_file, $pdf, $page_number);
      if ($file instanceof FileInterface) {
        $context['results']['files'][] = $file;
      }
    }
  }

  /**
   * Provides conversion logic from PDF page to the image.
   */
  protected static function generatePage(array $params, FileInterface $pdf_file, Pdf $pdf, int $page_number = 1) {
    /** @var \Drupal\field\FieldConfigInterface $field_definition */
    $field_definition = reset($params['image']['instance']);
    $settings = $field_definition->getSettings();

    $destination = self::getUploadLocation($settings);
    $prepared_filename = $pdf_file->id() . '-' . $page_number . '.' . $pdf->getOutputFormat();
    // Create the file.
    $file_uri = "{$destination}/{$prepared_filename}";
    if ($destination === $settings['uri_scheme'] . '://') {
      $file_uri = "{$destination}{$prepared_filename}";
    }

    $file_uri = self::getFileSystem()->getDestinationFilename($file_uri, FileSystemInterface::EXISTS_RENAME);

    $image_temp_path = self::getFileSystem()->getTempDirectory() . '/' . $prepared_filename;

    $pdf->setPage($page_number)
      ->saveImage($image_temp_path);

    if (file_exists($image_temp_path)) {
      // @todo logger about successful creation.
    }

    $guesser = \Drupal::service('file.mime_type.guesser');
    $prepared_filename = self::getFileSystem()->basename($image_temp_path);
    $current_user = \Drupal::currentUser();
    $file = File::create();
    $file->setOwnerId($current_user->id());
    $file->setFilename($prepared_filename);
    if ($guesser instanceof MimeTypeGuesserInterface) {
      $file->setMimeType($guesser->guessMimeType($prepared_filename));
      @trigger_error('\Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface is deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Implement \Symfony\Component\Mime\MimeTypeGuesserInterface instead. See https://www.drupal.org/node/3133341', E_USER_DEPRECATED);
    }
    $file->setFileUri($image_temp_path);
    $file->setSize(@filesize($image_temp_path));

    $file->setFileUri($file_uri);
    // Move the file to the correct location after validation. Use
    // FileSystemInterface::EXISTS_ERROR as the file location has already been
    // determined above in FileSystem::getDestinationFilename().
    try {
      self::$fileSystem->move($image_temp_path, $file_uri, FileSystemInterface::EXISTS_ERROR);
    }
    catch (FileException $e) {
      throw new HttpException(500, 'Temporary file could not be moved to file location');
    }
    $file->save();

    return $file;
  }

  /**
   * 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 static function generateProcessAttach(bool $success, array $results, array $operations) {
    $messenger = self::getMessenger();
    if ($success) {
      if (empty($results)) {
        $messenger->addMessage(t('No files produced from processing document'));
      }
      else {
        $messenger->addMessage(t('@count files processed.', ['@count' => count($results['files'])]));
        /** @var \Drupal\Core\Entity\EntityInterface $entity */
        $entity = $results['params']['entity'];
        /** @var \Drupal\field\FieldStorageConfigInterface $image_field */
        $image_field = reset($results['params']['image']['field']);
        $field_name = $image_field->getName();
        $entity_type_manager = self::getEntityTypeManager();
        if ($entity->id()) {
          // Don't use the entity as given,
          // load it again as things may have happened
          // to it since the batch job began.
          /** @var \Drupal\Core\Entity\ContentEntityInterface|null $entity */
          $entity = $entity_type_manager->getStorage($entity->getEntityTypeId())->load($entity->id());
          if ($entity) {
            $entity->set($field_name, []);
            ksort($results['files'], SORT_NUMERIC);
            $file_ids = [];
            /** @var \Drupal\file\FileInterface $file */
            foreach ($results['files'] as $file) {
              $file_ids[] = $file->id();
            }
            $entity->set($field_name, $file_ids);
            $entity->save();
          }
        }
      }
    }
    else {
      // An error occurred.
      // $operations contains the operations that remained unprocessed.
      $error_operation = reset($operations);
      $messenger->addMessage(
        t('An error occurred while processing @operation with arguments : @args',
          [
            '@operation' => $error_operation[0],
            '@args' => print_r($error_operation[0], TRUE),
          ]
        )
      );
    }
  }

  /**
   * Determines the URI for a file field.
   *
   * @param array $settings
   *   The array of field settings.
   *
   * @return string
   *   An un-sanitized file directory URI with tokens replaced. The result of
   *   the token replacement is then converted to plain text and returned.
   */
  protected static function getUploadLocation(array $settings) {
    $destination = trim($settings['file_directory'], '/');

    // Replace tokens. As the tokens might contain HTML we convert it to plain
    // text.
    $destination = PlainTextOutput::renderFromHtml(self::getToken()->replace($destination, [], [], new BubbleableMetadata()));
    return $settings['uri_scheme'] . '://' . $destination;
  }

}

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

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