You are here

public static function EntityconnectFormUtils::returnFormAlter in Entity connect 8.2

Complete entityreference field on parent form with the target_id value.

This is for when we return to the parent page we find the cached form and form_state clean up the form_state a bit and mark it to be rebuilt.

If the cache has a target_id we set that in the input.

Parameters

array $form: Parent form.

\Drupal\Core\Form\FormStateInterface $form_state: Parent form state.

array $cache_data: Parent cache data.

1 call to EntityconnectFormUtils::returnFormAlter()
entityconnect_form_alter in ./entityconnect.module
Implements hook_form_alter().

File

src/EntityconnectFormUtils.php, line 263

Class

EntityconnectFormUtils
Contains form alter, callbacks and utility methods for entityconnect.

Namespace

Drupal\entityconnect

Code

public static function returnFormAlter(array &$form, FormStateInterface $form_state, array $cache_data) {
  if (empty($form_state
    ->get('#entityconnect_processed'))) {
    $old_form = $cache_data['form'];

    /** @var \Drupal\Core\Form\FormStateInterface $old_form_state */
    $old_form_state = $cache_data['form_state'];

    // Save the storage and input from the original form state.
    $form_state
      ->setStorage($old_form_state
      ->getStorage());
    $form_state
      ->setUserInput($old_form_state
      ->getUserInput());
    $triggeringElement = $old_form_state
      ->getTriggeringElement();

    // Gets the parents of the triggering element (our entityconnect button)
    // which is at the same level as the reference field. Since we will be
    // traversing the actual form, use #array_parents as opposed to #parents.
    $parents = is_array($triggeringElement) && !empty($triggeringElement['#array_parents']) ? $triggeringElement['#array_parents'] : NULL;
    $key_exists = NULL;

    // Now get the reference field container.
    $widget_container = EntityconnectNestedArray::getValue($old_form, $parents, $key_exists);
    if ($key_exists) {
      if (isset($widget_container['widget'])) {
        $widget_container = $widget_container['widget'];
      }
    }
    else {

      // @ToDo: probably need something to happen in this case.
      return;
    }

    // Now get the actual parents for traversing user input.
    $parents = $widget_container['#parents'];
    $widget_container_type = isset($widget_container['#type']) ? $widget_container['#type'] : 'autocomplete';

    /** @var \Drupal\field\FieldStorageConfigInterface $field_info */
    $field_info = $cache_data['field_info'];
    if (isset($cache_data['target_id']) && empty($cache_data['cancel'])) {

      // Load the the target entity.
      $entity_type = $cache_data['target_entity_type'];
      $entity_storage = \Drupal::entityTypeManager()
        ->getStorage($entity_type);
      $entity = $entity_storage
        ->load($cache_data['target_id']);
      if ($cache_data['target_id']) {
        $target_id = $entity ? $entity
          ->id() : '';

        // ['#default_value'] should have differents build
        // function of the widget type.
        switch ($widget_container_type) {

          // Autocomplete.
          case 'autocomplete':
            if ($field_info
              ->getType() == 'entity_reference') {
              $element['target_id'] = $target_id ? sprintf('%s (%s)', $entity
                ->label(), $target_id) : '';

              // Autocomplete tags style.
              if ($element['target_id'] && !empty($widget_container['target_id']['#tags']) && !empty($widget_container['target_id']['#value'])) {
                $element['target_id'] .= ', ' . $widget_container['target_id']['#value'];
              }
            }
            break;

          // Select list.
          case 'select':
            if ($widget_container['#multiple'] == FALSE || !$target_id) {
              $element['target_id'] = $target_id;
            }
            else {
              $element['target_id'] = $widget_container['#value'] + [
                $target_id => $target_id,
              ];
            }
            break;

          // Radios widget.
          case 'radios':
            $element['target_id'] = $target_id;
            break;

          // Checkboxes widget.
          case 'checkboxes':
            $element['target_id'] = $widget_container['#value'];
            if ($target_id) {
              $element['target_id'] += [
                $target_id => $target_id,
              ];
            }
            break;
          default:
            $data = [
              'data' => &$cache_data,
              'widget_container' => $widget_container,
              'widget_container_type' => $widget_container_type,
              'field_info' => $field_info,
              'element_value' => NULL,
            ];
            \Drupal::moduleHandler()
              ->alter('entityconnect_return_form', $data);
            break;
        }
      }

      // This is the input we already got from the old form state.
      $input = $form_state
        ->getUserInput();
      if (isset($element)) {
        static::alterFormStateInput($input, $widget_container_type, $parents, $element['target_id']);
      }
      elseif (!empty($data['element_value'])) {
        static::alterFormStateInput($input, $widget_container_type, $parents, $data['element_value']);
      }

      // Include the alterations from above.
      $form_state
        ->setUserInput($input);
    }

    // Rebuild the form.
    $form_state
      ->setRebuild();

    // The combination of having user input and rebuilding the form means
    // that it will attempt to cache the form state which will fail if it is
    // a GET request.
    $form_state
      ->setRequestMethod('POST');

    // Return processing is complete.
    $form_state
      ->set('#entityconnect_processed', TRUE);
  }
}