entity_reference_field_create_link-1.x-dev/src/Plugin/Field/FieldWidget/EntityReferenceAutocompleteCreateLink.php
src/Plugin/Field/FieldWidget/EntityReferenceAutocompleteCreateLink.php
<?php
namespace Drupal\entity_reference_field_create_link\Plugin\Field\FieldWidget;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\Plugin\Field\FieldWidget\EntityReferenceAutocompleteWidget;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Link;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Plugin implementation of the 'entity_reference_autocomplete' widget.
*
* @FieldWidget(
* id = "entity_reference_field_create_link",
* label = @Translation("Autocomplete (with create link)"),
* description = @Translation("An autocomplete text field with a link to
* create a new entity."),
* field_types = {
* "entity_reference"
* }
* )
*/
class EntityReferenceAutocompleteCreateLink extends EntityReferenceAutocompleteWidget {
/**
* The entity type manager service.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
$instance = parent::create($container, $configuration, $plugin_id, $plugin_definition);
$instance->entityTypeManager = $container->get('entity_type.manager');
return $instance;
}
/**
* Generates a renderable link to create a new entity.
*
* @param string $routeName
* The name of the route for creating a new entity.
* @param string $routeParameterName
* The parameter name for the route.
* @param \Drupal\Core\Entity\EntityInterface $bundleObject
* The bundle object representing the entity type and bundle.
*
* @return array
* An array representing the renderable link.
*/
private function getAddLink(string $routeName, string $routeParameterName, EntityInterface $bundleObject): array {
return Link::createFromRoute(
$this->t('Create @name', ['@name' => $bundleObject->label()]),
$routeName,
[$routeParameterName => $bundleObject->id()],
[
'attributes' => [
'class' => ['button', 'button--action', 'button--small'],
'target' => '_blank',
],
]
)->toRenderable();
}
/**
* {@inheritdoc}
*/
public function form(FieldItemListInterface $items, array &$form, FormStateInterface $form_state, $get_delta = NULL): array {
$build = parent::form($items, $form, $form_state, $get_delta);
$build['add_links'] = [];
foreach ($this->getSelectionHandlerSetting('target_bundles') as $bundle) {
// There is no universal way to get the add route for a given entity type.
$entityTypeId = $this->getFieldSetting('target_type');
$linkKey = implode('__', [$entityTypeId, $bundle]);
switch ($entityTypeId) {
case 'node':
$build['add_links'][$linkKey] = $this->getAddLink(
'node.add',
'node_type',
$this->entityTypeManager
->getStorage('node_type')
->load($bundle)
);
break;
case 'taxonomy_term':
$build['add_links'][$linkKey] = $this->getAddLink(
'entity.taxonomy_term.add_form',
'taxonomy_vocabulary',
$this->entityTypeManager
->getStorage('taxonomy_vocabulary')
->load($bundle)
);
break;
case 'media':
$build['add_links'][$linkKey] = $this->getAddLink(
'entity.media.add_form',
'media_type',
$this->entityTypeManager
->getStorage('media_type')
->load($bundle)
);
break;
}
}
return $build;
}
}
