mirror of
https://gitlab.unicamp.br/infimecc_drupal11_modules/site_tools.git
synced 2026-05-03 17:00:40 -03:00
Adiciona sub-módulo site_tools_group_helpers
Fornece um plugin EntityReferenceSelection que restringe campos de referência a grupos aos grupos dos quais o usuário atual é membro. Inclui troca automática para o widget options_select ao configurar o handler, e remoção do #required em target_bundles para campos que referenciam group, permitindo deixar o tipo de grupo em branco. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
name: 'Site Tools — Group Helpers'
|
||||
type: module
|
||||
description: 'Utilitários reutilizáveis para integração com o módulo Group.'
|
||||
core_version_requirement: ^10.3 || ^11
|
||||
package: Custom
|
||||
dependencies:
|
||||
- site_tools:site_tools
|
||||
- group:group
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Install hooks for site_tools_group_helpers.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Implements hook_install().
|
||||
*
|
||||
* Applies the options_select widget to any entity_reference field already
|
||||
* configured to use the site_tools_group_helpers selection handler, for
|
||||
* example after a config import followed by module installation.
|
||||
*/
|
||||
function site_tools_group_helpers_install(): void {
|
||||
$field_configs = \Drupal::entityTypeManager()
|
||||
->getStorage('field_config')
|
||||
->loadByProperties(['field_type' => 'entity_reference']);
|
||||
|
||||
foreach ($field_configs as $field_config) {
|
||||
if ($field_config->getSetting('handler') === 'site_tools_group_helpers') {
|
||||
_site_tools_group_helpers_set_widget($field_config, 'options_select', []);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Module hooks for site_tools_group_helpers.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\field\FieldConfigInterface;
|
||||
|
||||
/**
|
||||
* Implements hook_form_FORM_ID_alter() for field_config_edit_form.
|
||||
*
|
||||
* Removes the #required constraint from the target_bundles checkboxes when
|
||||
* the field references the 'group' entity type, allowing the selection to be
|
||||
* left empty (= any group type) regardless of which handler is active.
|
||||
*/
|
||||
function site_tools_group_helpers_form_field_config_edit_form_alter(array &$form, FormStateInterface $form_state): void {
|
||||
$field = $form_state->getFormObject()->getEntity();
|
||||
|
||||
if ($field->getFieldStorageDefinition()->getSetting('target_type') !== 'group') {
|
||||
return;
|
||||
}
|
||||
|
||||
$target_bundles = &$form['settings']['handler']['handler_settings']['target_bundles'] ?? NULL;
|
||||
if ($target_bundles !== NULL) {
|
||||
$target_bundles['#required'] = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_config_update().
|
||||
*
|
||||
* When a field switches to the site_tools_group_helpers selection handler,
|
||||
* automatically updates all its form displays to use the options_select widget.
|
||||
* When it switches away, reverts to entity_reference_autocomplete.
|
||||
*/
|
||||
function site_tools_group_helpers_field_config_update(FieldConfigInterface $field_config): void {
|
||||
$handler = $field_config->getSetting('handler');
|
||||
$original_handler = $field_config->original?->getSetting('handler');
|
||||
|
||||
if ($handler === $original_handler) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($handler === 'site_tools_group_helpers') {
|
||||
_site_tools_group_helpers_set_widget($field_config, 'options_select', []);
|
||||
}
|
||||
elseif ($original_handler === 'site_tools_group_helpers') {
|
||||
_site_tools_group_helpers_set_widget($field_config, 'entity_reference_autocomplete', [
|
||||
'match_operator' => 'CONTAINS',
|
||||
'match_limit' => 10,
|
||||
'size' => 60,
|
||||
'placeholder' => '',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the widget type for a field across all its form displays.
|
||||
*
|
||||
* @param \Drupal\field\FieldConfigInterface $field_config
|
||||
* The field config entity.
|
||||
* @param string $widget_type
|
||||
* The widget plugin ID to apply.
|
||||
* @param array $settings
|
||||
* The widget settings to apply.
|
||||
*/
|
||||
function _site_tools_group_helpers_set_widget(FieldConfigInterface $field_config, string $widget_type, array $settings): void {
|
||||
$entity_type_id = $field_config->getTargetEntityTypeId();
|
||||
$bundle = $field_config->getTargetBundle();
|
||||
$field_name = $field_config->getName();
|
||||
|
||||
$form_displays = \Drupal::entityTypeManager()
|
||||
->getStorage('entity_form_display')
|
||||
->loadByProperties([
|
||||
'targetEntityType' => $entity_type_id,
|
||||
'bundle' => $bundle,
|
||||
]);
|
||||
|
||||
foreach ($form_displays as $form_display) {
|
||||
$component = $form_display->getComponent($field_name);
|
||||
if ($component === NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$form_display->setComponent($field_name, [
|
||||
'type' => $widget_type,
|
||||
'weight' => $component['weight'],
|
||||
'region' => $component['region'] ?? 'content',
|
||||
'settings' => $settings,
|
||||
'third_party_settings' => $component['third_party_settings'] ?? [],
|
||||
]);
|
||||
$form_display->save();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Drupal\site_tools_group_helpers\Plugin\EntityReferenceSelection;
|
||||
|
||||
use Drupal\Core\Entity\Attribute\EntityReferenceSelection;
|
||||
use Drupal\Core\Entity\Plugin\EntityReferenceSelection\DefaultSelection;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\StringTranslation\TranslatableMarkup;
|
||||
use Drupal\group\Entity\GroupMembership;
|
||||
|
||||
/**
|
||||
* Restricts group selection to groups where the current user is a member.
|
||||
*
|
||||
* Use this handler on any entity_reference field that targets the 'group'
|
||||
* entity type when only the groups the current user belongs to should appear
|
||||
* as options. Users with no memberships will see an empty list.
|
||||
*/
|
||||
#[EntityReferenceSelection(
|
||||
id: 'site_tools_group_helpers',
|
||||
label: new TranslatableMarkup('Member groups (current user)'),
|
||||
entity_types: ['group'],
|
||||
group: 'site_tools_group_helpers',
|
||||
weight: 0,
|
||||
)]
|
||||
class MemberGroupSelection extends DefaultSelection {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
|
||||
$form = parent::buildConfigurationForm($form, $form_state);
|
||||
|
||||
// Allow leaving group types empty (= any type), matching the behaviour
|
||||
// of the default selection handler.
|
||||
if (isset($form['target_bundles'])) {
|
||||
$form['target_bundles']['#required'] = FALSE;
|
||||
}
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function buildEntityQuery($match = NULL, $match_operator = 'CONTAINS') {
|
||||
$query = parent::buildEntityQuery($match, $match_operator);
|
||||
|
||||
$memberships = GroupMembership::loadByUser($this->currentUser);
|
||||
|
||||
if (empty($memberships)) {
|
||||
// User has no memberships — return an empty result set.
|
||||
$query->condition('id', 0, '=');
|
||||
return $query;
|
||||
}
|
||||
|
||||
$gids = array_map(fn($m) => $m->getGroupId(), $memberships);
|
||||
$query->condition('id', $gids, 'IN');
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user