external_entity-1.0.x-dev/src/Form/ExternalEntityResourceDisplayForm.php
src/Form/ExternalEntityResourceDisplayForm.php
<?php
declare(strict_types=1);
namespace Drupal\external_entity\Form;
use Drupal\Core\Form\SubformState;
use Drupal\Core\Form\FormStateInterface;
use Drupal\external_entity\AjaxFormTrait;
use Drupal\Core\Plugin\PluginFormInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\external_entity\Contracts\ExternalEntityRenderTypeInterface;
use Drupal\external_entity\Contracts\ExternalEntityRenderTypeManagerInterface;
/**
* Define the external entity resource display form.
*/
class ExternalEntityResourceDisplayForm extends ExternalEntityTypeAwareEntityForm {
use AjaxFormTrait;
/**
* @var \Drupal\external_entity\Contracts\ExternalEntityRenderTypeManagerInterface
*/
protected $renderTypeManager;
/**
* External entity type default form constructor.
*/
public function __construct(
ExternalEntityRenderTypeManagerInterface $render_type_manager,
) {
$this->renderTypeManager = $render_type_manager;
}
/**
* {@inheritDoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('plugin.manager.external_entity.render_type')
);
}
/**
* {@inheritDoc}
*/
public function form(
array $form,
FormStateInterface $form_state,
): array {
/** @var \Drupal\external_entity\Entity\ExternalEntityResourceDisplay $entity */
$entity = $this->entity;
$form['#parents'] = [];
$form['#prefix'] = '<div id="external-entity-resource-display">';
$form['#suffix'] = '</div>';
$resource = $this->getFormStateValue(
'resource',
$form_state,
$entity->getResource()
);
$form['resource'] = [
'#type' => 'select',
'#title' => $this->t('Resource'),
'#required' => TRUE,
'#description' => $this->t('Select the resource for this display.'),
'#default_value' => $resource,
'#options' => $this->getResourceOptions('resources'),
'#empty_option' => $this->t('- Select -'),
'#depth' => 1,
'#ajax' => [
'event' => 'change',
'method' => 'replaceWith',
'wrapper' => 'external-entity-resource-display',
'callback' => [$this, 'ajaxFormDepthCallback'],
],
];
if (isset($resource) && !empty($resource)) {
$variation = $this->getFormStateValue(
'variation',
$form_state,
$entity->getVariation()
);
$form['variation'] = [
'#type' => 'select',
'#title' => $this->t('Resource Variation'),
'#required' => TRUE,
'#description' => $this->t('Select the resource variation for this display.'),
'#default_value' => $variation,
'#options' => $this->getResourceOptions('variations')[$resource] ?? [],
'#empty_option' => $this->t('- Select -'),
'#depth' => 1,
'#ajax' => [
'event' => 'change',
'method' => 'replaceWith',
'wrapper' => 'external-entity-resource-display',
'callback' => [$this, 'ajaxFormDepthCallback'],
],
];
if (isset($variation) && !empty($variation)) {
$render_wrapper_id = 'external-entity-type-render';
$form['render'] = [
'#type' => 'details',
'#title' => $this->t('Entity Render'),
'#description' => $this->t('
Configure how the external entity should be rendered.'
),
'#tree' => TRUE,
'#open' => TRUE,
'#attributes' => [
'id' => $render_wrapper_id,
],
];
$render_type_id = $this->getFormStateValue(
['render', 'type'],
$form_state,
$entity->getRenderType()
);
$render_type_options = $this->getRenderTypeOptions();
$form['render']['type'] = [
'#type' => 'select',
'#title' => $this->t('Render Type'),
'#description' => $this->t('Select the external entity render type.'),
'#options' => $render_type_options,
'#empty_option' => $this->t('- Select -'),
'#required' => TRUE,
'#default_value' => $render_type_id,
'#depth' => 1,
'#ajax' => [
'event' => 'change',
'method' => 'replaceWith',
'wrapper' => $render_wrapper_id,
'callback' => [$this, 'ajaxFormDepthCallback'],
],
];
if (
isset($render_type_id, $render_type_options[$render_type_id])
&& $this->renderTypeManager->hasDefinition($render_type_id)
) {
$instance = $this->renderTypeManager->createInstance(
$render_type_id,
$entity->getRenderSettings()
);
$form['render']['settings'] = [
'#type' => 'container',
'#tree' => TRUE,
];
if ($instance instanceof PluginFormInterface) {
$subform = [
'#parents' => ['render', 'settings'],
];
if ($instance instanceof ExternalEntityRenderTypeInterface) {
$instance->setExternalEntityDisplay($entity);
}
$form['render']['settings'] += $instance->buildConfigurationForm(
$subform,
SubformState::createForSubform($subform, $form, $form_state)
);
}
}
}
}
return parent::form($form, $form_state);
}
/**
* {@inheritDoc}
*/
public function validateForm(
array &$form,
FormStateInterface $form_state,
): void {
parent::validateForm($form, $form_state);
/** @var \Drupal\external_entity\Entity\ExternalEntityResourceDisplay $entity */
$entity = $this->entity;
if ($entity->isNew() && $entity->exists()) {
$form_state->setError(
$form,
$this->t('A display has already been defined for this resource using this variation.')
);
}
}
/**
* Get external entity resource options.
*
* @param string|null $section
* The option section name.
*
* @return array
* If the section is provided, then only the section options are returned. If
* section is omitted then all options are returned, which are keyed by the section.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
protected function getResourceOptions(?string $section = NULL): array {
/** @var \Drupal\external_entity\Entity\ExternalEntityResourceDisplay $entity */
$entity = $this->entity;
if (!isset($entity)) {
return [];
}
$options = $entity->externalEntityType()
->getResourceOptions();
return $options[$section] ?? $options;
}
/**
* {@inheritDoc}
*/
public function save(
array $form,
FormStateInterface $form_state,
): int {
/** @var \Drupal\external_entity\Entity\ExternalEntityResourceDisplay $entity */
$entity = $this->entity;
$status = parent::save($form, $form_state);
$form_state->setRedirectUrl($entity->toUrl('collection'));
return $status;
}
/**
* @return array
*/
protected function getRenderTypeOptions(): array {
return $this->renderTypeManager->getDefinitionOptions();
}
}
