You are here

public function MappingEditForm::form in GatherContent 8.3

Gets the actual form array to be built.

Overrides EntityForm::form

See also

\Drupal\Core\Entity\EntityForm::processForm()

\Drupal\Core\Entity\EntityForm::afterBuild()

File

src/Form/MappingEditForm.php, line 98

Class

MappingEditForm
Class MappingEditForm.

Namespace

Drupal\gathercontent\Form

Code

public function form(array $form, FormStateInterface $form_state) {
  if (empty($this->step)) {
    $this->step = 'field_mapping';
  }
  $form['#attached']['library'][] = 'gathercontent/theme';
  $form['#attached']['library'][] = 'gathercontent/entity_references';

  /** @var \Drupal\gathercontent\Entity\MappingInterface $mapping */
  $mapping = $this->entity;
  $this->new = !$mapping
    ->hasMapping();
  $tmp = new Template();
  $this->template = $tmp
    ->getTemplate($mapping
    ->getGathercontentTemplateId());
  if ($this->step === 'field_mapping') {
    $content_types = node_type_get_names();
    $form['form_description'] = [
      '#type' => 'html_tag',
      '#tag' => 'i',
      '#value' => t('Please map your GatherContent Template fields to your Drupal
    Content Type Fields. Please note that a GatherContent field can only be
    mapped to a single Drupal field. So each field can only be mapped to once.'),
    ];
    $form['gathercontent_project'] = [
      '#type' => 'item',
      '#title' => $this
        ->t('Project name:'),
      '#markup' => $mapping
        ->getGathercontentProject(),
      '#wrapper_attributes' => [
        'class' => [
          'inline-label',
        ],
      ],
    ];
    $form['gathercontent'] = [
      '#type' => 'container',
    ];
    $form['gathercontent']['gathercontent_template'] = [
      '#type' => 'item',
      '#title' => $this
        ->t('GatherContent template:'),
      '#markup' => $mapping
        ->getGathercontentTemplate(),
      '#wrapper_attributes' => [
        'class' => [
          'inline-label',
        ],
      ],
    ];
    if (!$this->new) {
      $this->mappingData = unserialize($mapping
        ->getData());
      $this->contentType = $mapping
        ->getContentType();
      $form['#attached']['drupalSettings']['gathercontent'] = $this
        ->getAllEntityReferenceFields();
      $form['gathercontent']['content_type'] = [
        '#type' => 'item',
        '#title' => $this
          ->t('Drupal content type:'),
        '#markup' => $mapping
          ->getContentTypeName(),
        '#wrapper_attributes' => [
          'class' => [
            'inline-label',
          ],
        ],
      ];
      $form['mapping'] = [
        '#prefix' => '<div id="edit-mapping">',
        '#suffix' => '</div>',
      ];
      foreach ($this->template->config as $i => $fieldset) {
        if ($fieldset->hidden === FALSE) {
          $form['mapping'][$fieldset->name] = [
            '#type' => 'details',
            '#title' => $fieldset->label,
            '#open' => $i === 0 ? TRUE : FALSE,
            '#tree' => TRUE,
          ];
          if (\Drupal::moduleHandler()
            ->moduleExists('metatag')) {
            $form['mapping'][$fieldset->name]['type'] = [
              '#type' => 'select',
              '#options' => [
                'content' => t('Content'),
                'metatag' => t('Metatag'),
              ],
              '#title' => t('Type'),
              '#default_value' => isset($this->mappingData[$fieldset->name]['type']) || $form_state
                ->hasValue($fieldset->name)['type'] ? $form_state
                ->hasValue($fieldset->name)['type'] ? $form_state
                ->getValue($fieldset->name)['type'] : $this->mappingData[$fieldset->name]['type'] : 'content',
              '#ajax' => [
                'callback' => '::getMappingTable',
                'wrapper' => 'edit-mapping',
                'method' => 'replace',
                'effect' => 'fade',
              ],
            ];
          }
          if (\Drupal::moduleHandler()
            ->moduleExists('content_translation') && \Drupal::service('content_translation.manager')
            ->isEnabled('node', $form_state
            ->getValue('content_type'))) {
            $form['mapping'][$fieldset->name]['language'] = [
              '#type' => 'select',
              '#options' => [
                'und' => t('None'),
              ] + $this
                ->getLanguageList(),
              '#title' => t('Language'),
              '#default_value' => isset($this->mappingData[$fieldset->name]['language']) ? $this->mappingData[$fieldset->name]['language'] : 'und',
            ];
          }
          foreach ($fieldset->elements as $gc_field) {
            $d_fields = [];
            if (isset($form_state
              ->getTriggeringElement()['#name'])) {

              // We need different handling for changed fieldset.
              if ($form_state
                ->getTriggeringElement()['#array_parents'][1] === $fieldset->name) {
                if ($form_state
                  ->getTriggeringElement()['#value'] === 'content') {
                  $d_fields = $this
                    ->filterFields($gc_field, $mapping
                    ->getContentType());
                }
                elseif ($form_state
                  ->getTriggeringElement()['#value'] === 'metatag') {
                  $d_fields = $this
                    ->filterMetatags($gc_field);
                }
              }
              else {
                if ($form_state
                  ->getValue($fieldset->name)['type'] === 'content') {
                  $d_fields = $this
                    ->filterFields($gc_field, $mapping
                    ->getContentType());
                }
                elseif ($form_state
                  ->getTriggeringElement()['#value'] === 'metatag') {
                  $d_fields = $this
                    ->filterMetatags($gc_field);
                }
              }
            }
            else {
              if (isset($this->mappingData[$fieldset->name]['type']) && $this->mappingData[$fieldset->name]['type'] === 'content' || !isset($this->mappingData[$fieldset->name]['type'])) {
                $d_fields = $this
                  ->filterFields($gc_field, $mapping
                  ->getContentType());
              }
              else {
                $d_fields = $this
                  ->filterMetatags($gc_field);
              }
            }
            $form['mapping'][$fieldset->name]['elements'][$gc_field->name] = [
              '#type' => 'select',
              '#options' => $d_fields,
              '#title' => isset($gc_field->label) ? $gc_field->label : $gc_field->title,
              '#default_value' => isset($this->mappingData[$fieldset->name]['elements'][$gc_field->name]) ? $this->mappingData[$fieldset->name]['elements'][$gc_field->name] : NULL,
              '#empty_option' => t("Don't map"),
              '#attributes' => [
                'class' => [
                  'gathercontent-ct-element',
                ],
              ],
            ];
          }
        }
      }
      $form['mapping']['er_mapping_type'] = [
        '#type' => 'radios',
        '#title' => $this
          ->t('Taxonomy terms mapping type'),
        '#options' => [
          'automatic' => $this
            ->t('Automatic'),
          'semiautomatic' => $this
            ->t('Semi-automatic'),
          'manual' => $this
            ->t('Manual'),
        ],
        '#attributes' => [
          'class' => [
            'gathercontent-er-mapping-type',
          ],
        ],
        '#description' => $this
          ->t("<strong>Automatic</strong> - taxonomy terms will be automatically created in predefined vocabulary. You cannot select translations. Field should be set as translatable for correct functionality.<br>\n<strong>Semi-automatic</strong> - taxonomy terms will be imported into predefined vocabulary in the first language and we will offer you possibility to select their translations from other languages. For single language mapping this option will execute same action as 'Automatic' importField should not be set as translatable for correct functionality.<br>\n<strong>Manual</strong> - you can map existing taxonomy terms from predefined vocabulary to translations in all languages."),
      ];
    }
    else {
      $form['gathercontent']['content_type'] = [
        '#type' => 'select',
        '#title' => $this
          ->t('Drupal content type'),
        '#options' => $content_types,
        '#required' => TRUE,
        '#wrapper_attributes' => [
          'class' => [
            'inline-label',
          ],
        ],
        '#ajax' => [
          'callback' => '::getMappingTable',
          'wrapper' => 'edit-mapping',
          'method' => 'replace',
          'effect' => 'fade',
        ],
        '#default_value' => $form_state
          ->getValue('content_type'),
      ];
      $form['mapping'] = [
        '#prefix' => '<div id="edit-mapping">',
        '#suffix' => '</div>',
      ];
      if ($form_state
        ->hasValue('content_type')) {
        $this->contentType = $form_state
          ->getValue('content_type');
        foreach ($this->template->config as $i => $fieldset) {
          if ($fieldset->hidden === FALSE) {
            $form['mapping'][$fieldset->name] = [
              '#type' => 'details',
              '#title' => $fieldset->label,
              '#open' => $i === 0 ? TRUE : FALSE,
              '#tree' => TRUE,
            ];
            if ($i === 0) {
              $form['mapping'][$fieldset->name]['#prefix'] = '<div id="edit-mapping">';
            }
            if (end($this->template->config) === $fieldset) {
              $form['mapping'][$fieldset->name]['#suffix'] = '</div>';
            }
            if (\Drupal::moduleHandler()
              ->moduleExists('metatag')) {
              $form['mapping'][$fieldset->name]['type'] = [
                '#type' => 'select',
                '#options' => [
                  'content' => t('Content'),
                  'metatag' => t('Metatag'),
                ],
                '#title' => t('Type'),
                '#default_value' => $form_state
                  ->hasValue($fieldset->name)['type'] ? $form_state
                  ->getValue($fieldset->name)['type'] : 'content',
                '#ajax' => [
                  'callback' => '::getMappingTable',
                  'wrapper' => 'edit-mapping',
                  'method' => 'replace',
                  'effect' => 'fade',
                ],
              ];
            }
            if (\Drupal::moduleHandler()
              ->moduleExists('content_translation') && \Drupal::service('content_translation.manager')
              ->isEnabled('node', $form_state
              ->getValue('content_type'))) {
              $form['mapping'][$fieldset->name]['language'] = [
                '#type' => 'select',
                '#options' => [
                  'und' => t('None'),
                ] + $this
                  ->getLanguageList(),
                '#title' => t('Language'),
                '#default_value' => $form_state
                  ->hasValue($fieldset->name)['language'] ? $form_state
                  ->getValue($fieldset->name)['language'] : 'und',
              ];
            }
            foreach ($fieldset->elements as $gc_field) {
              $d_fields = [];
              if ($form_state
                ->getTriggeringElement()['#name'] !== 'content_type') {

                // We need different handling for changed fieldset.
                if ($form_state
                  ->getTriggeringElement()['#array_parents'][1] === $fieldset->name) {
                  if ($form_state
                    ->getTriggeringElement()['#value'] === 'content') {
                    $d_fields = $this
                      ->filterFields($gc_field, $this->contentType);
                  }
                  elseif ($form_state
                    ->getTriggeringElement()['#value'] === 'metatag') {
                    $d_fields = $this
                      ->filterMetatags($gc_field);
                  }
                }
                else {
                  if ($form_state
                    ->getValue($fieldset->name)['type'] === 'content') {
                    $d_fields = $this
                      ->filterFields($gc_field, $this->contentType);
                  }
                  elseif ($form_state
                    ->getValue($fieldset->name)['type'] === 'metatag') {
                    $d_fields = $this
                      ->filterMetatags($gc_field);
                  }
                }
              }
              else {
                $d_fields = $this
                  ->filterFields($gc_field, $this->contentType);
              }
              $form['mapping'][$fieldset->name]['elements'][$gc_field->name] = [
                '#type' => 'select',
                '#options' => $d_fields,
                '#title' => isset($gc_field->label) ? $gc_field->label : $gc_field->title,
                '#empty_option' => $this
                  ->t("Don't map"),
                '#default_value' => $form_state
                  ->hasValue($fieldset->name)['elements'][$gc_field->name] ? $form_state
                  ->getValue($fieldset->name)['elements'][$gc_field->name] : NULL,
                '#attributes' => [
                  'class' => [
                    'gathercontent-ct-element',
                  ],
                ],
              ];
            }
          }
        }
        $form['mapping']['er_mapping_type'] = [
          '#type' => 'radios',
          '#title' => $this
            ->t('Taxonomy terms mapping type'),
          '#options' => [
            'automatic' => $this
              ->t('Automatic'),
            'semiautomatic' => $this
              ->t('Semi-automatic'),
            'manual' => $this
              ->t('Manual'),
          ],
          '#attributes' => [
            'class' => [
              'gathercontent-er-mapping-type',
            ],
          ],
          '#description' => $this
            ->t("<strong>Automatic</strong> - taxonomy terms will be automatically created in predefined vocabulary. You cannot select translations. Field should be set as translatable for correct functionality.<br>\n<strong>Semi-automatic</strong> - taxonomy terms will be imported into predefined vocabulary in the first language and we will offer you possibility to select their translations from other languages. For single language mapping this option will execute same action as 'Automatic' importField should not be set as translatable for correct functionality.<br>\n<strong>Manual</strong> - you can map existing taxonomy terms from predefined vocabulary to translations in all languages."),
        ];
      }
    }
  }
  elseif ($this->step === 'er_mapping') {

    // Unset previous form.
    foreach ($form as $k => $item) {
      if (!in_array($k, [
        '#attributes',
        '#cache',
      ])) {
        unset($form[$k]);
      }
    }
    foreach ($this->entityReferenceFields as $field => $gcMapping) {
      $field_config = FieldConfig::loadByName('node', $this->contentType, $field);
      $options = [];
      $header = [];

      // Prepare options for every language.
      foreach ($gcMapping as $lang => $fieldSettings) {
        foreach ($this->template->config as $tab) {
          if ($tab->name === $fieldSettings['tab']) {
            foreach ($tab->elements as $element) {
              if ($element->name == $fieldSettings['name']) {
                $header[$lang] = $this
                  ->t('@field (@lang values)', [
                  '@field' => $element->label,
                  '@lang' => strtoupper($lang),
                ]);
                if (count($header) === 1 && $this->erImportType === 'manual') {
                  $header['terms'] = $this
                    ->t('Terms');
                }
                foreach ($element->options as $option) {
                  if (!isset($option->value)) {
                    $options[$lang][$option->name] = $option->label;
                  }
                }
              }
            }
          }
        }
      }
      $term_options = [];

      // For manual mapping load terms from vocabulary.
      if ($this->erImportType === 'manual') {
        $settings = $field_config
          ->getSetting('handler_settings');

        /** @var \Drupal\taxonomy\Entity\Term[] $terms */
        if (!empty($settings['auto_create_bundle'])) {
          $terms = $this->entityTypeManager
            ->getStorage('taxonomy_term')
            ->loadByProperties([
            'vid' => $settings['auto_create_bundle'],
          ]);
        }
        else {
          $target = reset($settings['target_bundles']);
          $terms = $this->entityTypeManager
            ->getStorage('taxonomy_term')
            ->loadByProperties([
            'vid' => $target,
          ]);
        }
        foreach ($terms as $term) {
          $term_options[$term
            ->id()] = $term
            ->getName();
        }
      }

      // Extract available languages and first language and his options.
      $languages = array_keys($header);
      $first_language = array_shift($languages);
      $first_language_options = array_shift($options);

      // Delete terms from languages, it's not language.
      if (isset($languages[0]) && $languages[0] === 'terms') {
        unset($languages[0]);
      }
      $form[$field] = [
        '#tree' => TRUE,
      ];
      $form[$field]['title'] = [
        '#type' => 'html_tag',
        '#value' => $this
          ->t('Field @field', [
          '@field' => $field_config
            ->getLabel(),
        ]),
        '#tag' => 'h2',
      ];

      // Define table header.
      $form[$field]['table'] = [
        '#type' => 'table',
        '#header' => $header,
      ];

      // Each option in the first language is new row.
      // This solution is not dealing with situation when other languages has
      // more options than first language.
      $rows = 0;
      foreach ($first_language_options as $k => $option) {
        $form[$field]['table'][$rows][$first_language] = [
          '#type' => 'value',
          '#value' => $k,
          '#markup' => $option,
        ];
        if ($this->erImportType === 'manual') {
          $form[$field]['table'][$rows]['terms'] = [
            '#type' => 'select',
            '#options' => $term_options,
            '#title' => $this
              ->t('Taxonomy term options'),
            '#title_display' => 'invisible',
            '#empty_option' => $this
              ->t('- None -'),
          ];
        }
        foreach ($languages as $i => $language) {
          $form[$field]['table'][$rows][$language] = [
            '#type' => 'select',
            '#options' => $options[$language],
            '#title' => $this
              ->t('@lang options', [
              '@lang' => $language,
            ]),
            '#title_display' => 'invisible',
            '#empty_option' => $this
              ->t('- None -'),
          ];
        }
        $rows++;
      }
    }
    $this->step = 'completed';
  }
  return $form;
}