You are here

public function ConvertBundlesForm::buildForm in Convert Bundles 8

Form constructor.

Parameters

array $form: An associative array containing the structure of the form.

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

Return value

array The form structure.

Overrides FormInterface::buildForm

File

src/Form/ConvertBundlesForm.php, line 332

Class

ConvertBundlesForm
ConvertBundlesForm.

Namespace

Drupal\convert_bundles\Form

Code

public function buildForm(array $form, FormStateInterface $form_state) {
  if (isset($this->form)) {
    $form = $this->form;
  }
  $form['#title'] = $this
    ->t('Convert Bundles');
  $submit_label = 'Next';
  switch ($this->step) {
    case 1:
      if ($this->routeMatch
        ->getRouteName() == 'convert_bundles.admin') {
        $this->tempStoreFactory
          ->get('convert_bundles_ids')
          ->delete($this->currentUser);
      }

      // Retrieve IDs from the temporary storage.
      $this->entities = $this->tempStoreFactory
        ->get('convert_bundles_ids')
        ->get($this->currentUser);
      if (!empty($this->entities)) {
        $this->step++;
        goto two;
      }
      $options = [];
      foreach (array_keys($this->entityTypeManager
        ->getDefinitions()) as $entity_type) {
        $bundles = $this->bundleInfo
          ->getAllBundleInfo();
        $storage = \Drupal::service('entity_type.manager')
          ->getStorage($entity_type);
        if (isset($bundles[$entity_type]) && !empty($bundles[$entity_type]) && count($bundles[$entity_type]) > 1 && method_exists($storage, 'getBaseTable') && method_exists($storage, 'getDataTable')) {
          $options[$entity_type] = $entity_type;
        }
      }
      $header = [
        'type_names' => $this
          ->t('Entity Types'),
      ];
      $form['#title'] .= ' - ' . $this
        ->t('Select Entity Type to Convert (Only Entity Types with multiple bundles are shown)');
      $form['convert_entity_type'] = [
        '#type' => 'select',
        '#header' => $header,
        '#options' => $options,
        '#empty' => $this
          ->t('No convertable types found'),
      ];
      break;
    case 2:
      two:
      $options = [];
      $bundle_info = $this->bundleInfo
        ->getAllBundleInfo();
      $bundles = [];
      if (!empty($this->entities)) {
        $entity_types = [];
        foreach ($this->entities as $entity) {
          $bundles[] = $entity
            ->bundle();
          $entity_types[] = $entity
            ->getEntityTypeId();
        }
        if (count($entity_type = array_unique($entity_types)) > 1) {
          \Drupal::messenger()
            ->addError($this
            ->t('We cant convert multiple types of entities at once'));
        }
        $this->entityType = $entity_type[0];
      }
      $all_bundles = $bundle_info[$this->entityType];
      foreach ($all_bundles as $machine_name => $bundle_array) {
        $this->allBundles[$machine_name] = $bundle_array['label'];
      }
      if (empty($bundles)) {
        $bundles = array_keys($all_bundles);
      }
      if (count($bundles) == 1) {
        $this->step++;
        $this->fromType = $bundles;
        goto three;
      }
      foreach (array_unique($bundles) as $bundle) {
        $options[$bundle]['bundle_names'] = $all_bundles[$bundle]['label'];
      }
      $header = [
        'bundle_names' => $this
          ->t('Bundle Name(s)'),
      ];
      $form['#title'] .= ' - ' . $this
        ->t('Select Bundles to Convert (Bundles are from all entities selected)');
      $form['convert_bundles_from'] = [
        '#type' => 'tableselect',
        '#header' => $header,
        '#options' => $options,
        '#empty' => $this
          ->t('No bundles found'),
      ];
      break;
    case 3:
      three:
      $form['#title'] .= ' - ' . $this
        ->t('Select the Bundle to Convert Selected Entities to');
      $form['convert_bundles_to'] = [
        '#type' => 'select',
        '#title' => $this
          ->t('To Bundle'),
        '#options' => $this->allBundles,
      ];
      break;
    case 4:

      // Get the fields.
      $entityFieldManager = $this->entityFieldManager;
      foreach ($this->fromType as $from_bundle) {
        $this->fieldsFrom[$from_bundle] = $entityFieldManager
          ->getFieldDefinitions($this->entityType, $from_bundle);
      }
      $this->fieldsTo = $entityFieldManager
        ->getFieldDefinitions($this->entityType, $this->toType);
      $fields_to = ConvertBundles::getToFields($this->fieldsTo);
      $fields_to_names = $fields_to['fields_to_names'];
      $fields_to_types = $fields_to['fields_to_types'];
      $fields_from = ConvertBundles::getFromFields($this->fieldsFrom, $fields_to_names, $fields_to_types);
      $fields_from_names = $fields_from['fields_from_names'];
      $fields_from_form = $fields_from['fields_from_form'];

      // Find missing fields. allowing values to be input later.
      $fields_to_names = array_diff($fields_to_names, [
        'remove',
        'append_to_body',
      ]);
      $this->fieldsNewTo = array_diff(array_keys($fields_to_names), $fields_from_names);
      $form = array_merge($form, $fields_from_form);
      $form['actions']['submit'] = [
        '#type' => 'submit',
        '#value' => $this
          ->t('Next'),
        '#button_type' => 'primary',
      ];
      break;
    case 5:
      $form['create_new'] = [
        '#type' => 'checkbox',
        '#title' => $this
          ->t('Create field values for new fields in target content type'),
      ];
      $form['actions']['submit'] = [
        '#type' => 'submit',
        '#value' => $this
          ->t('Next'),
        '#button_type' => 'primary',
      ];
      break;
    case 6:

      // Put the to fields in the form for new values.
      foreach ($this->fieldsNewTo as $field_name) {
        if (!in_array($field_name, $this->userInput)) {

          // TODO - Date widgets are relative. Fix.
          // Create an arbitrary entity object.
          $ids = (object) [
            'entity_type' => $this->entityType,
            'bundle' => $this->toType,
            'entity_id' => NULL,
          ];
          $fake_entity = _field_create_entity_from_ids($ids);
          $items = $fake_entity
            ->get($field_name);
          $temp_form_element = [];
          $temp_form_state = new FormState();
          $form[$field_name] = $items
            ->defaultValuesForm($temp_form_element, $temp_form_state);
        }
      }
      $form['actions']['submit'] = [
        '#type' => 'submit',
        '#value' => $this
          ->t('Next'),
        '#button_type' => 'primary',
      ];
      break;
    case 7:
      $count = \Drupal::translation()
        ->formatPlural(count($this->entities), '1 selected entity', '@count selected entities');
      $from_types = implode(', ', $this->fromType);
      \Drupal::messenger()
        ->addWarning($this
        ->t('Are you sure you want to convert @target of type <em>@from_type</em> to type <em>@to_type</em>?', [
        '@target' => $count,
        '@from_type' => $from_types,
        '@to_type' => $this->toType,
      ]));
      $form['actions']['submit'] = [
        '#type' => 'submit',
        '#value' => $this
          ->t('Convert'),
        '#button_type' => 'primary',
      ];
      break;
  }
  \Drupal::messenger()
    ->addWarning($this
    ->t('This module is experimental. PLEASE do not use on production databases without prior testing and a complete database dump.'));
  $form['actions']['submit'] = [
    '#type' => 'submit',
    '#value' => $submit_label,
    '#button_type' => 'primary',
  ];
  return $form;
}