summaryrefslogtreecommitdiffstats
path: root/apps/theming/lib
diff options
context:
space:
mode:
authorMorris Jobke <hey@morrisjobke.de>2018-06-15 17:02:14 +0200
committerGitHub <noreply@github.com>2018-06-15 17:02:14 +0200
commit8f6acbff621b02cead64219eb9e6b03f4951075a (patch)
tree68dec6474e476078801be1cd2de3036401c3fc8b /apps/theming/lib
parentd82ef721611654aa3a3aab0ea3c8c85c7e0187d6 (diff)
parentceee91d9d455eed8b01942bc56767c69077e9f3f (diff)
downloadnextcloud-server-8f6acbff621b02cead64219eb9e6b03f4951075a.tar.gz
nextcloud-server-8f6acbff621b02cead64219eb9e6b03f4951075a.zip
Merge pull request #9258 from nextcloud/theming-logo-png
Convert theming app logo to PNG to show it properly in emails
Diffstat (limited to 'apps/theming/lib')
-rw-r--r--apps/theming/lib/Controller/IconController.php4
-rw-r--r--apps/theming/lib/Controller/ThemingController.php14
-rw-r--r--apps/theming/lib/IconBuilder.php9
-rw-r--r--apps/theming/lib/ImageManager.php87
-rw-r--r--apps/theming/lib/Settings/Admin.php2
-rw-r--r--apps/theming/lib/ThemingDefaults.php33
6 files changed, 100 insertions, 49 deletions
diff --git a/apps/theming/lib/Controller/IconController.php b/apps/theming/lib/Controller/IconController.php
index 0caf9a2bc37..a2727546e09 100644
--- a/apps/theming/lib/Controller/IconController.php
+++ b/apps/theming/lib/Controller/IconController.php
@@ -119,7 +119,7 @@ class IconController extends Controller {
$response = new FileDisplayResponse($iconFile, Http::STATUS_OK, ['Content-Type' => 'image/x-icon']);
} catch (NotFoundException $e) {
}
- if ($iconFile === null && $this->themingDefaults->shouldReplaceIcons()) {
+ if ($iconFile === null && $this->imageManager->shouldReplaceIcons()) {
try {
$iconFile = $this->imageManager->getCachedImage('favIcon-' . $app);
} catch (NotFoundException $exception) {
@@ -155,7 +155,7 @@ class IconController extends Controller {
$response = new FileDisplayResponse($iconFile, Http::STATUS_OK, ['Content-Type' => 'image/x-icon']);
} catch (NotFoundException $e) {
}
- if ($this->themingDefaults->shouldReplaceIcons()) {
+ if ($this->imageManager->shouldReplaceIcons()) {
try {
$iconFile = $this->imageManager->getCachedImage('touchIcon-' . $app);
} catch (NotFoundException $exception) {
diff --git a/apps/theming/lib/Controller/ThemingController.php b/apps/theming/lib/Controller/ThemingController.php
index 99b98ab7da3..96f8dfde9fd 100644
--- a/apps/theming/lib/Controller/ThemingController.php
+++ b/apps/theming/lib/Controller/ThemingController.php
@@ -262,6 +262,8 @@ class ThemingController extends Controller {
$folder = $this->appData->newFolder('images');
}
+ $this->imageManager->delete($key);
+
$target = $folder->newFile($key);
$supportedFormats = ['image/jpeg', 'image/png', 'image/gif', 'image/svg+xml', 'image/svg'];
$detectedMimeType = mime_content_type($image['tmp_name']);
@@ -351,12 +353,13 @@ class ThemingController extends Controller {
* @NoCSRFRequired
*
* @param string $key
+ * @param bool $useSvg
* @return FileDisplayResponse|NotFoundResponse
- * @throws \Exception
+ * @throws NotPermittedException
*/
- public function getImage(string $key) {
+ public function getImage(string $key, bool $useSvg = true) {
try {
- $file = $this->imageManager->getImage($key);
+ $file = $this->imageManager->getImage($key, $useSvg);
} catch (NotFoundException $e) {
return new NotFoundResponse();
}
@@ -365,6 +368,11 @@ class ThemingController extends Controller {
$response->cacheFor(3600);
$response->addHeader('Content-Type', $this->config->getAppValue($this->appName, $key . 'Mime', ''));
$response->addHeader('Content-Disposition', 'attachment; filename="' . $key . '"');
+ if (!$useSvg) {
+ $response->addHeader('Content-Type', 'image/png');
+ } else {
+ $response->addHeader('Content-Type', $this->config->getAppValue($this->appName, $key . 'Mime', ''));
+ }
return $response;
}
diff --git a/apps/theming/lib/IconBuilder.php b/apps/theming/lib/IconBuilder.php
index ad44dd7ed6c..f85e2f9bff8 100644
--- a/apps/theming/lib/IconBuilder.php
+++ b/apps/theming/lib/IconBuilder.php
@@ -35,19 +35,24 @@ class IconBuilder {
private $themingDefaults;
/** @var Util */
private $util;
+ /** @var ImageManager */
+ private $imageManager;
/**
* IconBuilder constructor.
*
* @param ThemingDefaults $themingDefaults
* @param Util $util
+ * @param ImageManager $imageManager
*/
public function __construct(
ThemingDefaults $themingDefaults,
- Util $util
+ Util $util,
+ ImageManager $imageManager
) {
$this->themingDefaults = $themingDefaults;
$this->util = $util;
+ $this->imageManager = $imageManager;
}
/**
@@ -55,7 +60,7 @@ class IconBuilder {
* @return string|false image blob
*/
public function getFavicon($app) {
- if (!$this->themingDefaults->shouldReplaceIcons()) {
+ if (!$this->imageManager->shouldReplaceIcons()) {
return false;
}
try {
diff --git a/apps/theming/lib/ImageManager.php b/apps/theming/lib/ImageManager.php
index 830ed7f34a9..dfbdb582da6 100644
--- a/apps/theming/lib/ImageManager.php
+++ b/apps/theming/lib/ImageManager.php
@@ -26,24 +26,28 @@ namespace OCA\Theming;
use OCP\Files\SimpleFS\ISimpleFile;
use OCP\Files\SimpleFS\ISimpleFolder;
+use OCP\ICacheFactory;
use OCP\IConfig;
use OCP\Files\IAppData;
use OCP\Files\NotFoundException;
use OCP\Files\NotPermittedException;
+use OCP\ILogger;
use OCP\IURLGenerator;
-/**
- * @property IURLGenerator urlGenerator
- */
class ImageManager {
/** @var IConfig */
private $config;
/** @var IAppData */
private $appData;
-
+ /** @var IURLGenerator */
+ private $urlGenerator;
/** @var array */
private $supportedImageKeys = ['background', 'logo', 'logoheader', 'favicon'];
+ /** @var ICacheFactory */
+ private $cacheFactory;
+ /** @var ILogger */
+ private $logger;
/**
* ImageManager constructor.
@@ -51,20 +55,26 @@ class ImageManager {
* @param IConfig $config
* @param IAppData $appData
* @param IURLGenerator $urlGenerator
+ * @param ICacheFactory $cacheFactory
+ * @param ILogger $logger
*/
public function __construct(IConfig $config,
IAppData $appData,
- IURLGenerator $urlGenerator
+ IURLGenerator $urlGenerator,
+ ICacheFactory $cacheFactory,
+ ILogger $logger
) {
$this->config = $config;
$this->appData = $appData;
$this->urlGenerator = $urlGenerator;
+ $this->cacheFactory = $cacheFactory;
+ $this->logger = $logger;
}
- public function getImageUrl(string $key): string {
+ public function getImageUrl(string $key, bool $useSvg = true): string {
$cacheBusterCounter = $this->config->getAppValue('theming', 'cachebuster', '0');
try {
- $this->getImage($key);
+ $image = $this->getImage($key, $useSvg);
return $this->urlGenerator->linkToRoute('theming.Theming.getImage', [ 'key' => $key ]) . '?v=' . $cacheBusterCounter;
} catch (NotFoundException $e) {
}
@@ -79,21 +89,44 @@ class ImageManager {
}
}
- public function getImageUrlAbsolute(string $key): string {
- return $this->urlGenerator->getAbsoluteURL($this->getImageUrl($key));
+ public function getImageUrlAbsolute(string $key, bool $useSvg = true): string {
+ return $this->urlGenerator->getAbsoluteURL($this->getImageUrl($key, $useSvg));
}
/**
- * @param $key
+ * @param string $key
+ * @param bool $useSvg
* @return ISimpleFile
* @throws NotFoundException
+ * @throws NotPermittedException
*/
- public function getImage(string $key): ISimpleFile {
+ public function getImage(string $key, bool $useSvg = true): ISimpleFile {
+ $pngFile = null;
$logo = $this->config->getAppValue('theming', $key . 'Mime', false);
- if ($logo === false) {
+ $folder = $this->appData->getFolder('images');
+ if ($logo === false || !$folder->fileExists($key)) {
throw new NotFoundException();
}
- $folder = $this->appData->getFolder('images');
+ if (!$useSvg && $this->shouldReplaceIcons()) {
+ if (!$folder->fileExists($key . '.png')) {
+ try {
+ $finalIconFile = new \Imagick();
+ $finalIconFile->setBackgroundColor('none');
+ $finalIconFile->readImageBlob($folder->getFile($key)->getContent());
+ $finalIconFile->setImageFormat('png32');
+ $pngFile = $folder->newFile($key . '.png');
+ $pngFile->putContent($finalIconFile->getImageBlob());
+ } catch (\ImagickException $e) {
+ $this->logger->info('The image was requested to be no SVG file, but converting it to PNG failed.', $e->getMessage());
+ $pngFile = null;
+ }
+ } else {
+ $pngFile = $folder->getFile($key . '.png');
+ }
+ }
+ if ($pngFile !== null) {
+ return $pngFile;
+ }
return $folder->getFile($key);
}
@@ -159,12 +192,19 @@ class ImageManager {
}
public function delete(string $key) {
+ /* ignore exceptions, since we don't want to fail hard if something goes wrong during cleanup */
try {
$file = $this->appData->getFolder('images')->getFile($key);
$file->delete();
} catch (NotFoundException $e) {
} catch (NotPermittedException $e) {
}
+ try {
+ $file = $this->appData->getFolder('images')->getFile($key . '.png');
+ $file->delete();
+ } catch (NotFoundException $e) {
+ } catch (NotPermittedException $e) {
+ }
}
/**
@@ -182,4 +222,25 @@ class ImageManager {
}
}
}
+
+ /**
+ * Check if Imagemagick is enabled and if SVG is supported
+ * otherwise we can't render custom icons
+ *
+ * @return bool
+ */
+ public function shouldReplaceIcons() {
+ $cache = $this->cacheFactory->createDistributed('theming-' . $this->urlGenerator->getBaseUrl());
+ if($value = $cache->get('shouldReplaceIcons')) {
+ return (bool)$value;
+ }
+ $value = false;
+ if(extension_loaded('imagick')) {
+ if (count(\Imagick::queryFormats('SVG')) >= 1) {
+ $value = true;
+ }
+ }
+ $cache->set('shouldReplaceIcons', $value);
+ return $value;
+ }
}
diff --git a/apps/theming/lib/Settings/Admin.php b/apps/theming/lib/Settings/Admin.php
index 6a95dd39d43..c8d2d561513 100644
--- a/apps/theming/lib/Settings/Admin.php
+++ b/apps/theming/lib/Settings/Admin.php
@@ -81,7 +81,7 @@ class Admin implements ISettings {
'slogan' => $this->themingDefaults->getSlogan(),
'color' => $this->themingDefaults->getColorPrimary(),
'uploadLogoRoute' => $this->urlGenerator->linkToRoute('theming.Theming.uploadImage'),
- 'canThemeIcons' => $this->themingDefaults->shouldReplaceIcons(),
+ 'canThemeIcons' => $this->imageManager->shouldReplaceIcons(),
'iconDocs' => $this->urlGenerator->linkToDocs('admin-theming-icons'),
'images' => $this->imageManager->getCustomImages(),
'imprintUrl' => $this->themingDefaults->getImprintUrl(),
diff --git a/apps/theming/lib/ThemingDefaults.php b/apps/theming/lib/ThemingDefaults.php
index 00c47676bc8..d29eb69873f 100644
--- a/apps/theming/lib/ThemingDefaults.php
+++ b/apps/theming/lib/ThemingDefaults.php
@@ -205,7 +205,7 @@ class ThemingDefaults extends \OC_Defaults {
$logoExists = true;
try {
- $this->imageManager->getImage('logo');
+ $this->imageManager->getImage('logo', $useSvg);
} catch (\Exception $e) {
$logoExists = false;
}
@@ -221,7 +221,7 @@ class ThemingDefaults extends \OC_Defaults {
return $logo . '?v=' . $cacheBusterCounter;
}
- return $this->urlGenerator->linkToRoute('theming.Theming.getImage', [ 'key' => 'logo' ]) . '?v=' . $cacheBusterCounter;
+ return $this->urlGenerator->linkToRoute('theming.Theming.getImage', [ 'key' => 'logo', 'useSvg' => $useSvg, 'v' => $cacheBusterCounter ]);
}
/**
@@ -317,10 +317,10 @@ class ThemingDefaults extends \OC_Defaults {
$customFavicon = null;
}
- if ($image === 'favicon.ico' && ($customFavicon !== null || $this->shouldReplaceIcons())) {
+ if ($image === 'favicon.ico' && ($customFavicon !== null || $this->imageManager->shouldReplaceIcons())) {
return $this->urlGenerator->linkToRoute('theming.Icon.getFavicon', ['app' => $app]) . '?v=' . $cacheBusterValue;
}
- if ($image === 'favicon-touch.png' && ($customFavicon !== null || $this->shouldReplaceIcons())) {
+ if ($image === 'favicon-touch.png' && ($customFavicon !== null || $this->imageManager->shouldReplaceIcons())) {
return $this->urlGenerator->linkToRoute('theming.Icon.getTouchIcon', ['app' => $app]) . '?v=' . $cacheBusterValue;
}
if ($image === 'manifest.json') {
@@ -334,30 +334,7 @@ class ThemingDefaults extends \OC_Defaults {
}
return false;
}
-
- /**
- * Check if Imagemagick is enabled and if SVG is supported
- * otherwise we can't render custom icons
- *
- * @return bool
- */
- public function shouldReplaceIcons() {
- $cache = $this->cacheFactory->createDistributed('theming-' . $this->urlGenerator->getBaseUrl());
- if($value = $cache->get('shouldReplaceIcons')) {
- return (bool)$value;
- }
- $value = false;
- if(extension_loaded('imagick')) {
- $checkImagick = new \Imagick();
- if (count($checkImagick->queryFormats('SVG')) >= 1) {
- $value = true;
- }
- $checkImagick->clear();
- }
- $cache->set('shouldReplaceIcons', $value);
- return $value;
- }
-
+
/**
* Increases the cache buster key
*/