og-8.x-1.x-dev/src/Plugin/Field/FieldType/OgStandardReferenceItem.php
src/Plugin/Field/FieldType/OgStandardReferenceItem.php
<?php
declare(strict_types=1);
namespace Drupal\og\Plugin\Field\FieldType;
use Drupal\Component\Utility\Html;
use Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginManagerInterface;
use Drupal\Core\Field\Attribute\FieldType;
use Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\TypedData\ComplexDataDefinitionInterface;
use Drupal\Core\TypedData\TypedDataInterface;
use Drupal\og\Plugin\Field\OgEntityReferenceFieldItemList;
/**
* Field item class for OG membership references.
*/
#[FieldType(
id: 'og_standard_reference',
label: new TranslatableMarkup('OG reference'),
description: new TranslatableMarkup('An entity reference field pointing to the OG group entity, for a non-user entity.'),
category: 'reference',
default_widget: 'options_select',
default_formatter: 'entity_reference_label',
no_ui: TRUE,
list_class: OgEntityReferenceFieldItemList::class,
)]
class OgStandardReferenceItem extends EntityReferenceItem {
/**
* Selection plugin manager.
*/
protected SelectionPluginManagerInterface $selectionPluginManager;
public function __construct(
ComplexDataDefinitionInterface $definition,
$name,
?TypedDataInterface $parent,
?SelectionPluginManagerInterface $selectionPluginManager = NULL,
) {
parent::__construct($definition, $name, $parent);
// If the field item is instantiated without DI (e.g. by TypedData),
// resolve the selection‑plugin manager from the container so the item
// still works.
$this->selectionPluginManager = $selectionPluginManager
?? \Drupal::service('plugin.manager.entity_reference_selection');
}
/**
* {@inheritdoc}
*/
public function fieldSettingsForm(array $form, FormStateInterface $form_state) {
$field = $form_state->getFormObject()->getEntity();
// Get all selection plugins for this entity type.
$selection_plugins = $this->selectionPluginManager->getSelectionGroups($this->getSetting('target_type'));
$handlers_options = [];
foreach (array_keys($selection_plugins) as $selection_group_id) {
if ($selection_group_id == 'og') {
// Handle the og selection group.
$selection_group_plugin = 'og:default';
$handlers_options[$selection_group_plugin] = Html::escape((string) $selection_plugins[$selection_group_id][$selection_group_plugin]['label']);
}
}
$form = [
'#type' => 'container',
'#process' => [[static::class, 'fieldSettingsAjaxProcess']],
'#element_validate' => [[static::class, 'fieldSettingsFormValidate']],
];
$form['handler'] = [
'#type' => 'details',
'#title' => $this->t('Reference type'),
'#open' => TRUE,
'#tree' => TRUE,
'#process' => [[static::class, 'formProcessMergeParent']],
];
$form['handler']['handler'] = [
'#type' => 'select',
'#title' => $this->t('Reference method'),
'#options' => $handlers_options,
'#default_value' => $field->getSetting('handler'),
'#required' => TRUE,
// Use a form process callback to build #ajax property properly and also
// to avoid code duplication.
// @see \Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem::fieldSettingsAjaxProcess()
'#ajax' => TRUE,
'#limit_validation_errors' => [],
];
$form['handler']['handler_submit'] = [
'#type' => 'submit',
'#name' => 'handler_settings_submit',
'#value' => $this->t('Change handler'),
'#limit_validation_errors' => [],
'#attributes' => [
'class' => ['js-hide'],
],
'#submit' => [[static::class, 'settingsAjaxSubmit']],
];
$form['handler']['handler_settings'] = [
'#type' => 'container',
'#attributes' => ['class' => ['entity_reference-settings']],
];
$field->setSetting('handler', 'og:default');
$handler = $this->selectionPluginManager->getSelectionHandler($field);
$form['handler']['handler_settings'] += $handler->buildConfigurationForm([], $form_state);
return $form;
}
}
