pino-8.x-1.2-no-core/modules/member_import/src/Form/ImportMembersForm.php

modules/member_import/src/Form/ImportMembersForm.php
<?php

namespace Drupal\member_import\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;

use PhpOffice\PhpSpreadsheet\IOFactory;

/**
 * Form for importing new members.
 */
class ImportMembersForm extends FormBase {

  protected $step = 1;

  protected $data = [];

  protected $file = [];

  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'import_members_form';
  }

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

    // For step 2, display the data selection form.
    if ($this->step == 2) {

      // Populate the field options for Member entity.
      $entityManager = \Drupal::service('entity_field.manager');
      $fields = $entityManager->getFieldDefinitions('member', 'member');

      // Remove fields which are commonly not used.
      unset($fields['id'], $fields['uuid'], $fields['vid'], $fields['langcode'], $fields['revision_created'], $fields['revision_user'], $fields['revision_log_message'], $fields['user_id'], $fields['changed'], $fields['revision_translation_affected'], $fields['default_langcode'], $fields['revision_default']);

      $field_options = [];

      foreach ($fields as $key => $field) {
        $field_options[$key] = $field->getLabel();
      }

      // Get the real path to the uploaded file.
      $file_path = \Drupal::service('file_system')->realpath($this->file->getFileUri());

      // Load the file as a spreadsheet.
      $spreadsheet = IOFactory::load($file_path);

      $worksheet = $spreadsheet->getActiveSheet();

      // Is the header row included.
      $header_included = $form_state->getValue('header_included');

      if ($header_included) {
        $start_row = 2;
      }
      else {
        $start_row = 1;
      }

      // Loop through the columns.
      $lastColumn = $worksheet->getHighestColumn();

      for ($column = 'A'; $column <= $lastColumn; $column++) {

        $form['column_' . $column]['header'] = [
          '#markup' => '<h4 class="title is-4">' . t('Column %column', ['%column' => $column]) . ($header_included ? ' (' . $worksheet->getCell($column . '1') . ')' : '') . '</h4>',
        ];

        $example_values = $worksheet->rangeToArray($column . $start_row . ':' . $column . ($start_row + 2));

        $form['column_' . $column]['examples'] = [
          '#markup' => '<div class="columns"><div class="column is-one-third"><p class="content"><strong>' . t('Example values:') . '</strong><br/>' . implode("<br/>", [
            $example_values[0][0],
            $example_values[1][0],
            $example_values[2][0],
          ]) . '</p></div>',
        ];

        $form['column_' . $column]['field_' . $column] = [
          '#type' => 'select',
          '#options' => $field_options,
          '#empty_option' => t('- Not used -'),
          '#prefix' => '<div class="column">',
          '#suffix' => '</div></div>',
        ];

        // Try to guess the field based on header.
        if ($header_included) {
          $form['column_' . $column]['field_' . $column]['#default_value'] = $this->guessField($worksheet->getCell($column . '1')->getValue(), $field_options);
        }

      }

      $form['submit'] = [
        '#type' => 'submit',
        '#value' => t('Import'),
      ];

    }
    else {

      $form['file'] = [
        '#type' => 'file',
        '#title' => t('File upload'),
        '#upload_validators' => [
          'file_validate_extensions' => ['csv xls xlsx ods'],
          'file_validate_size' => [file_upload_max_size()],
        ],
        '#description' => t('Allowed file extensions') . ': csv, xls, xlsx, ods',
      ];

      $form['header_included'] = [
        '#type' => 'checkbox',
        '#title' => t('First row of file is headers'),
      ];

      $form['submit'] = [
        '#type' => 'submit',
        '#value' => t('Import'),
      ];

      $form['instructions'] = [
        '#markup' =>
          '<h4 class="title is-4">' . t('Instructions') . '</h4>
          <div class="content"><p>' . t('Upload a spreadsheet file containing the member data.') . '</p>
          <p>' . t('In the next step you can choose field relations between the spreadsheet data and Pino database.') . '</p>
          <p>' . t('Here are some tips for correct data handling:') . '</p>
          <ul>
            <li>' . t("Dates (like Join date) will be parsed using PHP's strtotime function, so no specific format is necessary") . '</li>
            <li>' . t('Booleans (like Is Active field) are handled as that empty fields are negative, and any data found is positive') . '</li>
            <li>' . t('Entity references (like Position field) have to be comma-separated text values. If only one value is present, commas are not required') . '</li>
          </ul></div>',
      ];

    }

    return $form;

  }

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

    // Step 2 requires no validation.
    if ($this->step == 2) {
      return;
    }

    $this->file = file_save_upload('file', $form['file']['#upload_validators'], FALSE, 0);

    if (!$this->file) {
      $form_state->setErrorByName('file', $this->t('File could not be uploaded.'));
    }

    $uploaded_files = $this->getRequest()->files->get('files', []);

    $form_state->setValue('file', $uploaded_files['file']->getRealPath());
    $form_state->setValue('file_extension', $uploaded_files['file']->getClientOriginalExtension());

  }

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

    // In step 1, rebuild the form, save the values and set the step to 2.
    if ($this->step == 1) {
      $form_state->setRebuild();
      $this->step = 2;
      $this->data = $form_state->getValues();
      return;
    }

    /* This is step 2, create a batch for rows
     * Get the real path to the uploaded file
     */

    $file_path = \Drupal::service('file_system')->realpath($this->file->getFileUri());

    // Load the file as a spreadsheet.
    $spreadsheet = IOFactory::load($file_path);

    $worksheet = $spreadsheet->getActiveSheet();

    // Create relations between the Drupal field and spreadsheet column.
    $field_relations = [];

    $lastColumn = $worksheet->getHighestColumn();

    $a = 0;

    for ($i = 'A'; $i <= $lastColumn; $i++) {

      $field_relations[$a] = $form_state->getValue('field_' . $i);

      $a++;

    }

    $rows = $worksheet->toArray();

    // Skip the header row if necessary.
    if ($this->data['header_included']) {
      array_shift($rows);
    }

    $operations = [];
    foreach ($rows as $row) {
      $operations[] = ['member_import_batch_import', [$row, $field_relations]];
    }

    $batch = [
      'title' => t('Importing new members'),
      'operations' => $operations,
      'finished' => 'member_import_batch_import_finished',
      'init_message' => t('Starting to import new members.'),
      'progress_message' => t('Processed @current out of @total. Estimated time: @estimate.'),
      'error_message' => t('The importing process has encountered an error.'),
      'file' => drupal_get_path('module', 'member_import') . '/member_import.batch.inc',
    ];

    batch_set($batch);

  }

  /**
   * Guess the Drupal field from spreadsheet header field.
   */
  private function guessField($field, $field_options) {

    // Header is named the same as the Drupal field.
    if (array_key_exists($field, $field_options)) {
      return $field;
    }

    $correct_field = "";

    // Some common field names.
    switch (mb_strtolower($field)) {
      case 'full name':
        return 'name';

      case 'email':
      case 'email address':
        return 'field_email_address';

      case 'active':
        return 'field_is_active';

      case 'join date':
      case 'joined':
        return 'field_join_date';

      case 'description':
      case 'additional information':
      case 'notes':
        return 'field_notes';

      case 'resignation':
      case 'resignation date':
        return 'field_resignation_date';

      case 'title':
      case 'position':
        return 'field_position';

    }

    return '';

  }

}

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

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