configFactory->get('site_users.settings'); if (!$config->get('photos.ldap_sync_enabled')) { return; } $attribute = $config->get('photos.ldap_attribute'); if (!$attribute || !$ldapEntry->hasAttribute($attribute, FALSE)) { return; } $binary = $ldapEntry->getAttribute($attribute, FALSE)[0] ?? NULL; if (empty($binary)) { return; } $extension = $this->detectExtension($binary); if (!$extension) { return; } $directory = 'public://ldap_photos'; $uri = $directory . '/' . 'ldap_photo_' . $account->id() . '.' . $extension; // If file exists and content is unchanged, just ensure it is first. $realpath = $this->fileSystem->realpath($uri); if ($realpath && file_exists($realpath) && md5_file($realpath) === md5($binary)) { $this->ensureMediaFirstInField($account, $uri); return; } $this->fileSystem->prepareDirectory($directory, FileSystemInterface::CREATE_DIRECTORY | FileSystemInterface::MODIFY_PERMISSIONS); $file = $this->fileRepository->writeData($binary, $uri, FileExists::Replace); if (!$file) { return; } $media = $this->findOrCreateMedia($file, (int) $account->id()); if (!$media) { return; } $this->prependMediaToField($account, (int) $media->id()); } /** * Detects the image extension from binary data via a temporary file. */ private function detectExtension(string $binary): ?string { $tmp = $this->fileSystem->tempnam('temporary://', 'ldap_photo_'); file_put_contents($this->fileSystem->realpath($tmp), $binary); $type = @exif_imagetype($this->fileSystem->realpath($tmp)); $this->fileSystem->unlink($tmp); return match ($type) { IMAGETYPE_JPEG => 'jpg', IMAGETYPE_PNG => 'png', IMAGETYPE_GIF => 'gif', default => NULL, }; } /** * Returns an existing media entity for the file, or creates one. */ private function findOrCreateMedia(FileInterface $file, int $uid): ?object { $media_storage = $this->entityTypeManager->getStorage('media'); $existing = $media_storage->loadByProperties([ 'bundle' => 'image', 'field_media_image.target_id' => $file->id(), ]); if (!empty($existing)) { return reset($existing); } $media = $media_storage->create([ 'bundle' => 'image', 'uid' => $uid, 'name' => $file->getFilename(), 'field_media_image' => [ 'target_id' => $file->id(), 'alt' => $file->getFilename(), ], 'status' => 1, ]); $media->save(); return $media; } /** * Ensures the media for an existing file URI is first in field_user_photos. */ private function ensureMediaFirstInField(UserInterface $account, string $uri): void { $files = $this->entityTypeManager->getStorage('file') ->loadByProperties(['uri' => $uri]); if (empty($files)) { return; } $file = reset($files); $media_storage = $this->entityTypeManager->getStorage('media'); $existing = $media_storage->loadByProperties([ 'bundle' => 'image', 'field_media_image.target_id' => $file->id(), ]); if (empty($existing)) { return; } $media = reset($existing); $this->prependMediaToField($account, (int) $media->id()); } /** * Prepends a media entity to field_user_photos, removing any duplicate. */ private function prependMediaToField(UserInterface $account, int $media_id): void { $current_ids = array_column($account->get('field_user_photos')->getValue(), 'target_id'); if (!empty($current_ids) && (int) $current_ids[0] === $media_id) { return; } $filtered = array_values(array_filter($current_ids, fn($id) => (int) $id !== $media_id)); array_unshift($filtered, $media_id); $account->set('field_user_photos', array_map(fn($id) => ['target_id' => $id], $filtered)); } }