You are here

public function WebformEntityReferenceWidgetTrait::formElement in Webform 6.x

Same name and namespace in other branches
  1. 8.5 src/Plugin/Field/FieldWidget/WebformEntityReferenceWidgetTrait.php \Drupal\webform\Plugin\Field\FieldWidget\WebformEntityReferenceWidgetTrait::formElement()

File

src/Plugin/Field/FieldWidget/WebformEntityReferenceWidgetTrait.php, line 115

Class

WebformEntityReferenceWidgetTrait
Trait for webform entity reference and autocomplete widget.

Namespace

Drupal\webform\Plugin\Field\FieldWidget

Code

public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {

  // Set item default status to open.
  if (!isset($items[$delta]->status)) {
    $items[$delta]->status = WebformInterface::STATUS_OPEN;
  }

  // Get field name.
  $field_name = $items
    ->getName();

  // Get field input name from field parents, field name, and the delta.
  $field_parents = array_merge($element['#field_parents'], [
    $field_name,
    $delta,
  ]);
  $field_input_name = array_shift($field_parents) . ('[' . implode('][', $field_parents) . ']');

  // Get target ID element.
  $target_id_element = $this
    ->getTargetIdElement($items, $delta, $element, $form, $form_state);

  // Determine if this is a paragraph.
  $is_paragraph = $items
    ->getEntity()
    ->getEntityTypeId() === 'paragraph';

  // Merge target ID and default element and set default #weight.
  // @see \Drupal\Core\Field\Plugin\Field\FieldWidget\EntityReferenceAutocompleteWidget::formElement
  $element = [
    'target_id' => $target_id_element + $element + [
      '#weight' => 0,
    ],
  ];

  // Get weight.
  $weight = $element['target_id']['#weight'];

  // Get webform.
  $target_id = NULL;
  if ($form_state
    ->isRebuilding()) {
    $target_id = $form_state
      ->getValue(array_merge($element['target_id']['#field_parents'], [
      $field_name,
      $delta,
      'target_id',
    ]));
  }
  else {
    $target_id = $items[$delta]->target_id;
  }

  /** @var \Drupal\webform\WebformInterface $webform */
  $webform = $target_id ? Webform::load($target_id) : NULL;
  $element['settings'] = [
    '#type' => 'details',
    '#title' => $this
      ->t('@title settings', [
      '@title' => $element['target_id']['#title'],
    ]),
    '#element_validate' => [
      [
        $this,
        'validateOpenClose',
      ],
    ],
    '#open' => $items[$delta]->target_id ? TRUE : FALSE,
    '#weight' => $weight++,
  ];

  // Disable a warning message about the webform's state using Ajax.
  $is_webform_closed = $webform && $webform
    ->isClosed();
  if ($is_webform_closed) {
    $t_args = [
      '%webform' => $webform
        ->label(),
      ':href' => $webform
        ->toUrl('settings-form')
        ->toString(),
    ];
    if ($webform
      ->access('update')) {
      $message = $this
        ->t('The %webform webform is <a href=":href">closed</a>. The below status will be ignored.', $t_args);
    }
    else {
      $message = $this
        ->t('The %webform webform is <strong>closed</strong>. The below status will be ignored.', $t_args);
    }
    $element['settings']['status_message'] = [
      '#type' => 'webform_message',
      '#message_type' => 'warning',
      '#message_message' => $message,
    ];
  }
  else {

    // Render empty element so that Ajax wrapper is embedded in the page.
    $element['settings']['status_message'] = [];
  }
  $ajax_id = 'webform-entity-reference-' . $field_name . '-' . $delta;
  $this
    ->buildAjaxElementTrigger($ajax_id, $element['target_id']);
  $this
    ->buildAjaxElementUpdate($ajax_id, $element);
  $this
    ->buildAjaxElementWrapper($ajax_id, $element['settings']['status_message']);
  $element['settings']['status'] = [
    '#type' => 'radios',
    '#title' => $this
      ->t('Status'),
    '#description' => $this
      ->t('The open, closed, or scheduled status applies to only this webform instance.'),
    '#options' => [
      WebformInterface::STATUS_OPEN => $this
        ->t('Open'),
      WebformInterface::STATUS_CLOSED => $this
        ->t('Closed'),
      WebformInterface::STATUS_SCHEDULED => $this
        ->t('Scheduled'),
    ],
    '#options_display' => 'side_by_side',
    '#default_value' => $items[$delta]->status,
  ];
  $element['settings']['scheduled'] = [
    '#type' => 'item',
    '#title' => $element['target_id']['#title'],
    '#title_display' => 'invisible',
    '#input' => FALSE,
    '#states' => [
      'visible' => [
        'input[name="' . $field_input_name . '[settings][status]"]' => [
          'value' => WebformInterface::STATUS_SCHEDULED,
        ],
      ],
    ],
  ];
  $element['settings']['scheduled']['open'] = [
    '#type' => 'datetime',
    '#title' => $this
      ->t('Open'),
    '#default_value' => $items[$delta]->open ? DrupalDateTime::createFromTimestamp(strtotime($items[$delta]->open)) : NULL,
    '#prefix' => '<div class="container-inline form-item">',
    '#suffix' => '</div>',
    '#help' => FALSE,
    '#description' => [
      '#type' => 'webform_help',
      '#help' => $this
        ->t('If the open date/time is left blank, this form will immediately be opened.'),
      '#help_title' => $this
        ->t('Open'),
    ],
  ];
  $element['settings']['scheduled']['close'] = [
    '#type' => 'datetime',
    '#title' => $this
      ->t('Close'),
    '#default_value' => $items[$delta]->close ? DrupalDateTime::createFromTimestamp(strtotime($items[$delta]->close)) : NULL,
    '#prefix' => '<div class="container-inline form-item">',
    '#suffix' => '</div>',
    '#help' => FALSE,
    '#description' => [
      '#type' => 'webform_help',
      '#help' => $this
        ->t('If the close date/time is left blank, this webform will never be closed.'),
      '#help_title' => $this
        ->t('Close'),
    ],
  ];
  if ($this
    ->getSetting('default_data')) {

    /** @var \Drupal\webform\WebformTokenManagerInterface $token_manager */
    $token_manager = \Drupal::service('webform.token_manager');
    $token_types = [
      'webform',
      'webform_submission',
    ];

    // Get title, description, and code example.
    // @see \Drupal\webform\Plugin\Block\WebformBlock::blockForm
    $title = $this
      ->t('Default submission data (YAML)');
    $placeholder = $this
      ->t("Enter 'name': 'value' pairs…");
    $description = [
      'content' => [
        '#markup' => $this
          ->t('Enter submission data as name and value pairs as <a href=":href">YAML</a> which will be used to prepopulate the selected webform.', [
          ':href' => 'https://en.wikipedia.org/wiki/YAML',
        ]),
        '#suffix' => ' ',
      ],
      'token' => $token_manager
        ->buildTreeLink(),
    ];
    $default_data_example = [];
    $default_data_example[] = '# ' . $this
      ->t('This is an example of a comment.');
    $default_data_example[] = "element_key: 'some value'";
    $default_data_example[] = '';
    $default_data_example[] = '# ' . $this
      ->t("The below example uses a token to get the current node's title.");
    $default_data_example[] = "title: '[webform_submission:node:title:clear]'";
    $default_data_example[] = '';
    $default_data_example[] = '# ' . $this
      ->t("Add ':clear' to the end token to return an empty value when the token is missing.");
    $default_data_example[] = '# ' . $this
      ->t('The below example uses a token to get a field value from the current node.');
    $default_data_example[] = "full_name: '[webform_submission:node:field_full_name:clear]'";
    if ($is_paragraph) {
      $token_types[] = 'paragraph';
      $default_data_example[] = '';
      $default_data_example[] = '# ' . $this
        ->t('You can also use paragraphs tokens.');
      $default_data_example[] = "some_value: '[paragraph:some_value:clear]";
    }
    $element['settings']['default_data'] = [
      '#type' => 'webform_codemirror',
      '#mode' => 'yaml',
      '#title' => $title,
      '#description' => $description,
      '#placeholder' => $placeholder,
      '#default_value' => $items[$delta]->default_data,
      '#webform_element' => TRUE,
      '#more_title' => $this
        ->t('Example'),
      '#more' => [
        '#theme' => 'webform_codemirror',
        '#type' => 'yaml',
        '#code' => implode(PHP_EOL, $default_data_example),
      ],
    ];
    $token_manager
      ->elementValidate($element['settings']['default_data'], $token_types);
  }
  else {

    // Preserve default data set by variants passed via the URL.
    // @see webform_node_node_prepare_form().
    $element['settings']['default_data'] = [
      '#type' => 'value',
      '#value' => $items[$delta]->default_data,
    ];
  }
  return $element;
}