You are here

public function WebformEntityReferenceWidgetTrait::formElement in Webform 8.5

Same name and namespace in other branches
  1. 6.x 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',
    ];
    $default_data_example = "# This is an example of a comment.\nelement_key: 'some value'\n\n# The below example uses a token to get the current node's title.\n# Add ':clear' to the end token to return an empty value when the token is missing.\ntitle: '[webform_submission:node:title:clear]'\n# The below example uses a token to get a field value from the current node.\nfull_name: '[webform_submission:node:field_full_name:clear]";
    if ($is_paragraph) {
      $token_types[] = 'paragraph';
      $default_data_example .= PHP_EOL . "# You can also use paragraphs tokens.\nsome_value: '[paragraph:some_value:clear]";
    }
    $element['settings']['default_data'] = [
      '#type' => 'webform_codemirror',
      '#mode' => 'yaml',
      '#title' => $this
        ->t('Default submission data (YAML)'),
      '#placeholder' => $this
        ->t("Enter 'name': 'value' pairs…"),
      '#default_value' => $items[$delta]->default_data,
      '#webform_element' => TRUE,
      '#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($token_types),
      ],
      '#more_title' => $this
        ->t('Example'),
      '#more' => [
        '#theme' => 'webform_codemirror',
        '#type' => 'yaml',
        '#code' => $default_data_example,
      ],
    ];
    $element['settings']['token_tree_link'] = $token_manager
      ->buildTreeElement($token_types);
    $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;
}