Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>pull/42977/head
@@ -57,6 +57,7 @@ class ImageManager { | |||
private ICacheFactory $cacheFactory, | |||
private LoggerInterface $logger, | |||
private ITempManager $tempManager, | |||
private BackgroundService $backgroundService, | |||
) { | |||
} | |||
@@ -228,47 +229,56 @@ class ImageManager { | |||
throw new \Exception('Unsupported image type: ' . $detectedMimeType); | |||
} | |||
if ($key === 'background' && $this->shouldOptimizeBackgroundImage($detectedMimeType, filesize($tmpFile))) { | |||
try { | |||
// Optimize the image since some people may upload images that will be | |||
// either to big or are not progressive rendering. | |||
$newImage = @imagecreatefromstring(file_get_contents($tmpFile)); | |||
if ($newImage === false) { | |||
throw new \Exception('Could not read background image, possibly corrupted.'); | |||
} | |||
if ($key === 'background') { | |||
if ($this->shouldOptimizeBackgroundImage($detectedMimeType, filesize($tmpFile))) { | |||
try { | |||
// Optimize the image since some people may upload images that will be | |||
// either to big or are not progressive rendering. | |||
$newImage = @imagecreatefromstring(file_get_contents($tmpFile)); | |||
if ($newImage === false) { | |||
throw new \Exception('Could not read background image, possibly corrupted.'); | |||
} | |||
// Preserve transparency | |||
imagesavealpha($newImage, true); | |||
imagealphablending($newImage, true); | |||
// Preserve transparency | |||
imagesavealpha($newImage, true); | |||
imagealphablending($newImage, true); | |||
$newWidth = (imagesx($newImage) < 4096 ? imagesx($newImage) : 4096); | |||
$newHeight = (int)(imagesy($newImage) / (imagesx($newImage) / $newWidth)); | |||
$outputImage = imagescale($newImage, $newWidth, $newHeight); | |||
if ($outputImage === false) { | |||
throw new \Exception('Could not scale uploaded background image.'); | |||
} | |||
$imageWidth = imagesx($newImage); | |||
$imageHeight = imagesy($newImage); | |||
$newTmpFile = $this->tempManager->getTemporaryFile(); | |||
imageinterlace($outputImage, true); | |||
// Keep jpeg images encoded as jpeg | |||
if (str_contains($detectedMimeType, 'image/jpeg')) { | |||
if (!imagejpeg($outputImage, $newTmpFile, 90)) { | |||
throw new \Exception('Could not recompress background image as JPEG'); | |||
/** @var int */ | |||
$newWidth = min(4096, $imageWidth); | |||
$newHeight = intval($imageHeight / ($imageWidth / $newWidth)); | |||
$outputImage = imagescale($newImage, $newWidth, $newHeight); | |||
if ($outputImage === false) { | |||
throw new \Exception('Could not scale uploaded background image.'); | |||
} | |||
} else { | |||
if (!imagepng($outputImage, $newTmpFile, 8)) { | |||
throw new \Exception('Could not recompress background image as PNG'); | |||
$newTmpFile = $this->tempManager->getTemporaryFile(); | |||
imageinterlace($outputImage, true); | |||
// Keep jpeg images encoded as jpeg | |||
if (str_contains($detectedMimeType, 'image/jpeg')) { | |||
if (!imagejpeg($outputImage, $newTmpFile, 90)) { | |||
throw new \Exception('Could not recompress background image as JPEG'); | |||
} | |||
} else { | |||
if (!imagepng($outputImage, $newTmpFile, 8)) { | |||
throw new \Exception('Could not recompress background image as PNG'); | |||
} | |||
} | |||
} | |||
$tmpFile = $newTmpFile; | |||
imagedestroy($outputImage); | |||
} catch (\Exception $e) { | |||
if (is_resource($outputImage) || $outputImage instanceof \GdImage) { | |||
$tmpFile = $newTmpFile; | |||
imagedestroy($outputImage); | |||
} | |||
} catch (\Exception $e) { | |||
if (isset($outputImage) && is_resource($outputImage) || $outputImage instanceof \GdImage) { | |||
imagedestroy($outputImage); | |||
} | |||
$this->logger->debug($e->getMessage()); | |||
$this->logger->debug($e->getMessage()); | |||
} | |||
} | |||
// For background images we need to announce it | |||
$this->backgroundService->setGlobalBackground($tmpFile); | |||
} | |||
$target->putContent(file_get_contents($tmpFile)); |
@@ -286,21 +286,19 @@ class BackgroundService { | |||
} | |||
/** | |||
* Storing the data in appdata/theming/users/USERID | |||
* | |||
* @return ISimpleFolder | |||
* @throws NotPermittedException | |||
* Called when a new global background (backgroundMime) is uploaded (admin setting) | |||
* This sets all necessary app config values | |||
* @param resource|string $path | |||
*/ | |||
private function getAppDataFolder(): ISimpleFolder { | |||
try { | |||
$rootFolder = $this->appData->getFolder('users'); | |||
} catch (NotFoundException $e) { | |||
$rootFolder = $this->appData->newFolder('users'); | |||
} | |||
try { | |||
return $rootFolder->getFolder($this->userId); | |||
} catch (NotFoundException $e) { | |||
return $rootFolder->newFolder($this->userId); | |||
public function setGlobalBackground($path): void { | |||
$image = new \OCP\Image(); | |||
$handle = is_resource($path) ? $path : fopen($path, 'rb'); | |||
if ($handle && $image->loadFromFileHandle($handle) !== false) { | |||
$meanColor = $this->calculateMeanColor($image); | |||
if ($meanColor !== false) { | |||
$this->config->setAppValue(Application::APP_ID, 'background_color', $meanColor); | |||
} | |||
} | |||
} | |||
@@ -359,4 +357,23 @@ class BackgroundService { | |||
$meanColor .= toHex((int)(array_sum($blues) / count($blues))); | |||
return $meanColor; | |||
} | |||
/** | |||
* Storing the data in appdata/theming/users/USERID | |||
* | |||
* @return ISimpleFolder | |||
* @throws NotPermittedException | |||
*/ | |||
private function getAppDataFolder(): ISimpleFolder { | |||
try { | |||
$rootFolder = $this->appData->getFolder('users'); | |||
} catch (NotFoundException $e) { | |||
$rootFolder = $this->appData->newFolder('users'); | |||
} | |||
try { | |||
return $rootFolder->getFolder($this->userId); | |||
} catch (NotFoundException $e) { | |||
return $rootFolder->newFolder($this->userId); | |||
} | |||
} | |||
} |
@@ -132,7 +132,7 @@ trait CommonThemeTrait { | |||
&& !$this->themingDefaults->isUserThemingDisabled() | |||
&& $this->appManager->isEnabledForUser(Application::APP_ID)) { | |||
$backgroundImage = $this->config->getUserValue($user->getUID(), Application::APP_ID, 'background_image', BackgroundService::BACKGROUND_DEFAULT); | |||
$backgroundColor = $this->config->getUserValue($user->getUID(), Application::APP_ID, 'background_color', $this->themingDefaults->getColorPrimary()); | |||
$backgroundColor = $this->config->getUserValue($user->getUID(), Application::APP_ID, 'background_color', $this->themingDefaults->getColorBackground()); | |||
$currentVersion = (int)$this->config->getUserValue($user->getUID(), Application::APP_ID, 'userCacheBuster', '0'); | |||
$isBackgroundBright = $this->util->invertTextColor($backgroundColor); |
@@ -7,6 +7,7 @@ | |||
* @author Bjoern Schiessle <bjoern@schiessle.org> | |||
* @author Christoph Wurst <christoph@winzerhof-wurst.at> | |||
* @author Daniel Kesselberg <mail@danielkesselberg.de> | |||
* @author Ferdinand Thiessen <opensource@fthiessen.de> | |||
* @author Guillaume COMPAGNON <gcompagnon@outlook.com> | |||
* @author Jan-Christoph Borchardt <hey@jancborchardt.net> | |||
* @author Joachim Bauch <bauch@struktur.de> | |||
@@ -55,16 +56,6 @@ use OCP\IUserSession; | |||
class ThemingDefaults extends \OC_Defaults { | |||
private IConfig $config; | |||
private IL10N $l; | |||
private ImageManager $imageManager; | |||
private IUserSession $userSession; | |||
private IURLGenerator $urlGenerator; | |||
private ICacheFactory $cacheFactory; | |||
private Util $util; | |||
private IAppManager $appManager; | |||
private INavigationManager $navigationManager; | |||
private string $name; | |||
private string $title; | |||
private string $entity; | |||
@@ -80,36 +71,20 @@ class ThemingDefaults extends \OC_Defaults { | |||
/** | |||
* ThemingDefaults constructor. | |||
* | |||
* @param IConfig $config | |||
* @param IL10N $l | |||
* @param ImageManager $imageManager | |||
* @param IUserSession $userSession | |||
* @param IURLGenerator $urlGenerator | |||
* @param ICacheFactory $cacheFactory | |||
* @param Util $util | |||
* @param IAppManager $appManager | |||
*/ | |||
public function __construct(IConfig $config, | |||
IL10N $l, | |||
IUserSession $userSession, | |||
IURLGenerator $urlGenerator, | |||
ICacheFactory $cacheFactory, | |||
Util $util, | |||
ImageManager $imageManager, | |||
IAppManager $appManager, | |||
INavigationManager $navigationManager | |||
public function __construct( | |||
private IConfig $config, | |||
private IL10N $l, | |||
private IUserSession $userSession, | |||
private IURLGenerator $urlGenerator, | |||
private ICacheFactory $cacheFactory, | |||
private Util $util, | |||
private ImageManager $imageManager, | |||
private IAppManager $appManager, | |||
private INavigationManager $navigationManager, | |||
private BackgroundService $backgroundService, | |||
) { | |||
parent::__construct(); | |||
$this->config = $config; | |||
$this->l = $l; | |||
$this->imageManager = $imageManager; | |||
$this->userSession = $userSession; | |||
$this->urlGenerator = $urlGenerator; | |||
$this->cacheFactory = $cacheFactory; | |||
$this->util = $util; | |||
$this->appManager = $appManager; | |||
$this->navigationManager = $navigationManager; | |||
$this->name = parent::getName(); | |||
$this->title = parent::getTitle(); | |||
@@ -520,9 +495,15 @@ class ThemingDefaults extends \OC_Defaults { | |||
case 'slogan': | |||
$returnValue = $this->getSlogan(); | |||
break; | |||
case 'color': | |||
case 'primary_color': | |||
$returnValue = $this->getDefaultColorPrimary(); | |||
break; | |||
case 'background_color': | |||
if ($this->imageManager->hasImage('background')) { | |||
$file = $this->imageManager->getImage('background'); | |||
$this->backgroundService->setGlobalBackground($file->read()); | |||
} | |||
break; | |||
case 'logo': | |||
case 'logoheader': | |||
case 'background': |
@@ -171,6 +171,7 @@ use OCA\Files_External\Service\GlobalStoragesService; | |||
use OCA\Files_External\Service\UserGlobalStoragesService; | |||
use OCA\Files_External\Service\UserStoragesService; | |||
use OCA\Theming\ImageManager; | |||
use OCA\Theming\Service\BackgroundService; | |||
use OCA\Theming\ThemingDefaults; | |||
use OCA\Theming\Util; | |||
use OCP\Accounts\IAccountManager; | |||
@@ -1190,7 +1191,8 @@ class Server extends ServerContainer implements IServerContainer { | |||
$c->get(IURLGenerator::class), | |||
$this->get(ICacheFactory::class), | |||
$this->get(LoggerInterface::class), | |||
$this->get(ITempManager::class) | |||
$this->get(ITempManager::class), | |||
$this->get(BackgroundService::class), | |||
); | |||
return new ThemingDefaults( | |||
$c->get(\OCP\IConfig::class), | |||
@@ -1201,7 +1203,8 @@ class Server extends ServerContainer implements IServerContainer { | |||
new Util($c->get(\OCP\IConfig::class), $this->get(IAppManager::class), $c->getAppDataDir('theming'), $imageManager), | |||
$imageManager, | |||
$c->get(IAppManager::class), | |||
$c->get(INavigationManager::class) | |||
$c->get(INavigationManager::class), | |||
$c->get(BackgroundService::class), | |||
); | |||
} | |||
return new \OC_Defaults(); |