feat: Perfis públicos de usuário via view mode 'public'

- Adiciona hook_entity_view_mode_alter() para redirecionar visitantes
  não-proprietários e não-admins para o view mode 'public' ao acessar
  /user/{uid}, exibindo apenas foto padrão, bio e redes sociais
- Simplifica hook_entity_field_access(): operação 'view' retorna neutral
  para não-proprietários (visibilidade controlada pelo view mode)
- Cria update_10005() que provisiona o view mode 'public', seu display
  e concede a permissão 'access user profiles' ao papel anonymous
- Replica a concessão de permissão em hook_install() para novas instalações
- Corrige TypeError em hook_entity_view_mode_alter(): $context aceita null
- Amplia hook_media_access() para permitir visualização de mídia publicada
  também para usuários anônimos

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-25 16:29:41 -03:00
parent 6266b42e0e
commit f58c8f90f4
2 changed files with 89 additions and 7 deletions

View File

@@ -98,9 +98,7 @@ function site_users_check_profile_field_access($operation, AccountInterface $acc
if ($is_own && $account->hasPermission('view own user profile fields')) {
return AccessResult::allowed()->cachePerPermissions()->cachePerUser();
}
if (!$is_own) {
return AccessResult::forbidden()->cachePerPermissions()->cachePerUser();
}
// Visibilidade pública controlada pelo view mode — não bloquear aqui.
return AccessResult::neutral()->cachePerUser();
}
@@ -153,9 +151,7 @@ function site_users_check_photo_field_access($operation, AccountInterface $accou
if ($is_own && $account->hasPermission('view own user profile fields')) {
return AccessResult::allowed()->cachePerPermissions()->cachePerUser();
}
if (!$is_own) {
return AccessResult::forbidden()->cachePerPermissions()->cachePerUser();
}
// Visibilidade pública controlada pelo view mode — não bloquear aqui.
return AccessResult::neutral()->cachePerUser();
}
@@ -332,11 +328,26 @@ function site_users_user_presave(UserInterface $user) {
}
}
/**
* Implements hook_entity_view_mode_alter().
*/
function site_users_entity_view_mode_alter(string &$view_mode, EntityInterface $entity, ?array $context): void {
if ($entity->getEntityTypeId() !== 'user' || $view_mode !== 'full') {
return;
}
$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';
}
}
/**
* Implements hook_ENTITY_TYPE_access() for media entities.
*/
function site_users_media_access(\Drupal\media\MediaInterface $entity, string $operation, AccountInterface $account): AccessResult {
if ($operation === 'view' && $entity->isPublished() && $account->isAuthenticated()) {
if ($operation === 'view' && $entity->isPublished()) {
return AccessResult::allowed()
->cachePerUser()
->addCacheableDependency($entity);