Files
site_users/src/Form/SiteUsersSettingsForm.php
Quintino A. G. Souza c464ae035d fix: Grava false para campos protegidos ao salvar configurações
Campos que retornam forbidden() em fieldAccess() são gravados como
false no submitForm(), evitando que um valor true residual persista
quando um campo passa a ser protegido por outro módulo. Inclui também
o nome do campo no label no formato [módulo:field_name].

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 10:00:56 -03:00

173 lines
5.4 KiB
PHP

<?php
namespace Drupal\site_users\Form;
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\field\FieldConfigInterface;
/**
* Formulário de configuração do módulo Site Users.
*/
class SiteUsersSettingsForm extends ConfigFormBase {
/**
* Returns all configurable user fields, discovered dynamically.
*
* @return array
* Associative array of field_name => label.
*/
protected function getEditableFields(): array {
$definitions = \Drupal::service('entity_field.manager')
->getFieldDefinitions('user', 'user');
$fields = [];
foreach ($definitions as $field_name => $definition) {
if ($definition instanceof FieldConfigInterface) {
$provider = $this->getFieldStorageProvider($field_name);
$fields[$field_name] = $this->t('@label [@module:@field]', [
'@label' => $definition->getLabel(),
'@module' => $provider,
'@field' => $field_name,
]);
}
}
ksort($fields);
return $fields;
}
/**
* Finds which module provides the field storage config file.
*
* @param string $field_name
* The field name.
*
* @return string
* The module name, or 'unknown' if not found.
*/
protected function getFieldStorageProvider(string $field_name): string {
$config_file = 'field.storage.user.' . $field_name . '.yml';
$module_handler = \Drupal::moduleHandler();
$root = \Drupal::root();
foreach ($module_handler->getModuleList() as $module_name => $module) {
foreach (['config/install', 'config/optional'] as $dir) {
if (file_exists($root . '/' . $module->getPath() . '/' . $dir . '/' . $config_file)) {
return $module_name;
}
}
}
return 'unknown';
}
/**
* {@inheritdoc}
*/
public function getFormId() {
return 'site_users_settings_form';
}
/**
* {@inheritdoc}
*/
protected function getEditableConfigNames() {
return ['site_users.settings'];
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$config = $this->config('site_users.settings');
// Fieldset para configurações de fotos.
$form['photos'] = [
'#type' => 'fieldset',
'#title' => $this->t('Photo settings'),
'#collapsible' => FALSE,
];
$form['photos']['photos_max_count'] = [
'#type' => 'number',
'#title' => $this->t('Number of photos allowed'),
'#description' => $this->t('Maximum number of photos a user can add to the profile.'),
'#default_value' => $config->get('photos.max_count') ?? 5,
'#min' => 1,
'#max' => 100,
'#required' => TRUE,
];
$form['photos']['photos_ldap_attribute'] = [
'#type' => 'textfield',
'#title' => $this->t('LDAP photo attribute'),
'#description' => $this->t('If LDAP is enabled, enter the name of the attribute that contains the user photo (e.g., thumbnailPhoto, jpegPhoto).'),
'#default_value' => $config->get('photos.ldap_attribute') ?? 'jpegPhoto',
'#maxlength' => 255,
];
// Fieldset para campos editáveis pelo próprio usuário.
$form['user_editable_fields'] = [
'#type' => 'fieldset',
'#title' => $this->t('User-editable profile fields'),
'#description' => $this->t('Select which fields users can edit on their own profile. Fields protected by other modules remain non-editable regardless of this setting.'),
'#tree' => TRUE,
];
$definitions = \Drupal::service('entity_field.manager')
->getFieldDefinitions('user', 'user');
$access_handler = \Drupal::entityTypeManager()
->getAccessControlHandler('user');
foreach ($this->getEditableFields() as $field_name => $label) {
$is_protected = $access_handler
->fieldAccess('edit', $definitions[$field_name], NULL, NULL, TRUE)
->isForbidden();
$form['user_editable_fields'][$field_name] = [
'#type' => 'checkbox',
'#title' => $label,
'#default_value' => $config->get('user_editable_fields.' . $field_name) ?? TRUE,
'#disabled' => $is_protected,
'#description' => $is_protected ? $this->t('Protected by another module.') : '',
];
}
return parent::buildForm($form, $form_state);
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$config = $this->config('site_users.settings');
$config
->set('photos.max_count', $form_state->getValue('photos_max_count'))
->set('photos.ldap_attribute', $form_state->getValue('photos_ldap_attribute'));
$definitions = \Drupal::service('entity_field.manager')
->getFieldDefinitions('user', 'user');
$access_handler = \Drupal::entityTypeManager()
->getAccessControlHandler('user');
$editable = $form_state->getValue('user_editable_fields');
foreach (array_keys($this->getEditableFields()) as $field_name) {
$is_protected = $access_handler
->fieldAccess('edit', $definitions[$field_name], NULL, NULL, TRUE)
->isForbidden();
if ($is_protected) {
// Campos protegidos por outros módulos são sempre não-editáveis.
$config->set('user_editable_fields.' . $field_name, FALSE);
}
elseif (isset($editable[$field_name])) {
$config->set('user_editable_fields.' . $field_name, (bool) $editable[$field_name]);
}
}
$config->save();
parent::submitForm($form, $form_state);
}
}