View source
<?php
namespace Drupal\oembed_providers;
use Drupal\Component\Utility\UrlHelper;
use Drupal\Core\Entity\EntityForm;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Messenger\MessengerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
class OembedProviderForm extends EntityForm {
protected $entityTypeManager;
protected $messenger;
public function __construct(EntityTypeManagerInterface $entityTypeManager, MessengerInterface $messenger) {
$this->entityTypeManager = $entityTypeManager;
$this->messenger = $messenger;
}
public static function create(ContainerInterface $container) {
return new static($container
->get('entity_type.manager'), $container
->get('messenger'));
}
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/',
]),
'#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>',
];
$endpoint_add = $form_state
->get('endpoint_add');
$endpoint_remove = $form_state
->get('endpoint_remove');
$endpoints = $entity
->get('endpoints') ? $entity
->get('endpoints') : [];
$endpoint_indices = [];
foreach ($endpoints as $endpoint_id => $endpoint_value) {
if ($endpoint_id === 'actions') {
unset($endpoints['actions']);
}
else {
if (is_numeric($endpoint_id)) {
$endpoint_indices[] = $endpoint_id + 1;
}
else {
$parts = explode('-', $endpoint_id);
$endpoint_indices[] = $parts[1];
}
}
}
$endpoint_count = count($endpoints);
if ($endpoint_count == 0) {
$endpoint_count = 1;
$endpoint_indices[] = 1;
}
if ($endpoint_add) {
$endpoint_count++;
}
for ($i = 0; $i < $endpoint_count; $i++) {
$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/*'),
'#default_value' => isset($endpoints[$i]['schemes']) ? implode(PHP_EOL, $endpoints[$i]['schemes']) : '',
'#required' => TRUE,
];
$form['endpoints']['endpoint-' . $num]['url'] = [
'#type' => 'url',
'#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'),
],
];
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;
}
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,
];
}
}
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;
$form_state
->set('endpoint_add', NULL);
$form_state
->set('endpoint_remove', NULL);
return parent::form($form, $form_state);
}
public function ajaxCallback(array &$form, FormStateInterface $form_state) {
return $form['endpoints'];
}
public function addCallback(array &$form, FormStateInterface $form_state) {
$form_state
->set('endpoint_add', TRUE);
$form_state
->setRebuild();
}
public function removeCallback(array &$form, FormStateInterface $form_state) {
$trigger = $form_state
->getTriggeringElement();
$form_state
->set('endpoint_remove', $trigger['#parents'][1]);
$form_state
->setRebuild();
}
public function validateForm(array &$form, FormStateInterface $form_state) {
$trigger = $form_state
->getTriggeringElement();
if (in_array('remove_endpoint', $trigger['#parents']) || in_array('add_endpoint', $trigger['#parents'])) {
$form_state
->clearErrors();
return;
}
parent::validateForm($form, $form_state);
$values = $form_state
->getValues();
unset($values['endpoints']['actions']);
foreach ($values['endpoints'] as $endpoint_id => $endpoint_value) {
$schemes = preg_split('/\\R/', $endpoint_value['schemes']);
foreach ($schemes as $key => $scheme) {
if (!UrlHelper::isValid($scheme, TRUE)) {
$form_state
->setError($form['endpoints'][$endpoint_id]['schemes'], $this
->t('A valid URL is required on line @line.', [
'@line' => $key + 1,
]));
}
}
if (empty($endpoint_value['discovery']) && empty($endpoint_value['formats']['json']) && empty($endpoint_value['formats']['xml'])) {
$form_state
->setError($form['endpoints'][$endpoint_id]['formats'], $this
->t('If discovery is disabled, then one or more formats must be explicitly defined for an endpoint.'));
}
}
}
public function save(array $form, FormStateInterface $form_state) {
$entity = $this->entity;
$endpoints = $entity
->get('endpoints');
unset($endpoints['actions']);
$endpoints_indexed_array = [];
foreach ($endpoints as $value) {
unset($value['actions']);
$value['schemes'] = preg_split('/\\R/', $value['schemes']);
$value['discovery'] = (bool) $value['discovery'];
$value['formats']['json'] = (bool) $value['formats']['json'];
$value['formats']['xml'] = (bool) $value['formats']['xml'];
$endpoints_indexed_array[] = $value;
}
$entity
->set('endpoints', $endpoints_indexed_array);
$status = $entity
->save();
if ($status === SAVED_NEW) {
$this
->messenger()
->addMessage($this
->t('The %label oEmbed provider was created.', [
'%label' => $entity
->label(),
]));
}
else {
$this
->messenger()
->addMessage($this
->t('The %label oEmbed provider was updated.', [
'%label' => $entity
->label(),
]));
}
$form_state
->setRedirect('entity.oembed_provider.collection');
}
public function exist($id) {
if ($id == 'add') {
return TRUE;
}
$entity = $this->entityTypeManager
->getStorage('oembed_provider')
->getQuery()
->condition('id', $id)
->execute();
return (bool) $entity;
}
}