`PreviewController::getFileIdForAlbums()` crashes with "Call to a member function getOwner() on null" → all album previews return HTTP 500`
bug0. Needs triage
## Describe the bug
`OCA\Photos\Controller\PreviewController::getFileIdForAlbums()` does not handle the case where neither `AlbumMapper::getForAlbumIdAndFileId()` nor `FiltersManager::getFilesBasedOnFilters()` return a result for an album in the iteration. When this happens, `$albumFile` stays `null`, and the next line dereferences it:
```php
$nodes = $this->rootFolder
->getUserFolder($albumFile->getOwner()) // crashes here (line 135)
->getById($fileId);
```
Result: `Error: Call to a member function getOwner() on null`. Because this aborts the iteration over all albums visible to the user, **every** preview request via `/apps/photos/api/v1/preview/<fileId>` returns HTTP 500 for that user as soon as more than one album is involved — even though the underlying file and all album data are valid.
This also breaks `nextcloud/memories`, which uses the Photos preview endpoint as a tile source — the entire grid stays grey.
## Steps to reproduce
1. Owner user creates several albums (mix of own and shared-with-other-user) and adds photos.
2. Share the albums with another user (collaborator).
3. Log in as the collaborator.
4. Open Memories or any UI that requests `/apps/photos/api/v1/preview/<fileId>?x=512&y=512`.
5. Server returns 500 for every tile.
In the affected setup, all 11 visible albums had `file_count == resolvable_count` (verified via `oc_photos_albums_files` join `oc_filecache`). Data is clean — the crash is purely a missing null guard in the iteration.
## Expected behavior
If a given album does not contain or cannot resolve the requested `$fileId`, skip that album and continue iterating, exactly as the surrounding `if (\count($nodes) === 0)` logic already anticipates.
## Actual behavior
First album in the loop where neither `getForAlbumIdAndFileId()` nor `getFilesBasedOnFilters()` produces a result causes a fatal `Error`, returning HTTP 500 for the whole request.
## Stacktrace (Nextcloud log, level 3)
```
Call to a member function getOwner() on null
in apps/photos/lib/Controller/PreviewController.php line 135
Trace:
apps/photos/lib/Controller/PreviewController.php:95
OCA\Photos\Controller\PreviewController->getFileIdForAlbums(
<fileId>,
[11 × OCA\Photos\Album\AlbumInfo]
)
lib/private/AppFramework/Http/Dispatcher.php:204
...->index(<fileId>, 512, 512)
```
Preceding notice (level 2):
```
Undefined array key 0 at apps/photos/lib/Album/AlbumMapper.php#209
```
## Suggested fix
Add a null guard after `array_pop($albumFiles)` in `getFileIdForAlbums()`:
```diff
protected function getFileIdForAlbums(int $fileId, array $albums): array {
foreach ($albums as $album) {
$albumFile = $this->albumMapper->getForAlbumIdAndFileId($album->getId(), $fileId);
if ($albumFile === null) {
$albumFiles = $this->filtersManager->getFilesBasedOnFilters($album->getUserId(), $album->getDecodedFilters(), $fileId);
$albumFile = array_pop($albumFiles);
+ if ($albumFile === null) {
+ continue;
+ }
}
$nodes = $this->rootFolder
->getUserFolder($albumFile->getOwner())
->getById($fileId);
if (\count($nodes) !== 0) {
return $nodes;
}
}
return [];
}
```
Verified: with this single line applied, the preview endpoint returns 200 with the expected image, and Memories tiles render correctly. Album functionality is fully restored.
The notice in `AlbumMapper.php:209` (`Undefined array key 0`) likely deserves a defensive check on its own, but the `PreviewController` patch alone resolves the user-visible crash.
## Platform
- Nextcloud: 32.0.1.2
- Photos app: 5.0.0-dev.1
- PHP: (please fill — `docker exec nextcloud php -v`)
- Reverse proxy: Traefik behind Cloudflare
- Browsers reproduced in: Safari 18.0.1 (macOS), Firefox, Chrome — server-side issue, browser-independent
0 条评论