PR #58224 introduced a raster→SVG conversion path in ImageManager::getImage()
that breaks display of custom theming images. The root cause is a three-part
bug chain:
1. getImage() attempted to convert raster images (PNG/JPEG) to SVG format,
which Imagick cannot do meaningfully and produces broken output.
2. getMimeType() returns 'application/octet-stream' for extensionless stored
files, so the Content-Type response header was wrong.
3. Stale .svg cache files persisted after image replacement, causing
subsequent requests to serve the wrong format.
Fix by:
- Restricting the Imagick conversion to SVG→PNG only (not raster→SVG)
- Reading the stored MIME type from IAppConfig for extensionless files in
ThemingController::getImage()
- Deleting .svg cache files in ImageManager::delete()
- Injecting IAppConfig into ImageManager and reading the cachebuster via
IAppConfig::getAppValueInt() so the URL returned after upload always
carries the freshly-incremented value (IConfig::getAppValue() can return
a stale cached value within the same request)
- Updating the FileInputField Vue component to use a reactive cacheKey ref
that increments on every upload, so the thumbnail refreshes even when the
MIME type of the new image is the same as the old one
- Updating unit tests for ImageManager and ThemingController
- Updating psalm baseline for stable32
Backport of #60198
AI-Assisted-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Anna Larch <anna@nextcloud.com>
Signed-off-by: nextcloud-command <nextcloud-command@users.noreply.github.com>
The MailPlugin collaborator returned results for both user and mail
collaborators, but it was registered only for mail collaborators. While
it might make sense to move the user results to the UserPlugin instead
that change would be more complex and riskier, so for now the MailPlugin
is now registered for both user and mail collaborators and the results
are limited only to the registered type.
As the plugins are registered only with their class and then resolved
when needed using dependency injection it is not possible (as far as I
know) to provide an explicit parameter in the constructor to
differentiate whether the MailPlugin should return user or mail
collaborators. To overcome this two subclasses are introduced,
MailByMailPlugin and UserByMailPlugin, which just hardcode in their
constructor the collaborator type that their parent MailPlugin must use,
and those subclasses are the ones registered instead of the MailPlugin
(which still contains all the logic).
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
This removes a circular dependency between AppConfig and cache factory.
When a cache in the app config is used.
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
Also removed deprecated tag from the class as this class will not be
removed, only the interface IAppContainer and associated methods should
be removed.
Signed-off-by: Côme Chilliet <come.chilliet@nextcloud.com>
Only IManager was registered but the class name is used as well for DI
in the encryption application. This was causing a crash of encryption
command when using PHP 8.4 and lazy ghosts.
Signed-off-by: Côme Chilliet <come.chilliet@nextcloud.com>
Avoids a corner case issue if one application was disabled and another
one enabled with the same version, just to be safe.
Signed-off-by: Côme Chilliet <come.chilliet@nextcloud.com>
This makes sure the cached routes are updated after enabling a
previously disabled application
Signed-off-by: Côme Chilliet <come.chilliet@nextcloud.com>
Ideally circles and talk should migrate to calling registerProvider and
core would not need to use their OCA classes like currently.
Signed-off-by: Côme Chilliet <come.chilliet@nextcloud.com>