path_redirect_import-8.x-1.0-beta4/src/RedirectExport.php

src/RedirectExport.php
<?php

namespace Drupal\path_redirect_import;

use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\File\FileSystemInterface;
use Drupal\Core\Link;
use Drupal\Core\Url;
use Drupal\file\Entity\File;
use Drupal\file\FileRepositoryInterface;
use Drupal\migrate\Plugin\MigrationPluginManagerInterface;
use League\Csv\Writer;

/**
 * Service that manages the redirect export batch operations.
 */
class RedirectExport {
  use MigratePluginTrait;

  const MIGRATE_FOLDER = 'public://path_redirect_import/';
  const BATCH_SIZE = 50;
  const HEADERS = ['source', 'destination', 'language', 'status_code'];

  /**
   * The file system service.
   *
   * @var \Drupal\Core\File\FileSystemInterface
   */
  protected $fileSystem;

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

  /**
   * The file repository.
   *
   * @var \Drupal\file\FileRepositoryInterface
   */
  protected $fileRepository;

  /**
   * Constructs a RedirectExport object.
   *
   * @param \Drupal\Core\File\FileSystemInterface $file_system
   *   The file system service.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager.
   * @param \Drupal\migrate\Plugin\MigrationPluginManagerInterface $migration_plugin_manager
   *   The plugin manager for config entity-based migrations.
   * @param \Drupal\file\FileRepositoryInterface $file_repository
   *   The file repository.
   */
  public function __construct(
    FileSystemInterface $file_system,
    EntityTypeManagerInterface $entity_type_manager,
    MigrationPluginManagerInterface $migration_plugin_manager,
    FileRepositoryInterface $file_repository
  ) {
    $this->fileSystem = $file_system;
    $this->entityTypeManager = $entity_type_manager;
    $this->migrationPluginManager = $migration_plugin_manager;
    $this->fileRepository = $file_repository;
  }

  /**
   * Method description.
   */
  public function doSomething() {
    // @DCG place your code here.
  }

  /**
   * Creates the spreadsheet file to export entries to.
   *
   * @return \Drupal\file\FileInterface
   *   File.
   *
   * @throws \Drupal\Core\Entity\EntityStorageException
   */
  protected function getFile() {
    $filename = 'export_' . time() . '.csv';
    $uri = self::MIGRATE_FOLDER . $filename;
    $directory = self::MIGRATE_FOLDER;
    $this->fileSystem->prepareDirectory($directory, FileSystemInterface::CREATE_DIRECTORY | FileSystemInterface::MODIFY_PERMISSIONS);
    return $this->fileRepository->writeData('', $uri, FileSystemInterface::EXISTS_REPLACE);
  }

  /**
   * Get the CSV writer.
   *
   * @param string $file_path
   *   Path of the file.
   * @param string $mode
   *   Mode to open the file.
   * @param array $configuration
   *   Array with CSV configuration.
   *
   * @return \League\Csv\Writer
   *   The writer.
   *
   * @throws \Drupal\migrate\MigrateException
   * @throws \League\Csv\Exception
   */
  protected static function createWriter($file_path, $mode, array $configuration) {
    $writer = Writer::createFromPath($file_path, $mode);

    $writer->setDelimiter($configuration['delimiter']);
    $writer->setEnclosure($configuration['enclosure']);
    $writer->setEscape($configuration['escape']);

    return $writer;
  }

  /**
   * Load the same configuration of migrate for CSV=>Table import path.
   *
   * @return array
   *   Configuration for csv info, separators, etc.
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   */
  protected function getConfigurationFromPlugin() {
    $migration_plugin = $this->migrationPlugin();

    return $migration_plugin->getSourcePlugin()->getConfiguration();
  }

