You are here

public function WebformSubmissionExporter::buildExportOptionsForm in Webform 8.5

Same name and namespace in other branches
  1. 6.x src/WebformSubmissionExporter.php \Drupal\webform\WebformSubmissionExporter::buildExportOptionsForm()

Build export options webform.

Parameters

array $form: The webform.

\Drupal\Core\Form\FormStateInterface $form_state: The current state of the form.

array $export_options: The default values.

Overrides WebformSubmissionExporterInterface::buildExportOptionsForm

File

src/WebformSubmissionExporter.php, line 303

Class

WebformSubmissionExporter
Webform submission exporter.

Namespace

Drupal\webform

Code

public function buildExportOptionsForm(array &$form, FormStateInterface $form_state, array $export_options = []) {
  $export_options += $this
    ->getDefaultExportOptions();
  $this
    ->setExporter($export_options);
  $webform = $this
    ->getWebform();

  // Get exporter plugins.
  $exporter_plugins = $this->exporterManager
    ->getInstances($export_options);

  // Determine if the file can be downloaded or displayed in the file browser.
  $total = $this->entityStorage
    ->getTotal($this
    ->getWebform(), $this
    ->getSourceEntity());
  $default_batch_limit = $this->configFactory
    ->get('webform.settings')
    ->get('batch.default_batch_export_size') ?: 500;
  $download_access = $total > $default_batch_limit ? FALSE : TRUE;

  // Build #states.
  $states_archive = [
    'invisible' => [],
  ];
  $states_options = [
    'invisible' => [],
  ];
  $states_files = [
    'invisible' => [],
  ];
  if ($webform && $download_access) {
    $states_files['invisible'][] = [
      ':input[name="download"]' => [
        'checked' => FALSE,
      ],
    ];
  }
  $states_archive_type = [
    'visible' => [],
  ];
  if ($webform && $webform
    ->hasManagedFile()) {
    $states_archive_type['visible'][] = [
      ':input[name="files"]' => [
        'checked' => TRUE,
      ],
    ];
  }
  foreach ($exporter_plugins as $plugin_id => $exporter_plugin) {
    if ($exporter_plugin
      ->isArchive()) {
      $this
        ->appendExporterToStates($states_archive, $plugin_id);
    }
    if (!$exporter_plugin
      ->hasOptions()) {
      $this
        ->appendExporterToStates($states_options, $plugin_id);
    }
    if (!$exporter_plugin
      ->hasFiles()) {
      $this
        ->appendExporterToStates($states_files, $plugin_id);
    }
    if ($webform && $exporter_plugin
      ->isArchive()) {
      $this
        ->appendExporterToStates($states_archive_type, $plugin_id);
    }
  }
  $form['#attributes']['data-webform-states-no-clear'] = TRUE;

  // Build the list of exporter descriptions.
  $exporters = $this->exporterManager
    ->getInstances();
  $exporter_description = '';
  foreach ($exporters as $exporter) {
    $exporter_description .= '<hr/>';
    $exporter_description .= '<div><strong>' . $exporter
      ->label() . '</strong></div>';
    $exporter_description .= '<div>' . $exporter
      ->description() . '</div>';
  }
  $form['export']['format'] = [
    '#type' => 'details',
    '#title' => $this
      ->t('Format options'),
    '#open' => TRUE,
  ];
  $form['export']['format']['exporter'] = [
    '#type' => 'select',
    '#title' => $this
      ->t('Export format'),
    '#options' => $this->exporterManager
      ->getOptions(),
    '#description' => $exporter_description,
    '#default_value' => $export_options['exporter'],
    // Below .js-webform-exporter is used for exporter configuration form
    // #states.
    // @see \Drupal\webform\Plugin\WebformExporterBase::buildConfigurationForm
    '#attributes' => [
      'class' => [
        'js-webform-exporter',
      ],
    ],
  ];

  // Exporter configuration forms.
  $form['export']['format']['exporters'] = [
    '#tree' => TRUE,
  ];
  foreach ($exporter_plugins as $plugin_id => $exporter) {
    $subform_state = SubformState::createForSubform($form['export']['format'], $form, $form_state);
    $exporter_form = $exporter
      ->buildConfigurationForm([], $subform_state);
    if ($exporter_form) {
      $form['export']['format']['exporters'][$plugin_id] = [
        '#type' => 'container',
        '#states' => [
          'visible' => [
            ':input.js-webform-exporter' => [
              'value' => $plugin_id,
            ],
          ],
        ],
      ] + $exporter_form;
    }
  }

  // Element.
  $form['export']['element'] = [
    '#type' => 'details',
    '#title' => $this
      ->t('Element options'),
    '#open' => TRUE,
    '#states' => $states_options,
  ];
  $form['export']['element']['multiple_delimiter'] = [
    '#type' => 'select',
    '#title' => $this
      ->t('Element multiple values delimiter'),
    '#description' => $this
      ->t('The delimiter used when an element has multiple values.'),
    '#required' => TRUE,
    '#options' => [
      ';' => $this
        ->t('Semicolon (;)'),
      ',' => $this
        ->t('Comma (,)'),
      '|' => $this
        ->t('Pipe (|)'),
      '.' => $this
        ->t('Period (.)'),
      ' ' => $this
        ->t('Space ()'),
    ],
    '#default_value' => $export_options['multiple_delimiter'],
  ];

  // Header.
  $form['export']['header'] = [
    '#type' => 'details',
    '#title' => $this
      ->t('Header options'),
    '#open' => TRUE,
    '#states' => $states_options,
  ];
  $form['export']['header']['header_format'] = [
    '#type' => 'radios',
    '#title' => $this
      ->t('Column header format'),
    '#description' => $this
      ->t('Choose whether to show the element label or element key in each column header.'),
    '#required' => TRUE,
    '#options' => [
      'label' => $this
        ->t('Element titles (label)'),
      'key' => $this
        ->t('Element keys (key)'),
    ],
    '#default_value' => $export_options['header_format'],
  ];
  $form['export']['header']['header_prefix'] = [
    '#type' => 'checkbox',
    '#title' => $this
      ->t("Include an element's title with all sub elements and values in each column header"),
    '#return_value' => TRUE,
    '#default_value' => $export_options['header_prefix'],
  ];
  $form['export']['header']['header_prefix_label_delimiter'] = [
    '#type' => 'textfield',
    '#title' => $this
      ->t('Column header label delimiter'),
    '#required' => TRUE,
    '#default_value' => $export_options['header_prefix_label_delimiter'],
  ];
  $form['export']['header']['header_prefix_key_delimiter'] = [
    '#type' => 'textfield',
    '#title' => $this
      ->t('Column header key delimiter'),
    '#required' => TRUE,
    '#default_value' => $export_options['header_prefix_key_delimiter'],
  ];
  if ($webform) {
    $form['export']['header']['header_prefix_label_delimiter']['#states'] = [
      'visible' => [
        ':input[name="header_prefix"]' => [
          'checked' => TRUE,
        ],
        ':input[name="header_format"]' => [
          'value' => 'label',
        ],
      ],
    ];
    $form['export']['header']['header_prefix_key_delimiter']['#states'] = [
      'visible' => [
        ':input[name="header_prefix"]' => [
          'checked' => TRUE,
        ],
        ':input[name="header_format"]' => [
          'value' => 'key',
        ],
      ],
    ];
  }

  // Build element specific export webforms.
  // Grouping everything in $form['export']['elements'] so that element handlers can
  // assign #weight to its export options webform.
  $form['export']['elements'] = [
    '#type' => 'container',
    '#attributes' => [
      'class' => [
        'form-item',
      ],
    ],
    '#states' => $states_options,
  ];
  $element_types = $this
    ->getWebformElementTypes();
  $element_plugins = $this->elementManager
    ->getInstances();
  foreach ($element_plugins as $element_type => $element_plugin) {
    if (empty($element_types) || isset($element_types[$element_type])) {
      $subform_state = SubformState::createForSubform($form['export']['elements'], $form, $form_state);
      $element_plugin
        ->buildExportOptionsForm($form['export']['elements'], $subform_state, $export_options);
    }
  }

  // All the remain options are only applicable to a webform's export.
  // @see Drupal\webform\Form\WebformResultsExportForm
  if ($webform) {

    // Elements.
    $form['export']['columns'] = [
      '#type' => 'details',
      '#title' => $this
        ->t('Column options'),
      '#description' => $this
        ->t('The selected columns will be included in the export.'),
      '#states' => $states_options,
    ];
    $form['export']['columns']['excluded_columns'] = [
      '#type' => 'webform_excluded_columns',
      '#webform_id' => $webform
        ->id(),
      '#default_value' => $export_options['excluded_columns'],
    ];

    // Download options.
    $form['export']['download'] = [
      '#type' => 'details',
      '#title' => $this
        ->t('Download options'),
      '#open' => TRUE,
    ];
    $form['export']['download']['download'] = [
      '#type' => 'checkbox',
      '#title' => $this
        ->t('Download export file'),
      '#description' => $this
        ->t('If checked, the export file will be automatically download to your local machine. If unchecked, the export file will be displayed as plain text within your browser.'),
      '#return_value' => TRUE,
      '#default_value' => $export_options['download'],
      '#access' => $download_access,
      '#states' => $states_archive,
    ];
    $form['export']['download']['files'] = [
      '#type' => 'checkbox',
      '#title' => $this
        ->t('Download uploaded files'),
      '#description' => $this
        ->t('If checked, the exported file and any submission file uploads will be download in the archive file.'),
      '#return_value' => TRUE,
      '#default_value' => $webform
        ->hasManagedFile() ? $export_options['files'] : 0,
      '#access' => $webform
        ->hasManagedFile(),
      '#states' => $states_files,
    ];
    $source_entity = $this
      ->getSourceEntity();
    if (!$source_entity) {
      $entity_types = $this->entityStorage
        ->getSourceEntityTypes($webform);
      if ($entity_types) {
        $form['export']['download']['submitted'] = [
          '#type' => 'item',
          '#input' => FALSE,
          '#title' => $this
            ->t('Submitted to'),
          '#description' => $this
            ->t('Select the entity type and then enter the entity id.'),
        ];
        $form['export']['download']['submitted']['container'] = [
          '#prefix' => '<div class="container-inline">',
          '#suffix' => '</div>',
        ];
        $form['export']['download']['submitted']['container']['entity_type'] = [
          '#type' => 'select',
          '#title' => $this
            ->t('Entity type'),
          '#title_display' => 'invisible',
          '#options' => [
            '' => $this
              ->t('All'),
          ] + $entity_types,
          '#default_value' => $export_options['entity_type'],
        ];
        if ($export_options['entity_type']) {
          $source_entity_options = $this->entityStorage
            ->getSourceEntityAsOptions($webform, $export_options['entity_type']);
          if ($source_entity_options) {
            $form['export']['download']['submitted']['container']['entity_id'] = [
              '#type' => 'select',
              '#title' => $this
                ->t('Entity id'),
              '#title_display' => 'invisible',
              '#default_value' => $export_options['entity_id'],
              '#options' => $source_entity_options,
            ];
          }
          else {
            $form['export']['download']['submitted']['container']['entity_id'] = [
              '#type' => 'number',
              '#title' => $this
                ->t('Entity id'),
              '#title_display' => 'invisible',
              '#min' => 1,
              '#size' => 10,
              '#default_value' => $export_options['entity_id'],
            ];
          }
        }
        else {
          $form['export']['download']['submitted']['container']['entity_id'] = [
            '#type' => 'value',
            '#value' => '',
          ];
        }
        $this
          ->buildAjaxElement('webform-submission-export-download-submitted', $form['export']['download']['submitted'], $form['export']['download']['submitted']['container']['entity_type']);
      }
    }
    $form['export']['download']['range_type'] = [
      '#type' => 'select',
      '#title' => $this
        ->t('Limit to'),
      '#options' => [
        'all' => $this
          ->t('All'),
        'latest' => $this
          ->t('Latest'),
        'uid' => $this
          ->t('Submitted by'),
        'serial' => $this
          ->t('Submission number'),
        'sid' => $this
          ->t('Submission ID'),
        'date' => $this
          ->t('Created date'),
        'date_completed' => $this
          ->t('Completed date'),
        'date_changed' => $this
          ->t('Changed date'),
      ],
      '#default_value' => $export_options['range_type'],
    ];
    $form['export']['download']['latest'] = [
      '#type' => 'container',
      '#attributes' => [
        'class' => [
          'container-inline',
        ],
      ],
      '#states' => [
        'visible' => [
          ':input[name="range_type"]' => [
            'value' => 'latest',
          ],
        ],
      ],
      'range_latest' => [
        '#type' => 'number',
        '#title' => $this
          ->t('Number of submissions'),
        '#min' => 1,
        '#default_value' => $export_options['range_latest'],
      ],
    ];
    $form['export']['download']['submitted_by'] = [
      '#type' => 'container',
      '#attributes' => [
        'class' => [
          'container-inline',
        ],
      ],
      '#states' => [
        'visible' => [
          ':input[name="range_type"]' => [
            'value' => 'uid',
          ],
        ],
      ],
      'uid' => [
        '#type' => 'entity_autocomplete',
        '#title' => $this
          ->t('User'),
        '#target_type' => 'user',
        '#default_value' => $export_options['uid'],
        '#states' => [
          'visible' => [
            ':input[name="range_type"]' => [
              'value' => 'uid',
            ],
          ],
        ],
      ],
    ];
    $ranges = [
      'serial' => [
        '#type' => 'number',
      ],
      'sid' => [
        '#type' => 'number',
      ],
      'date' => [
        '#type' => 'date',
      ],
      'date_completed' => [
        '#type' => 'date',
      ],
      'date_changed' => [
        '#type' => 'date',
      ],
    ];
    foreach ($ranges as $key => $range_element) {
      $form['export']['download'][$key] = [
        '#type' => 'container',
        '#attributes' => [
          'class' => [
            'container-inline',
          ],
        ],
        '#tree' => TRUE,
        '#states' => [
          'visible' => [
            ':input[name="range_type"]' => [
              'value' => $key,
            ],
          ],
        ],
      ];
      $form['export']['download'][$key]['range_start'] = $range_element + [
        '#title' => $this
          ->t('From'),
        '#parents' => [
          $key,
          'range_start',
        ],
        '#default_value' => $export_options['range_start'],
      ];
      $form['export']['download'][$key]['range_end'] = $range_element + [
        '#title' => $this
          ->t('To'),
        '#parents' => [
          $key,
          'range_end',
        ],
        '#default_value' => $export_options['range_end'],
      ];
    }
    $form['export']['download']['order'] = [
      '#type' => 'select',
      '#title' => $this
        ->t('Order'),
      '#description' => $this
        ->t('Order submissions by ascending (oldest first) or descending (newest first).'),
      '#options' => [
        'asc' => $this
          ->t('Sort ascending'),
        'desc' => $this
          ->t('Sort descending'),
      ],
      '#default_value' => $export_options['order'],
      '#states' => [
        'visible' => [
          ':input[name="range_type"]' => [
            '!value' => 'latest',
          ],
        ],
      ],
    ];
    $form['export']['download']['sticky'] = [
      '#type' => 'checkbox',
      '#title' => $this
        ->t('Starred/flagged submissions'),
      '#description' => $this
        ->t('If checked, only starred/flagged submissions will be downloaded. If unchecked, all submissions will downloaded.'),
      '#return_value' => TRUE,
      '#default_value' => $export_options['sticky'],
    ];

    // If drafts are allowed, provide options to filter download based on
    // submission state.
    $form['export']['download']['state'] = [
      '#type' => 'radios',
      '#title' => $this
        ->t('Submission state'),
      '#default_value' => $export_options['state'],
      '#options' => [
        'all' => $this
          ->t('Completed and draft submissions'),
        'completed' => $this
          ->t('Completed submissions only'),
        'draft' => $this
          ->t('Drafts only'),
      ],
      '#access' => $webform
        ->getSetting('draft') !== WebformInterface::DRAFT_NONE,
    ];
  }

  // Archive.
  if (class_exists('\\ZipArchive')) {
    $form['export']['archive'] = [
      '#type' => 'details',
      '#title' => $this
        ->t('Archive options'),
      '#open' => TRUE,
      '#states' => $states_archive_type,
    ];
    $form['export']['archive']['archive_type'] = [
      '#type' => 'select',
      '#title' => $this
        ->t('Archive file type'),
      '#description' => $this
        ->t('Select the archive file type for submission file uploads and generated documents.'),
      '#default_value' => $export_options['archive_type'],
      '#options' => [
        WebformExporterInterface::ARCHIVE_TAR => $this
          ->t('Tar archive (*.tar.gz)'),
        WebformExporterInterface::ARCHIVE_ZIP => $this
          ->t('ZIP file (*.zip)'),
      ],
    ];
  }
  else {
    $form['export']['archive_type'] = [
      '#type' => 'value',
      '#value' => WebformExporterInterface::ARCHIVE_TAR,
    ];
  }
}