You are here

public function OembedProviderForm::form in oEmbed Providers 1.1.x

Same name and namespace in other branches
  1. 2.x src/OembedProviderForm.php \Drupal\oembed_providers\OembedProviderForm::form()
  2. 1.0.x src/OembedProviderForm.php \Drupal\oembed_providers\OembedProviderForm::form()

Overrides Drupal\Core\Entity\EntityForm::form().

Parameters

array $form: A nested array form elements comprising the form.

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

Return value

array The array containing the complete form.

Overrides EntityForm::form

File

src/OembedProviderForm.php, line 65

Class

OembedProviderForm
Form controller for the oEmbed provider edit/add forms.

Namespace

Drupal\oembed_providers

Code

public function form(array $form, FormStateInterface $form_state) {
  if ($this->operation == 'edit') {
    $form['#title'] = $this
      ->t('<em>Edit oEmbed provider</em> @label', [
      '@label' => $this->entity
        ->label(),
    ]);
  }
  $entity = $this->entity;
  $form['doc_markup'] = [
    '#markup' => $this
      ->t('For documentation regarding oEmbed provider definitions, see <a href="@url">oEmbed.com</a>', [
      '@url' => 'https://oembed.com/',
    ]),
    // Simulate warning message.
    '#prefix' => '<div role="contentinfo" aria-label="Warning message" class="messages messages--warning">',
    '#suffix' => '</div>',
  ];
  $form['label'] = [
    '#type' => 'textfield',
    '#title' => $this
      ->t('Provider name'),
    '#default_value' => $entity
      ->label(),
    '#required' => TRUE,
  ];
  $form['id'] = [
    '#type' => 'machine_name',
    '#default_value' => $entity
      ->id(),
    '#machine_name' => [
      'exists' => [
        $this,
        'exist',
      ],
    ],
    '#disabled' => !$entity
      ->isNew(),
  ];
  $form['provider_url'] = [
    '#type' => 'url',
    '#title' => $this
      ->t('Provider URL'),
    '#default_value' => $entity
      ->get('provider_url'),
    '#required' => TRUE,
  ];
  $form['endpoints'] = [
    '#type' => 'fieldset',
    '#title' => $this
      ->t('Endpoints'),
    '#prefix' => '<div id="endpoints-wrapper">',
    '#suffix' => '</div>',
  ];

  // Set add/remove variables if form is being reloaded by an AJAX action.
  $endpoint_add = $form_state
    ->get('endpoint_add');
  $endpoint_remove = $form_state
    ->get('endpoint_remove');

  // Get endpoints.
  $endpoints = $entity
    ->get('endpoints') ? $entity
    ->get('endpoints') : [];

  // An array to stores index keys for endpoints.
  $endpoint_indices = [];

  // Loop through endpoints.
  foreach ($endpoints as $endpoint_id => $endpoint_value) {

    // Remove 'actions' array; it's not an endpoint.
    if ($endpoint_id === 'actions') {
      unset($endpoints['actions']);
    }
    else {

      // If original form load (e.g. not AJAX), then array keys are indexed
      // and can be used outright.
      if (is_numeric($endpoint_id)) {

        // Start endpoint count at 1, not 0.
        $endpoint_indices[] = $endpoint_id + 1;
      }
      else {

        // Add existing key to indexed array.
        $parts = explode('-', $endpoint_id);
        $endpoint_indices[] = $parts[1];
      }
    }
  }
  $endpoint_count = count($endpoints);

  // If there are no endpoints yet, then set default values.
  if ($endpoint_count == 0) {
    $endpoint_count = 1;
    $endpoint_indices[] = 1;
  }

  // If an endpoint is being added, increment the endpoint count.
  if ($endpoint_add) {
    $endpoint_count++;
  }
  for ($i = 0; $i < $endpoint_count; $i++) {

    // Use existing endpoint index keys when generating form array.
    // If an index doesn't exist, then add 1 to the last index key value.
    $num = isset($endpoint_indices[$i]) ? $endpoint_indices[$i] : $endpoint_indices[$i - 1] + 1;
    $form['endpoints']['endpoint-' . $num] = [
      '#type' => 'fieldset',
      '#title' => $this
        ->t('Endpoint #@num', [
        '@num' => $num,
      ]),
      '#prefix' => '<div id="endpoint-' . $num . '">',
      '#suffix' => '</div>',
    ];
    $form['endpoints']['endpoint-' . $num]['schemes'] = [
      '#type' => 'textarea',
      '#title' => $this
        ->t('Endpoint schemes'),
      '#description' => $this
        ->t('URLs from a provider that may have an embedded representation (each scheme is entered on a new line)<br>E.g. http://custom-provider.example.com/id/*<br>https://custom-provider.example.com/id/*'),
      // Convert indexed array to a string of values, delimited by a new line.
      '#default_value' => isset($endpoints[$i]['schemes']) ? implode(PHP_EOL, $endpoints[$i]['schemes']) : '',
      '#required' => TRUE,
    ];
    $form['endpoints']['endpoint-' . $num]['url'] = [
      // Use 'textfield' instead of 'url' to avoid validation issues with the
      // `{format}` string, which is supported by core Media.
      // See Drupal\media\OEmbed\Endpoint::__construct().
      '#type' => 'textfield',
      '#title' => $this
        ->t('Endpoint URL'),
      '#description' => $this
        ->t('A URL where the consumer can request representations for scheme URLs<br>E.g. https://custom-provider.example.com/api/v2/oembed/'),
      '#default_value' => isset($endpoints[$i]['url']) ? $endpoints[$i]['url'] : '',
      '#required' => TRUE,
    ];
    $form['endpoints']['endpoint-' . $num]['discovery'] = [
      '#type' => 'checkbox',
      '#title' => $this
        ->t('Discovery'),
      '#description' => $this
        ->t('Whether or not a provider supports discoverability of supported formats'),
      '#default_value' => isset($endpoints[$i]['discovery']) ? (int) $endpoints[$i]['discovery'] : 0,
    ];
    $form['endpoints']['endpoint-' . $num]['formats'] = [
      '#type' => 'checkboxes',
      '#title' => $this
        ->t('Available formats'),
      '#description' => $this
        ->t('Formats explicitly supported by the provider'),
      '#options' => [
        'json' => $this
          ->t('JSON'),
        'xml' => $this
          ->t('XML'),
      ],
    ];

    // Convert checkboxes values from boolean to expected FAPI values
    // for default value.
    if (isset($endpoints[$i]['formats'])) {
      $formats_default_value = [];
      foreach ($endpoints[$i]['formats'] as $format => $format_value) {
        if ($format_value == TRUE) {
          $formats_default_value[$format] = $format;
        }
        elseif ($format_value == FALSE) {
          $formats_default_value[$format] = 0;
        }
      }
      $form['endpoints']['endpoint-' . $num]['formats']['#default_value'] = $formats_default_value;
    }

    // Only provide remove button if either 1) there is more than one
    // endpoint and no endpoints are being removed or 2) there are more than
    // two endpoints and an endpoint is being removed. The last endpoint
    // cannot be removed.
    if ($endpoint_count > 1 && !$endpoint_remove || $endpoint_count > 2 && $endpoint_remove) {
      $form['endpoints']['endpoint-' . $num]['actions']['remove_endpoint'] = [
        '#type' => 'submit',
        '#value' => $this
          ->t('Remove endpoint'),
        '#submit' => [
          '::removeCallback',
        ],
        '#ajax' => [
          'callback' => '::ajaxCallback',
          'wrapper' => 'endpoints-wrapper',
        ],
        '#name' => 'remove-endpoint' . $num,
      ];
    }
  }

  // Only after entire form is build should any removed endpoint be removed.
  if ($endpoint_remove) {
    unset($form['endpoints'][$endpoint_remove]);
  }
  $form['endpoints']['actions'] = [
    '#type' => 'actions',
  ];
  $form['endpoints']['actions']['add_endpoint'] = [
    '#type' => 'submit',
    '#value' => $this
      ->t('Add an endpoint'),
    '#submit' => [
      '::addCallback',
    ],
    '#ajax' => [
      'callback' => '::ajaxCallback',
      'wrapper' => 'endpoints-wrapper',
    ],
    '#button_type' => 'default',
    '#name' => 'add-endpoint',
  ];
  $form['#tree'] = TRUE;

  // Reset AJAX variables.
  $form_state
    ->set('endpoint_add', NULL);
  $form_state
    ->set('endpoint_remove', NULL);
  return parent::form($form, $form_state);
}