  /**
   * Returns the Export redirect batch operations.
   *
   * @return array
   *   The batch operations.
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   * @throws \Drupal\Core\Entity\EntityStorageException
   */
  public function getBatchOperations() {
    // Create file, folder and prepare variables.
    $file = $this->getFile();
    $configuration = $this->getConfigurationFromPlugin();

    // Load a list of all ids to process.
    $ids = $this->entityTypeManager
      ->getStorage('redirect')
      ->getQuery()
      ->accessCheck(TRUE)
      ->execute();

    // Breakdown process into small batches.
    $operations = [];
    $item_start = 0;
    foreach (array_chunk($ids, self::BATCH_SIZE) as $batch_data) {
      $operations[] = [
        get_class($this) . '::batchProcessExport',
        [$file, $configuration, $batch_data, $item_start, count($ids)],
      ];
      $item_start += self::BATCH_SIZE;
    }

    return $operations;
  }

  /**
   * Export into the CSV per batches.
   *
   * @param \Drupal\file\entity\File $file
   *   File where information will be stored to.
   * @param array $configuration
   *   Configuration for CSV structure.
   * @param array $batch_data
   *   Ids of redirect entities to process.
   * @param int $start
   *   Next item to process.
   * @param int $total
   *   Total of items to process.
   * @param mixed $context
   *   Context array/iterable.
   */
  public static function batchProcessExport(File $file, array $configuration, array $batch_data, int $start, int $total, &$context) {
    $file_path = \Drupal::service('file_system')->realpath($file->getFileUri());

    $context['results']['failures'] = isset($context['results']['failures']) ?? 0;
    $context['results']['file'] = $file;
    // Write header in first iteration of first batch.
    if (empty($start)) {
      // Write header.
      $writer = self::createWriter($file_path, 'w', $configuration);
      $writer->insertOne(self::HEADERS);
    }

    $storage_handler = \Drupal::entityTypeManager()->getStorage('redirect');
    $entities = $storage_handler->loadMultiple($batch_data);

    if (empty($writer)) {
      $writer = self::createWriter($file_path, 'a', $configuration);
    }

    // Now export entities one by one, only with the fields we need.
    /** @var \Drupal\redirect\Entity\Redirect $redirect_entity */
    foreach ($entities as $redirect_entity) {
      try {
        $source = $redirect_entity->getSourceUrl();
        $redirect = $redirect_entity->getRedirectUrl();
        $lang = $redirect_entity->get('language')->value;
        $status_code = $redirect_entity->get('status_code')->value;
        $writer->insertOne([
          $source,
          $redirect->toString(),
          $lang,
          $status_code,
        ]);
      }
      catch (\Exception $e) {
        $context['results']['failures']++;
      }
      $start++;
    }

    $context['finished'] = 1;
    if ($start >= $total) {
      $context['results']['processed'] = $start;
    }
    else {
      $context['message'] = t('Exporting (@percent%).', [
        '@percent' => (int) (($start / $total) * 100),
      ]);
    }
  }

  /**
   * Finished callback for import batches.
   *
   * @param bool $success
   *   A boolean indicating whether the batch has completed successfully.
   * @param array $results
   *   The value set in $context['results'] by callback_batch_operation().
   * @param array $operations
   *   If $success is FALSE, contains the operations that remained unprocessed.
   */
  public static function batchFinishedExport($success, array $results, array $operations) {
    /** @var \Drupal\file\Entity\File $file */
    $file = !empty($results['file']) ? $results['file'] : NULL;
    if ($success && $file) {
      $uri = \Drupal::service('file_url_generator')->generateAbsoluteString($file->getFileUri());
      $url = Url::fromUri($uri);
      $download = Link::fromTextAndUrl(t('link'), $url);
      $return['link'] = $url;
      \Drupal::messenger()->addStatus(t('Export process finished. You may download the file through this %link', ['%link' => $download->toString()]));

      if (isset($results['failures']) && isset($results['processed'])) {
        \Drupal::messenger()->addStatus(t('Processed @processed items. Exported: @correct, failures: @failures',
          [
            '@processed' => $results['processed'],
            '@correct' => $results['processed'] - $results['failures'],
            '@failures' => $results['failures'],
          ]));
      }
    }
    else {
      \Drupal::messenger()->addError(t('Export process failed. Please review existing redirections or contact an administrator.'));
    }
    // In any other case, set file as temporary so that cron deletes it.
    if ($file) {
      $file->setTemporary();
      $file->save();
    }
  }

}

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

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