data_pipelines-1.x-dev/src/Form/DestinationForm.php
src/Form/DestinationForm.php
<?php
namespace Drupal\data_pipelines\Form;
use Drupal\Core\Entity\EntityForm;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Form\SubformState;
use Drupal\Core\Messenger\MessengerInterface;
use Drupal\data_pipelines\Destination\DatasetDestinationPluginManager;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Provides a form for adding/editing destinations.
*/
class DestinationForm extends EntityForm {
/**
* The destination storage.
*
* @var \Drupal\Core\Entity\EntityStorageInterface
*/
protected $storage;
/**
* The destination plugin manager.
*
* @var \Drupal\data_pipelines\Destination\DatasetDestinationPluginManager
*/
protected $destinationPluginManager;
/**
* Constructs a new action form.
*
* @param \Drupal\Core\Entity\EntityStorageInterface $storage
* The action storage.
* @param \Drupal\data_pipelines\Destination\DatasetDestinationPluginManager $destinationPluginManager
* The destination plugin manager.
* @param \Drupal\Core\Messenger\MessengerInterface $messenger
* The messenger service.
*/
final public function __construct(EntityStorageInterface $storage, DatasetDestinationPluginManager $destinationPluginManager, MessengerInterface $messenger) {
$this->storage = $storage;
$this->destinationPluginManager = $destinationPluginManager;
$this->messenger = $messenger;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('entity_type.manager')->getStorage('dataset_destination'),
$container->get('plugin.manager.data_pipelines_destination'),
$container->get('messenger')
);
}
/**
* {@inheritdoc}
*/
public function form(array $form, FormStateInterface $form_state): array {
parent::form($form, $form_state);
/** @var \Drupal\data_pipelines\Entity\DestinationInterface $destination */
$destination = $this->entity;
$form['label'] = [
'#type' => 'textfield',
'#title' => $this->t('Label'),
'#default_value' => $this->entity->label(),
'#maxlength' => '255',
'#description' => $this->t('The label for this destination.'),
];
$form['id'] = [
'#type' => 'machine_name',
'#default_value' => $this->entity->id(),
'#disabled' => !$this->entity->isNew(),
'#maxlength' => 64,
'#description' => $this->t('A unique name for this destination. It must only contain lowercase letters, numbers and underscores.'),
'#machine_name' => [
'exists' => [$this, 'exists'],
],
];
$destinationAjax = [
'callback' => [$this, 'updateDestinationForm'],
'wrapper' => 'plugin-settings-destination',
'effect' => 'fade',
'method' => 'replaceWith',
];
$form['update_destination_plugin'] = [
'#type' => 'submit',
'#value' => $this->t('Update destination plugin'),
'#limit_validation_errors' => [['destination']],
'#attributes' => [
'class' => ['visually-hidden'],
],
'#submit' => ['::rebuildForm'],
'#ajax' => $destinationAjax,
];
$destinationPluginId = $form_state->getValue('destination', $destination->getDestinationPluginId() ?: NULL);
$destinationPlugin = $destination->getDestinationPlugin() ?: NULL;
if ($destinationPluginId && !$destinationPlugin) {
$destinationPlugin = $this->destinationPluginManager->createInstance($destinationPluginId);
}
$form['destination'] = [
'#type' => 'radios',
'#title' => $this->t('Destination'),
'#description' => $this->t('Select the destination type.'),
'#default_value' => $destinationPluginId,
'#required' => TRUE,
'#options' => array_map(function (array $plugin) {
return $plugin['label'];
}, $this->destinationPluginManager->getDefinitions()),
'#ajax' => $destinationAjax + [
'trigger_as' => [
'name' => 'op',
'value' => 'Update destination plugin',
],
],
];
$form['destinationSettings'] = [
'#prefix' => '<div id="plugin-settings-destination">',
'#suffix' => '</div>',
'#tree' => TRUE,
'#type' => 'details',
'#open' => TRUE,
'#title' => $this->t('Destination settings'),
'__none' => [
'#markup' => $this->t('There are no settings for the selected option.'),
],
];
if ($destinationPlugin && $destinationPlugin->hasFormClass('configure')) {
$subform_state = SubformState::createForSubform($form['destinationSettings'], $form, $form_state);
$settings_form = $destinationPlugin->buildConfigurationForm($form['destinationSettings'], $subform_state);
if ($settings_form) {
$form['destinationSettings'] += $settings_form;
unset($form['destinationSettings']['__none']);
}
}
return $form;
}
/**
* Submission handler.
*/
public function rebuildForm(array $form, FormStateInterface $form_state) {
$form_state->cleanValues();
$this->entity = $this->buildEntity($form, $form_state);
$form_state->setRebuild(TRUE);
}
/**
* Ajax callback.
*/
public function updateDestinationForm(array $form, FormStateInterface $form_state) {
$build = $form['destinationSettings'] ?? [];
$build['messages'] = [
'#type' => 'status_messages',
'#weight' => -100,
];
return $build;
}
/**
* Determines if the destination already exists.
*
* @param string $id
* The destination ID.
*
* @return bool
* TRUE if the destination exists, FALSE otherwise.
*/
public function exists($id) {
$destination_id = $this->storage->load($id);
return !empty($destination_id);
}
/**
* {@inheritdoc}
*/
public function validateForm(array &$form, FormStateInterface $form_state) {
/** @var \Drupal\data_pipelines\Entity\DestinationInterface $destination */
$destination = $this->entity;
if (($deploy_plugin = $destination->getDestinationPlugin()) && $deploy_plugin->hasFormClass('configure') && isset($form['destinationSettings'])) {
$subform_state = SubformState::createForSubform($form['destinationSettings'], $form, $form_state);
$deploy_plugin->validateConfigurationForm($form['destinationSettings'], $subform_state);
}
parent::validateForm($form, $form_state);
}
/**
* {@inheritdoc}
*/
public function save(array $form, FormStateInterface $form_state) {
/** @var \Drupal\data_pipelines\Entity\DestinationInterface $destination */
$destination = $this->entity;
if (($destinationPlugin = $destination->getDestinationPlugin()) && $destinationPlugin->hasFormClass('configure') && isset($form['destinationSettings'])) {
$subform_state = SubformState::createForSubform($form['destinationSettings'], $form, $form_state);
$destinationPlugin->submitConfigurationForm($form['destinationSettings'], $subform_state);
}
$status = $destination->save();
switch ($status) {
case SAVED_NEW:
$this->messenger->addStatus($this->t('Created the %label Destination.', [
'%label' => $destination->label(),
]));
break;
default:
$this->messenger->addStatus($this->t('Saved the %label Destination.', [
'%label' => $destination->label(),
]));
}
$form_state->setRedirectUrl($destination->toUrl('collection'));
return $status;
}
}
