mirror of
https://gitlab.unicamp.br/infimecc_drupal11_modules/site_users.git
synced 2026-03-08 01:17:41 -03:00
- Altera langcode de pt-br para en em todos os field.field YAMLs - Traduz labels e descriptions dos campos para inglês - Converte strings de info.yml, permissions.yml, links.menu.yml e routing.yml para inglês - Converte todas as strings t() e @Translation em PHP para inglês - Adiciona traduções de config em config/translations/pt-br/ para os 7 campos de usuário - Adiciona arquivo translations/site_users.pt-br.po com todas as strings de interface traduzidas para pt-br Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
351 lines
11 KiB
Plaintext
351 lines
11 KiB
Plaintext
<?php
|
|
|
|
/**
|
|
* @file
|
|
* Módulo Site Users - customizações de usuários do site.
|
|
*/
|
|
|
|
use Drupal\Core\Access\AccessResult;
|
|
use Drupal\Core\Entity\EntityInterface;
|
|
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
|
|
use Drupal\Core\Field\FieldDefinitionInterface;
|
|
use Drupal\Core\Field\FieldItemListInterface;
|
|
use Drupal\Core\Form\FormStateInterface;
|
|
use Drupal\Core\Session\AccountInterface;
|
|
use Drupal\media\MediaInterface;
|
|
use Drupal\user\UserInterface;
|
|
|
|
/**
|
|
* Implements hook_theme().
|
|
*/
|
|
function site_users_theme($existing, $type, $theme, $path) {
|
|
return [
|
|
'user__full' => [
|
|
'template' => 'user--full',
|
|
'base hook' => 'user',
|
|
],
|
|
'site_users_info_block' => [
|
|
'template' => 'site-user-info-block',
|
|
'variables' => [
|
|
'user_info' => [],
|
|
'user' => NULL,
|
|
],
|
|
],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Implements hook_theme_suggestions_HOOK_alter() for user templates.
|
|
*/
|
|
function site_users_theme_suggestions_user_alter(array &$suggestions, array $variables) {
|
|
$view_mode = $variables['elements']['#view_mode'] ?? 'default';
|
|
$suggestions[] = 'user__' . $view_mode;
|
|
}
|
|
|
|
/**
|
|
* Implements hook_entity_field_access().
|
|
*/
|
|
function site_users_entity_field_access($operation, FieldDefinitionInterface $field_definition, AccountInterface $account, ?FieldItemListInterface $items = NULL) {
|
|
// Apenas para entidade user.
|
|
if ($field_definition->getTargetEntityTypeId() !== 'user') {
|
|
return AccessResult::neutral();
|
|
}
|
|
|
|
// Lista de campos controlados pelo módulo.
|
|
$profile_fields = [
|
|
'field_user_name',
|
|
'field_user_phone',
|
|
'field_user_category',
|
|
'field_user_dept_code',
|
|
'field_user_bio',
|
|
];
|
|
|
|
$photo_fields = [
|
|
'field_user_photos',
|
|
'field_user_default_photo',
|
|
];
|
|
$field_name = $field_definition->getName();
|
|
|
|
// Verificar se é um campo de perfil.
|
|
if (in_array($field_name, $profile_fields)) {
|
|
return site_users_check_profile_field_access($operation, $account, $items);
|
|
}
|
|
|
|
// Verificar se é um campo de fotos.
|
|
if (in_array($field_name, $photo_fields)) {
|
|
return site_users_check_photo_field_access($operation, $account, $items);
|
|
}
|
|
|
|
return AccessResult::neutral();
|
|
}
|
|
|
|
/**
|
|
* Verifica acesso aos campos de perfil.
|
|
*/
|
|
function site_users_check_profile_field_access($operation, AccountInterface $account, ?FieldItemListInterface $items = NULL) {
|
|
// Administradores têm acesso total.
|
|
if ($account->hasPermission('administer site_users settings')) {
|
|
return AccessResult::allowed()->cachePerPermissions();
|
|
}
|
|
|
|
// Determinar se é o próprio usuário.
|
|
$is_own = FALSE;
|
|
if ($items) {
|
|
$entity = $items->getEntity();
|
|
$is_own = ($entity->id() == $account->id());
|
|
}
|
|
|
|
if ($operation === 'view') {
|
|
// Pode ver qualquer perfil.
|
|
if ($account->hasPermission('view any user profile fields')) {
|
|
return AccessResult::allowed()->cachePerPermissions();
|
|
}
|
|
// Pode ver apenas o próprio perfil.
|
|
if ($is_own && $account->hasPermission('view own user profile fields')) {
|
|
return AccessResult::allowed()->cachePerPermissions()->cachePerUser();
|
|
}
|
|
return AccessResult::forbidden()->cachePerPermissions()->cachePerUser();
|
|
}
|
|
|
|
if ($operation === 'edit') {
|
|
// Pode editar qualquer perfil.
|
|
if ($account->hasPermission('edit any user profile fields')) {
|
|
return AccessResult::allowed()->cachePerPermissions();
|
|
}
|
|
// Pode editar apenas o próprio perfil.
|
|
if ($is_own && $account->hasPermission('edit own user profile fields')) {
|
|
return AccessResult::allowed()->cachePerPermissions()->cachePerUser();
|
|
}
|
|
return AccessResult::forbidden()->cachePerPermissions()->cachePerUser();
|
|
}
|
|
|
|
return AccessResult::neutral();
|
|
}
|
|
|
|
/**
|
|
* Verifica acesso ao campo de fotos.
|
|
*/
|
|
function site_users_check_photo_field_access($operation, AccountInterface $account, ?FieldItemListInterface $items = NULL) {
|
|
// Administradores têm acesso total.
|
|
if ($account->hasPermission('administer site_users settings')) {
|
|
return AccessResult::allowed()->cachePerPermissions();
|
|
}
|
|
|
|
// Determinar se é o próprio usuário.
|
|
$is_own = FALSE;
|
|
if ($items) {
|
|
$entity = $items->getEntity();
|
|
$is_own = ($entity->id() == $account->id());
|
|
}
|
|
|
|
if ($operation === 'view') {
|
|
// Fotos seguem a mesma regra dos campos de perfil para visualização.
|
|
if ($account->hasPermission('view any user profile fields')) {
|
|
return AccessResult::allowed()->cachePerPermissions();
|
|
}
|
|
if ($is_own && $account->hasPermission('view own user profile fields')) {
|
|
return AccessResult::allowed()->cachePerPermissions()->cachePerUser();
|
|
}
|
|
return AccessResult::forbidden()->cachePerPermissions()->cachePerUser();
|
|
}
|
|
|
|
if ($operation === 'edit') {
|
|
// Pode gerenciar fotos de qualquer usuário.
|
|
if ($account->hasPermission('manage user photos')) {
|
|
return AccessResult::allowed()->cachePerPermissions();
|
|
}
|
|
// Pode gerenciar apenas as próprias fotos.
|
|
if ($is_own && $account->hasPermission('manage own user photos')) {
|
|
return AccessResult::allowed()->cachePerPermissions()->cachePerUser();
|
|
}
|
|
return AccessResult::forbidden()->cachePerPermissions()->cachePerUser();
|
|
}
|
|
|
|
return AccessResult::neutral();
|
|
}
|
|
|
|
/**
|
|
* Implements hook_form_FORM_ID_alter() for user_form.
|
|
*/
|
|
function site_users_form_user_form_alter(&$form, FormStateInterface $form_state, $form_id) {
|
|
if (isset($form['field_user_photos'])) {
|
|
$form['#validate'][] = 'site_users_validate_photos_count';
|
|
_site_users_add_default_photo_selector($form, $form_state);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Implements hook_form_FORM_ID_alter() for user_register_form.
|
|
*/
|
|
function site_users_form_user_register_form_alter(&$form, FormStateInterface $form_state, $form_id) {
|
|
if (isset($form['field_user_photos'])) {
|
|
$form['#validate'][] = 'site_users_validate_photos_count';
|
|
_site_users_add_default_photo_selector($form, $form_state);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Adiciona o seletor de foto padrão ao formulário.
|
|
*/
|
|
function _site_users_add_default_photo_selector(&$form, FormStateInterface $form_state) {
|
|
/** @var \Drupal\user\UserInterface $user */
|
|
$user = $form_state->getFormObject()->getEntity();
|
|
|
|
// Obter fotos atuais do usuário.
|
|
$photos = [];
|
|
if ($user->hasField('field_user_photos') && !$user->get('field_user_photos')->isEmpty()) {
|
|
foreach ($user->get('field_user_photos')->referencedEntities() as $media) {
|
|
if ($media instanceof MediaInterface) {
|
|
$photos[$media->id()] = $media->label();
|
|
}
|
|
}
|
|
}
|
|
|
|
// Obter foto padrão atual.
|
|
$default_photo_id = NULL;
|
|
if ($user->hasField('field_user_default_photo') && !$user->get('field_user_default_photo')->isEmpty()) {
|
|
$default_photo_id = $user->get('field_user_default_photo')->target_id;
|
|
}
|
|
|
|
// Adicionar seletor de foto padrão após o campo de fotos.
|
|
$form['default_photo_selector'] = [
|
|
'#type' => 'container',
|
|
'#weight' => $form['field_user_photos']['#weight'] + 0.5 ?? 15,
|
|
'#states' => [
|
|
'visible' => [
|
|
':input[name="field_user_photos[selection]"]' => ['filled' => TRUE],
|
|
],
|
|
],
|
|
];
|
|
|
|
if (!empty($photos)) {
|
|
$form['default_photo_selector']['field_user_default_photo_select'] = [
|
|
'#type' => 'radios',
|
|
'#title' => t('Default photo'),
|
|
'#description' => t('Select the main profile photo.'),
|
|
'#options' => $photos,
|
|
'#default_value' => $default_photo_id,
|
|
];
|
|
}
|
|
else {
|
|
$form['default_photo_selector']['field_user_default_photo_select'] = [
|
|
'#type' => 'item',
|
|
'#title' => t('Default photo'),
|
|
'#markup' => t('Add photos to select one as default.'),
|
|
];
|
|
}
|
|
|
|
// Adicionar submit handler para salvar a foto padrão.
|
|
$form['actions']['submit']['#submit'][] = '_site_users_save_default_photo';
|
|
}
|
|
|
|
/**
|
|
* Submit handler para salvar a foto padrão selecionada.
|
|
*/
|
|
function _site_users_save_default_photo(&$form, FormStateInterface $form_state) {
|
|
$selected_photo = $form_state->getValue('field_user_default_photo_select');
|
|
|
|
/** @var \Drupal\user\UserInterface $user */
|
|
$user = $form_state->getFormObject()->getEntity();
|
|
|
|
if ($user->hasField('field_user_default_photo')) {
|
|
$user->set('field_user_default_photo', $selected_photo);
|
|
$user->save();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Validação customizada para quantidade máxima de fotos.
|
|
*/
|
|
function site_users_validate_photos_count(&$form, FormStateInterface $form_state) {
|
|
$photos = $form_state->getValue('field_user_photos');
|
|
|
|
if (empty($photos)) {
|
|
return;
|
|
}
|
|
|
|
// Contar fotos selecionadas (ignorar valores vazios).
|
|
$count = 0;
|
|
foreach ($photos as $delta => $photo) {
|
|
if (is_numeric($delta) && !empty($photo['target_id'])) {
|
|
$count++;
|
|
}
|
|
}
|
|
|
|
// Obter limite configurado.
|
|
$config = \Drupal::config('site_users.settings');
|
|
$max_count = $config->get('photos.max_count') ?? 5;
|
|
|
|
if ($count > $max_count) {
|
|
$form_state->setErrorByName('field_user_photos', t('You can add a maximum of @max photos. Currently @count photos are selected.', [
|
|
'@max' => $max_count,
|
|
'@count' => $count,
|
|
]));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Implements hook_ENTITY_TYPE_presave() for user entities.
|
|
*/
|
|
function site_users_user_presave(UserInterface $user) {
|
|
// Garantir consistência da foto padrão.
|
|
if (!$user->hasField('field_user_photos') || !$user->hasField('field_user_default_photo')) {
|
|
return;
|
|
}
|
|
|
|
// Obter IDs das fotos atuais.
|
|
$photo_ids = [];
|
|
foreach ($user->get('field_user_photos')->getValue() as $item) {
|
|
if (!empty($item['target_id'])) {
|
|
$photo_ids[] = $item['target_id'];
|
|
}
|
|
}
|
|
|
|
// Obter foto padrão atual.
|
|
$default_photo_id = $user->get('field_user_default_photo')->target_id;
|
|
|
|
// Se não há fotos, limpar foto padrão.
|
|
if (empty($photo_ids)) {
|
|
$user->set('field_user_default_photo', NULL);
|
|
return;
|
|
}
|
|
|
|
// Se a foto padrão não está entre as fotos, selecionar a primeira.
|
|
if (empty($default_photo_id) || !in_array($default_photo_id, $photo_ids)) {
|
|
$user->set('field_user_default_photo', $photo_ids[0]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Obtém a foto padrão de um usuário.
|
|
*
|
|
* @param \Drupal\user\UserInterface $user
|
|
* O usuário.
|
|
*
|
|
* @return \Drupal\media\MediaInterface|null
|
|
* A entidade de mídia da foto padrão, ou NULL se não houver.
|
|
*/
|
|
function site_users_get_default_photo(UserInterface $user): ?MediaInterface {
|
|
if (!$user->hasField('field_user_default_photo') || !$user->hasField('field_user_photos')) {
|
|
return NULL;
|
|
}
|
|
|
|
// Tentar obter a foto padrão configurada.
|
|
if (!$user->get('field_user_default_photo')->isEmpty()) {
|
|
$default_photo = $user->get('field_user_default_photo')->entity;
|
|
if ($default_photo instanceof MediaInterface) {
|
|
return $default_photo;
|
|
}
|
|
}
|
|
|
|
// Fallback: retornar a primeira foto disponível.
|
|
if (!$user->get('field_user_photos')->isEmpty()) {
|
|
$first_photo = $user->get('field_user_photos')->first()->entity;
|
|
if ($first_photo instanceof MediaInterface) {
|
|
return $first_photo;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|