mirror of
https://gitlab.unicamp.br/infimecc_drupal11_modules/site_users.git
synced 2026-05-03 21:20:42 -03:00
Melhorias no microsite e sincronização de fotos LDAP
Fotos LDAP:
- Ignora sync quando conta ainda não tem UID (evitava URI compartilhada)
- Filtra fotos abaixo do tamanho mínimo configurável (padrão 10 KB)
- Adiciona campo ldap_min_photo_size nas configurações e schema
- Update 10010: remove fotos placeholder já existentes
- Update 10011: remove mídias com URI ldap_photo_.{ext} sem UID
Bloco de cabeçalho do microsite:
- Exibe departamento abaixo do nome, sem label, com link para a entidade
- Exibe telefone de trabalho (work_phone) no lugar de phone (restrito)
Página de perfil:
- Título fixo "Perfil de @name" via callback profileTitle()
- Exclui rota profile da substituição de título pelo nó homepage
Subpáginas com URL amigável:
- Adiciona MicrositeSubpagePathProcessor (inbound + outbound)
- Inbound: /user/{username}/{subpage} → /user/{uid}/{subpage}
- Outbound: /user/{uid}/{subpage} → /user/{username}/{subpage}
- Busca alias em todos os idiomas para contornar limitação do AliasManager
Tema do microsite em rotas externas:
- MicrositeThemeNegotiator cobre rotas com parâmetro user sob /user/{user}/
- Cobre nós do structural_pages cujo alias começa com /user/{uid}/
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -194,6 +194,79 @@ function site_users_install() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove mídias LDAP geradas sem UID (URI ldap_photo_.jpg/png) de todos os
|
||||
* usuários e apaga os arquivos e mídias correspondentes.
|
||||
*
|
||||
* Causa: durante provisionamento LDAP, $account->id() era vazio antes do
|
||||
* primeiro save, gerando URI única compartilhada por todos os usuários.
|
||||
*/
|
||||
function site_users_update_10011() {
|
||||
$file_storage = \Drupal::entityTypeManager()->getStorage('file');
|
||||
$media_storage = \Drupal::entityTypeManager()->getStorage('media');
|
||||
$user_storage = \Drupal::entityTypeManager()->getStorage('user');
|
||||
|
||||
// Localiza arquivos com URI sem UID (ldap_photo_.jpg, ldap_photo_.png…).
|
||||
$fids = $file_storage->getQuery()
|
||||
->condition('uri', 'public://ldap_photos/ldap_photo_.', 'STARTS_WITH')
|
||||
->accessCheck(FALSE)
|
||||
->execute();
|
||||
|
||||
if (empty($fids)) {
|
||||
return t('Nenhum arquivo LDAP sem UID encontrado.');
|
||||
}
|
||||
|
||||
$removed_media = 0;
|
||||
$affected_users = 0;
|
||||
|
||||
foreach ($fids as $fid) {
|
||||
$medias = $media_storage->loadByProperties([
|
||||
'bundle' => 'image',
|
||||
'field_media_image.target_id' => $fid,
|
||||
]);
|
||||
|
||||
foreach ($medias as $media) {
|
||||
$mid = (int) $media->id();
|
||||
|
||||
$uids = $user_storage->getQuery()
|
||||
->condition('field_user_photos.target_id', $mid)
|
||||
->accessCheck(FALSE)
|
||||
->execute();
|
||||
|
||||
foreach ($uids as $uid) {
|
||||
$user = $user_storage->load($uid);
|
||||
if (!$user) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$photos = array_column($user->get('field_user_photos')->getValue(), 'target_id');
|
||||
$photos = array_values(array_filter($photos, fn($id) => (int) $id !== $mid));
|
||||
$user->set('field_user_photos', array_map(fn($id) => ['target_id' => $id], $photos));
|
||||
|
||||
if ((int) $user->get('field_user_default_photo')->target_id === $mid) {
|
||||
$user->set('field_user_default_photo', empty($photos) ? NULL : $photos[0]);
|
||||
}
|
||||
|
||||
$user->save();
|
||||
$affected_users++;
|
||||
}
|
||||
|
||||
$media->delete();
|
||||
$removed_media++;
|
||||
}
|
||||
|
||||
$file = $file_storage->load($fid);
|
||||
if ($file) {
|
||||
$file->delete();
|
||||
}
|
||||
}
|
||||
|
||||
return t('Removidas @m mídias sem UID de @u usuários.', [
|
||||
'@m' => $removed_media,
|
||||
'@u' => $affected_users,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adiciona o campo field_user_default_photo para seleção de foto padrão.
|
||||
*/
|
||||
@@ -470,10 +543,10 @@ function site_users_update_10006() {
|
||||
$form_display->removeComponent('field_user_selected_view_mode')->save();
|
||||
}
|
||||
|
||||
// 6. Remover de todos os view displays existentes.
|
||||
$displays = $display_storage->loadMultiple();
|
||||
// 6. Remover de todos os view displays de usuário existentes.
|
||||
$displays = $display_storage->loadByProperties(['targetEntityType' => 'user']);
|
||||
foreach ($displays as $display) {
|
||||
if ($display->getTargetEntityTypeId() === 'user' && $display->getComponent('field_user_selected_view_mode')) {
|
||||
if ($display->getComponent('field_user_selected_view_mode')) {
|
||||
$display->removeComponent('field_user_selected_view_mode')->save();
|
||||
}
|
||||
}
|
||||
@@ -614,6 +687,86 @@ function site_users_update_10009() {
|
||||
return t('Campo field_user_homepage criado com sucesso.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove fotos LDAP placeholder (abaixo do tamanho mínimo configurado).
|
||||
*
|
||||
* Limpa field_user_photos e field_user_default_photo dos usuários afetados
|
||||
* e apaga as entidades de mídia e arquivo correspondentes.
|
||||
*/
|
||||
function site_users_update_10010() {
|
||||
$min_size = (int) (\Drupal::config('site_users.settings')->get('photos.ldap_min_photo_size') ?? 10240);
|
||||
|
||||
// Busca arquivos LDAP abaixo do tamanho mínimo.
|
||||
$fids = \Drupal::entityTypeManager()->getStorage('file')->getQuery()
|
||||
->condition('uri', 'public://ldap_photos/', 'STARTS_WITH')
|
||||
->condition('filesize', $min_size, '<')
|
||||
->accessCheck(FALSE)
|
||||
->execute();
|
||||
|
||||
if (empty($fids)) {
|
||||
return t('Nenhuma foto LDAP placeholder encontrada.');
|
||||
}
|
||||
|
||||
$media_storage = \Drupal::entityTypeManager()->getStorage('media');
|
||||
$user_storage = \Drupal::entityTypeManager()->getStorage('user');
|
||||
$removed_media = 0;
|
||||
$affected_users = 0;
|
||||
|
||||
foreach ($fids as $fid) {
|
||||
// Localiza a entidade de mídia que usa este arquivo.
|
||||
$medias = $media_storage->loadByProperties([
|
||||
'bundle' => 'image',
|
||||
'field_media_image.target_id' => $fid,
|
||||
]);
|
||||
|
||||
foreach ($medias as $media) {
|
||||
$mid = (int) $media->id();
|
||||
|
||||
// Busca usuários que têm esta mídia em field_user_photos.
|
||||
$uids = $user_storage->getQuery()
|
||||
->condition('field_user_photos.target_id', $mid)
|
||||
->accessCheck(FALSE)
|
||||
->execute();
|
||||
|
||||
foreach ($uids as $uid) {
|
||||
/** @var \Drupal\user\UserInterface $user */
|
||||
$user = $user_storage->load($uid);
|
||||
if (!$user) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Remove a mídia de field_user_photos.
|
||||
$photos = array_column($user->get('field_user_photos')->getValue(), 'target_id');
|
||||
$photos = array_values(array_filter($photos, fn($id) => (int) $id !== $mid));
|
||||
$user->set('field_user_photos', array_map(fn($id) => ['target_id' => $id], $photos));
|
||||
|
||||
// Limpa field_user_default_photo se apontar para esta mídia.
|
||||
$default_mid = $user->get('field_user_default_photo')->target_id;
|
||||
if ((int) $default_mid === $mid) {
|
||||
$user->set('field_user_default_photo', empty($photos) ? NULL : $photos[0]);
|
||||
}
|
||||
|
||||
$user->save();
|
||||
$affected_users++;
|
||||
}
|
||||
|
||||
$media->delete();
|
||||
$removed_media++;
|
||||
}
|
||||
|
||||
// Apaga o arquivo gerenciado.
|
||||
$file = \Drupal::entityTypeManager()->getStorage('file')->load($fid);
|
||||
if ($file) {
|
||||
$file->delete();
|
||||
}
|
||||
}
|
||||
|
||||
return t('Removidas @m mídias placeholder de @u usuários.', [
|
||||
'@m' => $removed_media,
|
||||
'@u' => $affected_users,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Corrige mapeamentos LDAP com campos de string nulos na config ativa.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user