mirror of
https://gitlab.unicamp.br/infimecc_drupal11_modules/site_users.git
synced 2026-03-10 02:07:41 -03:00
feat: View mode por role/usuário com seletor de visibilidade no perfil
- Cria view mode e display 'restricted' (template mostra só username + mensagem) - Adiciona campo field_user_selected_view_mode (string, default: restricted) - update_10006: provisiona view mode, display e campo; inicializa role_view_modes - Seletor de visibilidade no form de edição do perfil (owner e admin) - hook_entity_view_mode_alter lê o campo e valida existência do display - Formulário de admin: checkboxes de view modes por role (exceto anonymous e authenticated) - Schema YAML completo para site_users.settings incluindo role_view_modes - Tradução pt-BR de todas as novas strings Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -28,6 +28,10 @@ function site_users_theme($existing, $type, $theme, $path) {
|
||||
'template' => 'user--full',
|
||||
'base hook' => 'user',
|
||||
],
|
||||
'user__restricted' => [
|
||||
'template' => 'user--restricted',
|
||||
'base hook' => 'user',
|
||||
],
|
||||
'site_users_info_block' => [
|
||||
'template' => 'site-user-info-block',
|
||||
'variables' => [
|
||||
@@ -184,6 +188,131 @@ function site_users_form_user_form_alter(&$form, FormStateInterface $form_state,
|
||||
$form['#validate'][] = 'site_users_validate_photos_count';
|
||||
_site_users_add_default_photo_selector($form, $form_state);
|
||||
}
|
||||
_site_users_add_visibility_selector($form, $form_state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adiciona o seletor de visibilidade do perfil ao formulário de usuário.
|
||||
*/
|
||||
function _site_users_add_visibility_selector(&$form, FormStateInterface $form_state) {
|
||||
/** @var \Drupal\user\UserInterface $user */
|
||||
$user = $form_state->getFormObject()->getEntity();
|
||||
$current_user = \Drupal::currentUser();
|
||||
|
||||
$is_own = (int) $user->id() === (int) $current_user->id();
|
||||
$is_admin = $current_user->hasPermission('administer users');
|
||||
|
||||
if (!$is_own && !$is_admin) {
|
||||
return;
|
||||
}
|
||||
|
||||
$options = _site_users_get_allowed_view_modes($user);
|
||||
|
||||
// Always include 'restricted'.
|
||||
$options = ['restricted' => t('Restricted (username only)')] + $options;
|
||||
|
||||
$current_value = 'restricted';
|
||||
if ($user->hasField('field_user_selected_view_mode') && !$user->get('field_user_selected_view_mode')->isEmpty()) {
|
||||
$current_value = $user->get('field_user_selected_view_mode')->value;
|
||||
}
|
||||
// Fallback to restricted if stored value is no longer allowed.
|
||||
if (!isset($options[$current_value])) {
|
||||
$current_value = 'restricted';
|
||||
}
|
||||
|
||||
$form['profile_visibility'] = [
|
||||
'#type' => 'fieldset',
|
||||
'#title' => t('Profile visibility'),
|
||||
'#weight' => 20,
|
||||
];
|
||||
|
||||
$form['profile_visibility']['profile_view_mode'] = [
|
||||
'#type' => 'radios',
|
||||
'#title' => t('How should my profile appear to other visitors?'),
|
||||
'#description' => t('Choose the information displayed on your public profile page.'),
|
||||
'#options' => $options,
|
||||
'#default_value' => $current_value,
|
||||
];
|
||||
|
||||
// Prepend validate handler.
|
||||
array_unshift($form['#validate'], '_site_users_validate_visibility_selector');
|
||||
|
||||
// Prepend submit handler before the default submit.
|
||||
array_unshift($form['actions']['submit']['#submit'], '_site_users_presave_visibility_selector');
|
||||
}
|
||||
|
||||
/**
|
||||
* Retorna os view modes permitidos para os roles do usuário.
|
||||
*
|
||||
* @param \Drupal\user\UserInterface $user
|
||||
* O usuário cujo perfil está sendo editado.
|
||||
*
|
||||
* @return array
|
||||
* Associative array of machine_name => label.
|
||||
*/
|
||||
function _site_users_get_allowed_view_modes(UserInterface $user): array {
|
||||
$config = \Drupal::config('site_users.settings');
|
||||
$role_view_modes = $config->get('role_view_modes') ?? [];
|
||||
|
||||
$allowed = [];
|
||||
foreach ($user->getRoles() as $role_id) {
|
||||
if (!empty($role_view_modes[$role_id]) && is_array($role_view_modes[$role_id])) {
|
||||
foreach ($role_view_modes[$role_id] as $vm) {
|
||||
$allowed[$vm] = $vm;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($allowed)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// Load labels for the allowed view modes.
|
||||
$view_mode_storage = \Drupal::entityTypeManager()->getStorage('entity_view_mode');
|
||||
$options = [];
|
||||
foreach (array_keys($allowed) as $machine_name) {
|
||||
$view_mode = $view_mode_storage->load('user.' . $machine_name);
|
||||
$options[$machine_name] = $view_mode ? $view_mode->label() : $machine_name;
|
||||
}
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate handler: confirma que o valor escolhido está na lista permitida.
|
||||
*/
|
||||
function _site_users_validate_visibility_selector(&$form, FormStateInterface $form_state) {
|
||||
$chosen = $form_state->getValue('profile_view_mode');
|
||||
if ($chosen === NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
/** @var \Drupal\user\UserInterface $user */
|
||||
$user = $form_state->getFormObject()->getEntity();
|
||||
$allowed = _site_users_get_allowed_view_modes($user);
|
||||
$allowed['restricted'] = 'restricted';
|
||||
|
||||
if (!isset($allowed[$chosen])) {
|
||||
$form_state->setErrorByName('profile_view_mode', t('Invalid profile visibility option selected.'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit handler (prepended): seta field_user_selected_view_mode no entity antes do save.
|
||||
*/
|
||||
function _site_users_presave_visibility_selector(&$form, FormStateInterface $form_state) {
|
||||
$chosen = $form_state->getValue('profile_view_mode');
|
||||
if ($chosen === NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
/** @var \Drupal\user\UserInterface $user */
|
||||
$user = $form_state->getFormObject()->getEntity();
|
||||
|
||||
if ($user->hasField('field_user_selected_view_mode')) {
|
||||
$user->set('field_user_selected_view_mode', $chosen);
|
||||
// Do not save here — the standard submit handler saves the entity.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -338,9 +467,31 @@ function site_users_entity_view_mode_alter(string &$view_mode, EntityInterface $
|
||||
$current_user = \Drupal::currentUser();
|
||||
$is_own = (int) $entity->id() === (int) $current_user->id();
|
||||
$is_admin = $current_user->hasPermission('administer users');
|
||||
if (!$is_own && !$is_admin) {
|
||||
$view_mode = 'public';
|
||||
|
||||
if ($is_own || $is_admin) {
|
||||
// Owner and admin always see the full view mode.
|
||||
return;
|
||||
}
|
||||
|
||||
// Read the chosen view mode from the profile being visited.
|
||||
$chosen = 'restricted';
|
||||
if ($entity instanceof UserInterface
|
||||
&& $entity->hasField('field_user_selected_view_mode')
|
||||
&& !$entity->get('field_user_selected_view_mode')->isEmpty()
|
||||
) {
|
||||
$chosen = $entity->get('field_user_selected_view_mode')->value;
|
||||
}
|
||||
|
||||
// Validate that a view display exists for the chosen value.
|
||||
if ($chosen !== 'restricted') {
|
||||
$display_id = 'user.user.' . $chosen;
|
||||
$display_storage = \Drupal::entityTypeManager()->getStorage('entity_view_display');
|
||||
if (!$display_storage->load($display_id)) {
|
||||
$chosen = 'restricted';
|
||||
}
|
||||
}
|
||||
|
||||
$view_mode = $chosen;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user