datafield-1.x-dev/src/Plugin/DataField/FieldWidget/PathWidget.php
src/Plugin/DataField/FieldWidget/PathWidget.php
<?php
namespace Drupal\datafield\Plugin\DataField\FieldWidget;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\EntityTypeRepositoryInterface;
use Drupal\Core\Field\Attribute\FieldWidget;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\Url;
use Drupal\datafield\Plugin\DataFieldWidgetInterface;
use Drupal\link\LinkItemInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Validator\ConstraintViolationInterface;
/**
* Plugin implementation of the 'path' widget.
*/
#[FieldWidget(
id: 'path',
label: new TranslatableMarkup('URL alias'),
field_types: ['uri'],
)]
class PathWidget implements DataFieldWidgetInterface, ContainerFactoryPluginInterface {
use StringTranslationTrait;
/**
* Constructs a EntityReferenceAutocompleteWidget object.
*
* @param string $plugin_id
* The plugin_id for the formatter.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param mixed $field_definition
* The plugin implementation definition.
* @param \Drupal\Core\Entity\EntityTypeRepositoryInterface $entityTypeRepository
* Entity type repository service.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
* The entity type manager service.
*/
public function __construct($plugin_id, $plugin_definition, $field_definition, protected EntityTypeRepositoryInterface $entityTypeRepository, protected readonly EntityTypeManagerInterface $entityTypeManager) {
unset($plugin_id, $plugin_definition, $field_definition);
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, $configuration, $plugin_id, $plugin_definition) {
return new static(
$plugin_id,
$plugin_definition,
$configuration,
$container->get('entity_type.repository'),
$container->get('entity_type.manager'),
);
}
/**
* {@inheritdoc}
*/
public static function defaultSettings() {
return [
'target_type' => 'node',
];
}
/**
* {@inheritdoc}
*/
public function getFormElement(&$element, $item = NULL, $setting = []) {
$element['#type'] = 'entity_autocomplete';
$element['#target_type'] = $element["#widget_settings"]["target_type"] ?? self::defaultSettings()['target_type'];
$element['#attributes']['data-autocomplete-first-character-blacklist'] = '/#?';
$element['#attributes']['placeholder'] = $this->t('Search content');
$element['#link_type'] = LinkItemInterface::LINK_GENERIC;
$element['#process_default_value'] = FALSE;
if (str_starts_with($element['#default_value'], '/')) {
$temp = explode('/', $element['#default_value']);
$element['#default_value'] = end($temp);
if (!is_numeric($element['#default_value'])) {
$url = Url::fromUri('internal:' . $item->getValue()[$setting["name"]]);
if ($url->isRouted()) {
$params = $url->getRouteParameters();
$entity_type = key($params);
$element['#default_value'] = $params[$entity_type];
}
}
}
if (is_numeric($element['#default_value'])) {
$entity = $this->entityTypeManager->getStorage($element['#target_type'])
->load($element['#default_value']);
$label = $entity->label();
$element['#default_value'] = $label . ' (' . $element['#default_value'] . ')';
}
}
/**
* {@inheritdoc}
*/
public function errorElement(array $element, ConstraintViolationInterface $violation, array $form, FormStateInterface $form_state) {
$path = explode('.', $violation->getPropertyPath());
$subfield = end($path);
if (!empty($element[$subfield])) {
$settings = $element[$subfield]['#field_settings'];
if (!empty($settings['list'])) {
return FALSE;
}
}
if (!empty($element[$subfield]['#value'])) {
$pattern = '/\((\d+)\)/';
$matches = [];
preg_match_all($pattern, $element[$subfield]['#value'], $matches);
if (!empty($matches[1])) {
$last = end($matches[1]);
if (is_numeric($last)) {
return FALSE;
}
}
}
return $element;
}
/**
* {@inheritdoc}
*/
public function settingsForm(array $form, FormStateInterface $form_state) {
$widget_settings = $form['#settings'];
$repository = $this->entityTypeRepository->getEntityTypeLabels(TRUE);
$contentType = !empty($repository) ? current($repository) : [];
return [
'target_type' => [
'#type' => 'select',
'#title' => $this->t('Entity reference type'),
'#options' => $contentType,
'#empty_option' => $this->t('- Select a field type -'),
'#default_value' => $widget_settings['target_type'] ?? self::defaultSettings()['target_type'],
],
];
}
/**
* {@inheritdoc}
*/
public function massageFormValues($value, array $form, FormStateInterface $form_state) {
if (!empty($value) && is_numeric($value) && !empty($form["#widget_settings"]["target_type"])) {
$entity = $this->entityTypeManager->getStorage($form["#widget_settings"]["target_type"])
->load($value);
if (method_exists($entity, 'toUrl')) {
$value = $entity->toUrl()->toString();
}
}
return $value;
}
}
