You are here

UserCsvImportForm.php in User CSV import 2.0.x

Same filename and directory in other branches
  1. 8 src/Form/UserCsvImportForm.php
  2. 1.0.x src/Form/UserCsvImportForm.php

File

src/Form/UserCsvImportForm.php
View source
<?php

namespace Drupal\user_csv_import\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
use Drupal\user\RoleInterface;
use Drupal\user_csv_import\Controller\UserCsvImportController;
use Drupal\Core\Messenger\MessengerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Entity\EntityFieldManager;
use Symfony\Component\HttpFoundation\Response;

/**
 * Provides methods to define and build the user import form.
 */
class UserCsvImportForm extends FormBase {

  /**
   * Provides messenger service.
   *
   * @var \Drupal\Core\Messenger\MessengerInterface
   */
  protected $messenger;

  /**
   * Provides user entity.
   *
   * @var \Drupal\Core\Entity\EntityFieldManager
   */
  protected $entityManager;

  /**
   * User import Form constructor.
   *
   * @param \Drupal\Core\Messenger\MessengerInterface $messenger
   * @param \Drupal\Core\Entity\EntityFieldManager $entityManager
   */
  public function __construct(MessengerInterface $messenger, EntityFieldManager $entityManager) {
    $this->messenger = $messenger;
    $this->entityManager = $entityManager;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static($container
      ->get('messenger'), $container
      ->get('entity_field.manager'));
  }

  /**
   * Implements \Drupal\Core\Form\FormInterface::getFormID().
   */
  public function getFormID() {
    return 'user_csv_import_form';
  }

  /**
   * {@inheritdoc}
   */
  protected function getEditableConfigNames() {
    return [];
  }

