You are here

public static function EntityExportCsvBatch::export in Entity Export CSV 8

Export entity data.

Parameters

string $entity_type_id: The entity type on which to export.

string $bundle: The entity bundle type.

array $fields: An array of fields to export keyed by field_name. The structure of this array is :

  • field_name

    • enable : 0|1
    • exporter : the field type exporter id to use.
    • form
      • options

        • plugin configuration key : value
        • plugin configuration key : value
        • etc.

string $langcode: The langcode to export.

array $conditions: An array of conditions to apply on the query. The structure of this array is :

  • group : AND / OR group condition
  • conditions : -

    • field_name
    • value
    • operator

    -

    • field_name
    • value
    • operator.

string $delimiter: The CSV delimiter.

array $context: An array of the batch context.

Throws

\Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException

\Drupal\Component\Plugin\Exception\PluginException

\Drupal\Component\Plugin\Exception\PluginNotFoundException

File

src/EntityExportCsvBatch.php, line 58

Class

EntityExportCsvBatch
Define entity export csv batch.

Namespace

Drupal\entity_export_csv

Code

public static function export($entity_type_id, $bundle, array $fields, $langcode, array $conditions, $delimiter, array &$context) {
  $limit = 50;
  $messenger = \Drupal::messenger();

  /** @var \Drupal\entity_export_csv\EntityExportCsvManagerInterface $entity_export_csv_manager */
  $entity_export_csv_manager = \Drupal::service('entity_export_csv.manager');

  /** @var \Drupal\entity_export_csv\Plugin\FieldTypeExportManagerInterface $field_type_export_manager */
  $field_type_export_manager = \Drupal::service('plugin.manager.field_type_export');
  $definitions = $entity_export_csv_manager
    ->getBundleFields($entity_type_id, $bundle, TRUE);
  if (!isset($context['results']['file_path'])) {
    $entity_types = $entity_export_csv_manager
      ->getContentEntityTypesEnabled(TRUE);
    $bundles = $entity_export_csv_manager
      ->getBundlesEnabledPerEntityType($entity_type_id, TRUE);
    if (!isset($entity_types[$entity_type_id]) || !isset($bundles[$bundle])) {
      $messenger
        ->addWarning(t('Exporting this entity type or bundle is not allowed anymore.'));
      $context['finished'] = 1;
      return;
    }
    else {
      $context['results']['entity_type_label'] = $entity_types[$entity_type_id];
      $context['results']['bundle_label'] = $bundles[$bundle];
    }
    try {
      $file_path = static::prepareExportFile($entity_type_id, $bundle, $context);
    } catch (\Exception $e) {
      $file_path = NULL;
    }
    if (!$file_path) {
      $messenger
        ->addError(t('Unable to create the export file. Please check the system file permissions.'));
      $context['finished'] = 1;
      return;
    }
    $headers = [];
    foreach ($fields as $field_name => $values) {
      $field_definition = isset($definitions[$field_name]) ? $definitions[$field_name] : NULL;
      if (!$field_definition) {
        continue;
      }
      $enable = $values['enable'];
      $exporter = $values['exporter'];
      $configuration = $values['form']['options'];
      if (empty($enable)) {
        continue;
      }
      try {

        /** @var \Drupal\entity_export_csv\Plugin\FieldTypeExportInterface $field_type_exporter */
        $field_type_exporter = $field_type_export_manager
          ->createInstance($exporter, $configuration);
        $field_headers = $field_type_exporter
          ->getHeaders($field_definition);
        $headers = array_merge($headers, $field_headers);
      } catch (\Exception $e) {

        // The exporter is not available anymore, probably deleted.
        $messenger
          ->addError('The export @exporter is not available anymore. Please contact an administrator', [
          '@exporter' => $exporter,
        ]);
      }
    }
    $context['results']['headers'] = $headers;
    $handle = fopen($file_path, 'w');

    // Add BOM to fix UTF-8 in Excel.
    fputs($handle, $bom = chr(0xef) . chr(0xbb) . chr(0xbf));

    // Write headers now.
    fputcsv($handle, $headers, $delimiter);
    fclose($handle);
  }

  /** @var \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager */
  $entity_type_manager = \Drupal::service('entity_type.manager');

  /** @var \Drupal\Core\Entity\EntityTypeInterface $entity_type_definition */
  $entity_type_definition = $entity_type_manager
    ->getDefinition($entity_type_id);
  $storage = $entity_type_manager
    ->getStorage($entity_type_id);
  $query = $storage
    ->getQuery();
  $bundle_key = $entity_type_definition
    ->getKey('bundle');
  if (!empty($bundle_key)) {
    $query
      ->condition($bundle_key, $bundle);
  }

  // Add the conditions on the query. No UI available currently. Conditions
  // can be added via a hook_form_alter and a custom submit.
  if (!empty($conditions) && !empty($conditions['conditions'])) {
    $group = !empty($conditions['group']) ? $conditions['group'] : 'and';
    if ($group === 'or') {
      $condition_group = $query
        ->orConditionGroup();
    }
    else {
      $condition_group = $query
        ->andConditionGroup();
    }
    foreach ($conditions['conditions'] as $condition) {
      $operator = !empty($condition['operator']) ? $condition['operator'] : '=';
      $field_name = !empty($condition['field_name']) ? $condition['field_name'] : '';
      $value = !empty($condition['value']) ? $condition['value'] : '';
      if (empty($field_name) || empty($value)) {
        continue;
      }
      $condition_group
        ->condition($field_name, $value, $operator);
    }
    if (!empty($condition_group
      ->count())) {
      $query
        ->condition($condition_group);
    }
  }
  if (empty($context['sandbox'])) {
    $count_query = clone $query;
    $total = $count_query
      ->count()
      ->execute();
    $context['sandbox'] = [];
    $context['sandbox']['batch'] = 0;
    $context['sandbox']['iterations'] = abs(ceil($total / $limit));
    $context['sandbox']['count'] = 0;
    $context['sandbox']['total'] = $total;
  }
  $count =& $context['sandbox']['count'];
  $total = $context['sandbox']['total'];
  $batch =& $context['sandbox']['batch'];
  $iterations = $context['sandbox']['iterations'];
  $offset = $batch * $limit;
  $entities = $query
    ->range($offset, $limit)
    ->execute();
  $handle = fopen($context['results']['file_path'], 'a');
  foreach ($entities as $entity_id) {
    $entity = $storage
      ->load($entity_id);
    if (!$entity instanceof ContentEntityInterface) {
      continue;
    }
    if ($langcode && $entity
      ->isTranslatable() && $entity
      ->hasTranslation($langcode)) {
      $entity = $entity
        ->getTranslation($langcode);
    }
    $row = [];
    foreach ($fields as $field_name => $values) {
      $field_definition = isset($definitions[$field_name]) ? $definitions[$field_name] : NULL;
      if (!$field_definition) {
        continue;
      }
      $enable = $values['enable'];
      $exporter = $values['exporter'];
      $configuration = $values['form']['options'];
      if (empty($enable)) {
        continue;
      }
      try {

        /** @var \Drupal\entity_export_csv\Plugin\FieldTypeExportInterface $field_type_exporter */
        $field_type_exporter = $field_type_export_manager
          ->createInstance($exporter, $configuration);
        $field_values = $field_type_exporter
          ->export($entity, $field_definition);
        $row = array_merge($row, $field_values);
      } catch (\Exception $e) {

        // The exporter is not available anymore, probably deleted. We already
        // have displayed an error message when building the file headers.
      }
    }
    fputcsv($handle, $row, $delimiter);
    $count++;
  }
  fclose($handle);
  $context['message'] = new TranslatableMarkup('Exporting entities @entity_type_label @bundle_label (@count/@total)', [
    '@entity_type_label' => $context['results']['entity_type_label'],
    '@bundle_label' => $context['results']['bundle_label'],
    '@count' => $count,
    '@total' => $total,
  ]);
  $batch++;
  if ($batch != $iterations) {
    $context['finished'] = $batch / $iterations;
  }
}