entitytype_filter-1.0.x-dev/src/Form/FilterEntityTypesForm.php
src/Form/FilterEntityTypesForm.php
<?php
namespace Drupal\entitytype_filter\Form;
use Drupal\Core\Entity\Element\EntityAutocomplete;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Field\FieldTypePluginManagerInterface;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\field\FieldConfigInterface;
use Drupal\entitytype_filter\EntitySearchService;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Defines a form for entity type selection.
*/
class FilterEntityTypesForm extends FormBase {
/**
* The current user.
*
* @var \Drupal\Core\Session\AccountInterface
*/
protected $account;
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* The field type plugin manager.
*
* @var \Drupal\Core\Field\FieldTypePluginManagerInterface
*/
protected $fieldTypePluginManager;
/**
* The entity field manager.
*
* @var \Drupal\Core\Entity\EntityFieldManagerInterface
*/
protected $entityFieldManager;
/**
* The entity search service.
*
* @var \Drupal\entitytype_filter\EntitySearchService
*/
protected $entitySearchService;
/**
* Constructs a new FilterEntityTypesForm object.
*
* @param \Drupal\Core\Session\AccountInterface $account
* The current user.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager.
* @param \Drupal\Core\Field\FieldTypePluginManagerInterface $field_type_plugin_manager
* The field type plugin manager.
* @param \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager
* The entity field manager.
* @param \Drupal\entitytype_filter\EntitySearchService $entity_search_service
* The entity search service.
*/
public function __construct(AccountInterface $account, EntityTypeManagerInterface $entity_type_manager, FieldTypePluginManagerInterface $field_type_plugin_manager, EntityFieldManagerInterface $entity_field_manager, EntitySearchService $entity_search_service) {
$this->account = $account;
$this->entityTypeManager = $entity_type_manager;
$this->fieldTypePluginManager = $field_type_plugin_manager;
$this->entityFieldManager = $entity_field_manager;
$this->entitySearchService = $entity_search_service;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
// Instantiates this form class.
return new static(
// Load the service required to construct this class.
$container->get('current_user'),
$container->get('entity_type.manager'),
$container->get('plugin.manager.field.field_type'),
$container->get('entity_field.manager'),
$container->get('entitytype_filter.search_service')
);
}
/**
* Form ID of FilterEntityTypesForm.
*/
public function getFormId() {
return 'entitytype_filter_form';
}
/**
* Builds FilterEntityTypesForm.
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$output = [];
$config_types = $this->entitySearchService->getBundleConfigEntityTypes(TRUE);
$options = array_map(fn($item) => $this->t("@label", ['@label' => $item['label']]), $config_types);
if ($form_state->getValue('autocomplete_ajax_container') && $form_state->getValue('autocomplete_ajax_container')['filter_entity_types']) {
$output = $this->getFieldsInfo($form_state);
}
$form['#tree'] = TRUE;
$header = [
'field_label' => $this->t('<b>Field Label</b>'),
'field_type' => $this->t('<b>Field Type</b>'),
];
$form['filter_entity_types_table'] = [
'#type' => 'table',
'#header' => $header,
'#rows' => $output,
'#weight' => '50',
'#empty' => $this->t('No Fields Exists.'),
];
$values = $form_state->getValues();
$ajax_wrapper = 'entity-ajax-wrapper';
$form['select_entity_type'] = [
'#type' => 'select',
'#title' => $this->t('Select Entity Type'),
'#empty_value' => '',
'#empty_option' => '- Select a value -',
'#default_value' => ($values['select_entity_type'] ?? ''),
'#options' => $options,
'#weight' => '-50',
'#ajax' => [
'callback' => [$this, 'selectEntityTypeChange'],
'event' => 'change',
'wrapper' => $ajax_wrapper,
],
'#prefix' => '<div class="custom-wrap">',
'#suffix' => '</div>',
];
$form['autocomplete_ajax_container'] = [
'#type' => 'container',
'#attributes' => [
'id' => $ajax_wrapper,
],
];
if (!empty($values) && !empty($values['select_entity_type'])) {
$config_entity_type = $values['select_entity_type'];
$form['autocomplete_ajax_container']['filter_entity_types'] = [
'#type' => 'textfield',
'#title' => $this->t('Search @selected_entity_type by title', ['@selected_entity_type' => $options[$config_entity_type]]),
'#weight' => '10',
'#maxlength' => 1280,
'#description' => '',
'#autocomplete_route_name' => 'entitytype_filter.autocomplete',
'#autocomplete_route_parameters' => [
'config_entity_type' => $config_entity_type,
],
];
}
$form['actions'] = [
'#type' => 'actions',
'#weight' => '10',
'#prefix' => '<div class="custom-wrap-1">',
'#suffix' => '</div>',
];
$form['actions']['submit'] = [
'#type' => 'submit',
'#value' => $this->t('Search'),
'#attributes' => [
'class' => ['button--primary'],
],
];
$form['#attached']['library'][] = 'entitytype_filter/filter_field';
return $form;
}
/**
* Implements validateForm().
*/
public function validateForm(array &$form, FormStateInterface $form_state) {
}
/**
* Implements submitForm().
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$form_state->setRebuild(TRUE);
}
/**
* Implements selectEntityTypeChange().
*/
public function selectEntityTypeChange(array $form, FormStateInterface $form_state) {
return $form['autocomplete_ajax_container'];
}
/**
* Returns a clickable link to the field UI page for the given entity type.
*/
public function getEntityBasedFieldUrl($entity_type, $entity_name, $field, $title = NULL) {
$label = $title ?? $field->label();
$config_entities = $this->entitySearchService->getBundleConfigEntityTypes(TRUE);
$config_entity_type = NULL;
foreach ($config_entities as $entity_type_id => $data) {
if ($data['bundle_of'] === $entity_type) {
$config_entity_type = $entity_type_id;
break;
}
}
$id = $field->id();
if ($config_entity_type && isset($config_entities[$config_entity_type])) {
$base_path = str_replace('{' . $config_entity_type . '}', $entity_name, $config_entities[$config_entity_type]['path']);
$field_ui_path = "{$base_path}/fields/$id";
return $this->t('<a href=":url" target="_blank">@label</a>', [
':url' => $field_ui_path,
'@label' => $label,
]);
}
return $label;
}
/**
* Get fields data.
*/
protected function getFieldsInfo(FormStateInterface $form_state): array {
$primary_entity_type = $form_state->getValue('select_entity_type');
$entity_type = preg_replace('/_type$/', '', $primary_entity_type);
$entity_name = EntityAutocomplete::extractEntityIdFromAutocompleteInput(
$form_state->getValue('autocomplete_ajax_container')['filter_entity_types']
);
if ($this->entityTypeManager->hasDefinition($primary_entity_type)) {
$definition = $this->entityTypeManager->getDefinition($primary_entity_type);
$bundle_of = $definition->getBundleOf();
$entity_type = $bundle_of . '_type' == $primary_entity_type ? $entity_type : $bundle_of;
}
$fields = array_filter(
$this->entityFieldManager->getFieldDefinitions($entity_type, $entity_name),
function ($fieldDefinition) {
return $fieldDefinition instanceof FieldConfigInterface;
}
);
$field_type_options = $this->entitySearchService->getGroupedFieldTypeOptions();
$output = [];
foreach ($fields as $field) {
$handler = $field->getSetting('handler');
$primary_type = $handler ? explode(':', $handler)[1] : NULL;
$primary_type_label = $primary_type ? ucfirst(str_replace('_', ' ', $primary_type)) : "";
$field_type = $this->entitySearchService->recursiveSearchKeyMap($field->getType(), $field_type_options) ?: $field->getType();
$output[$field->getName()] = [
'field_label' => $this->getEntityBasedFieldUrl($entity_type, $entity_name, $field),
'field_type' => !empty($primary_type_label) ? $primary_type_label : $field_type,
];
}
return $output;
}
}