  /**
   * Implements \Drupal\Core\Form\FormInterface::buildForm().
   *
   * @param array $form
   *   The form array.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The form state.
   *
   * @return array
   *   Return the form object.
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $form['#tree'] = TRUE;

    // Options field set.
    $form['config_options'] = [
      '#type' => 'fieldset',
      '#title' => $this
        ->t('Options'),
    ];

    // Roles field.
    $roles = user_role_names();
    unset($roles['anonymous']);
    $form['config_options']['roles'] = [
      '#type' => 'checkboxes',
      '#title' => $this
        ->t('Roles'),
      '#options' => $roles,
    ];

    // Special handling for the inevitable "Authenticated user" role.
    $form['config_options']['roles'][RoleInterface::AUTHENTICATED_ID] = [
      '#default_value' => TRUE,
      '#disabled' => TRUE,
    ];

    // Default password.
    $form['config_options']['password'] = [
      '#type' => 'textfield',
      '#title' => $this
        ->t('Default password'),
      '#required' => TRUE,
      '#description' => t('Passwords can be set in different ways. You can set one here that will be applied to all accounts. If you wish, you may set your automated emails to send a password reset link. This would allow the new users to set their own passwords. Optionally, you may checkmark the Password (pass) field below and provide unique passwords in the CSV for each user. In that case, this field is still required as any unpopulated `pass` column fields will default to this Default Password.'),
    ];

    // Status.
    $form['config_options']['status'] = [
      '#type' => 'select',
      '#title' => $this
        ->t('Status'),
      '#options' => [
        '0' => $this
          ->t('Blocked'),
        '1' => $this
          ->t('Active'),
      ],
      '#description' => t('Ensure this is set to Active if you want the user to be enabled.'),
    ];

    // Send email on create user.
    $form['config_options']['registration_email_type'] = [
      '#type' => 'select',
      '#title' => $this
        ->t('Select registration email type to send to user'),
      '#options' => [
        'none' => $this
          ->t('Do not send a registration email'),
        'register_admin_created' => $this
          ->t('Welcome message for user created by the admin'),
        'register_no_approval_required' => $this
          ->t('Welcome message when user self-registers'),
        'status_activated' => $this
          ->t('Account activated'),
      ],
      '#description' => t('If sending, ensure that \'Status\' is correctly set to coorispond with the email you plan to send out. Most sites will manage the emails here: /admin/config/people/accounts'),
    ];

    // Fields field set.
    $form['config_fields'] = [
      '#type' => 'fieldset',
      '#title' => $this
        ->t('Fields'),
    ];

    // Get user entity fields.
    $user_fields = $this
      ->filterDefaultFields($this->entityManager
      ->getFieldStorageDefinitions('user'));

    // Construct values for checkboxes.
    $selectable_fields = [];
    foreach ($user_fields as $field) {
      $selectable_fields[$field
        ->getName()] = $field
        ->getLabel();
    }

    // Select all fields.
    $form['config_fields']['check_all'] = [
      '#type' => 'checkbox',
      '#title' => $this
        ->t('All'),
    ];

    // User form fields.
    $form['config_fields']['fields'] = [
      '#type' => 'checkboxes',
      '#options' => $selectable_fields,
    ];

    // File to upload.
    $form['file'] = [
      '#type' => 'file',
      '#title' => 'CSV file upload',
      '#upload_validators' => [
        'file_validate_extensions' => [
          'csv',
        ],
      ],
    ];
    $form['actions']['#type'] = 'actions';
    $form['actions']['submit'] = [
      '#type' => 'submit',
      '#value' => $this
        ->t('Import users'),
      '#button_type' => 'primary',
    ];
    $form['actions']['sample'] = [
      '#type' => 'submit',
      '#value' => $this
        ->t('Generate sample CSV'),
      '#button_type' => 'secondary',
      '#submit' => [
        [
          $this,
          'generateSample',
        ],
      ],
    ];

    // By default, render the form using theme_system_config_form().
    $form['#theme'] = 'system_config_form';
    return $form;
  }
  public function generateSample(&$form, FormStateInterface $form_state) {
    $fields = $form_state
      ->getValue([
      'config_fields',
      'fields',
    ]);
    $content = implode(',', array_filter($fields)) . PHP_EOL;
    for ($i = 1; $i < 3; $i++) {
      $row = [];
      foreach (array_filter($fields) as $field) {
        $row[] = 'sample_' . $field . '_' . $i;
      }
      $content .= implode(',', $row) . PHP_EOL;
    }
    $response = new Response();
    $response
      ->setContent($content);
    $response->headers
      ->set('Content-Type', 'text/csv');
    $response->headers
      ->set('Content-Disposition', 'attachment; filename="user-csv-import-sample.csv"');
    $form_state
      ->setResponse($response);
  }

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

    // Get form data.
    $roles = $form_state
      ->getValue([
      'config_options',
      'roles',
    ]);
    $fields = $form_state
      ->getValue([
      'config_fields',
      'fields',
    ]);
    $sample_only = $form_state
      ->getValue('op') == $form['actions']['sample']['#value'];

    // Filter vales and clean empty.
    $roles_selected = array_filter($roles, function ($item) {
      return $item;
    });
    $fields_selected = array_filter($fields, function ($item) {
      return $item;
    });

    // If there is no options selected, show the error.
    if (empty($roles_selected) && !$sample_only) {
      $form_state
        ->setErrorByName('roles', $this
        ->t('Please select at least one role to apply to the imported user(s).'));
    }
    elseif (empty($fields_selected)) {
      $form_state
        ->setErrorByName('fields', $this
        ->t('Please select at least one field to apply to the imported user(s).'));

      // If "mail" and "name" fields are not selected, show an error.
    }
    elseif (!array_key_exists('mail', $fields_selected) or !array_key_exists('name', $fields_selected)) {
      $form_state
        ->setErrorByName('roles', $this
        ->t('The email and username fields is required'));
    }
    if ($sample_only) {

      // Don't validate file if we're generating a sample.
      return;
    }

    // Validate file.
    $this->file = file_save_upload('file', $form['file']['#upload_validators']);
    if (!$this->file[0]) {
      $form_state
        ->setErrorByName('file');
    }
  }

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

    // Get form data.
    $file = $this->file[0];
    $roles = $form_state
      ->getValue([
      'config_options',
      'roles',
    ]);
    $fields = $form_state
      ->getValue([
      'config_fields',
      'fields',
    ]);

    // Construct data to send to the controller.
    $config = [
      'roles' => array_filter($roles, function ($item) {
        return $item;
      }),
      'fields' => array_filter($fields, function ($item) {
        return $item;
      }),
      'registration_email_type' => $form_state
        ->getValue([
        'config_options',
        'registration_email_type',
      ]),
      'password' => $form_state
        ->getValue([
        'config_options',
        'password',
      ]),
      'status' => $form_state
        ->getValue([
        'config_options',
        'status',
      ]),
    ];

    // Return success message.
    if ($created = UserCsvImportController::processUpload($file, $config)) {
      $this->messenger
        ->addMessage($this
        ->t('Successfully imported @count users.', [
        '@count' => count($created),
      ]));
    }
    else {

      // Return error message.
      $this->messenger
        ->addMessage($this
        ->t('No users imported.'));
    }

    // Redirect to admin users page.
    $form_state
      ->setRedirectUrl(new Url('entity.user.collection'));
  }

  /**
   * Unset user account default fields.
   */
  private function filterDefaultFields($fields) {
    unset($fields['uid']);
    unset($fields['uuid']);
    unset($fields['langcode']);
    unset($fields['preferred_langcode']);
    unset($fields['preferred_admin_langcode']);
    unset($fields['timezone']);
    unset($fields['status']);
    unset($fields['created']);
    unset($fields['changed']);
    unset($fields['access']);
    unset($fields['login']);
    unset($fields['init']);
    unset($fields['roles']);
    unset($fields['default_langcode']);
    unset($fields['user_picture']);
    return $fields;
  }

}

Classes

Namesort descending Description
UserCsvImportForm Provides methods to define and build the user import form.