diff options
Diffstat (limited to 'apps/theming/lib')
-rw-r--r-- | apps/theming/lib/Controller/IconController.php | 53 | ||||
-rw-r--r-- | apps/theming/lib/IconBuilder.php | 18 | ||||
-rw-r--r-- | apps/theming/lib/ImageManager.php | 118 |
3 files changed, 169 insertions, 20 deletions
diff --git a/apps/theming/lib/Controller/IconController.php b/apps/theming/lib/Controller/IconController.php index f2355fe3f82..eb65ae54f1a 100644 --- a/apps/theming/lib/Controller/IconController.php +++ b/apps/theming/lib/Controller/IconController.php @@ -23,13 +23,16 @@ namespace OCA\Theming\Controller; use OCA\Theming\IconBuilder; +use OCA\Theming\ImageManager; use OCA\Theming\ThemingDefaults; use OCP\AppFramework\Controller; use OCP\AppFramework\Http; use OCP\AppFramework\Http\DataDisplayResponse; +use OCP\AppFramework\Http\FileDisplayResponse; use OCP\AppFramework\Utility\ITimeFactory; use OCP\IRequest; use OCA\Theming\Util; +use OCP\IConfig; class IconController extends Controller { /** @var ThemingDefaults */ @@ -38,8 +41,12 @@ class IconController extends Controller { private $util; /** @var ITimeFactory */ private $timeFactory; + /** @var IConfig */ + private $config; /** @var IconBuilder */ private $iconBuilder; + /** @var ImageManager */ + private $imageManager; /** * IconController constructor. @@ -49,7 +56,9 @@ class IconController extends Controller { * @param ThemingDefaults $themingDefaults * @param Util $util * @param ITimeFactory $timeFactory + * @param IConfig $config * @param IconBuilder $iconBuilder + * @param ImageManager $imageManager */ public function __construct( $appName, @@ -57,14 +66,18 @@ class IconController extends Controller { ThemingDefaults $themingDefaults, Util $util, ITimeFactory $timeFactory, - IconBuilder $iconBuilder + IConfig $config, + IconBuilder $iconBuilder, + ImageManager $imageManager ) { parent::__construct($appName, $request); $this->themingDefaults = $themingDefaults; $this->util = $util; $this->timeFactory = $timeFactory; + $this->config = $config; $this->iconBuilder = $iconBuilder; + $this->imageManager = $imageManager; } /** @@ -73,14 +86,15 @@ class IconController extends Controller { * * @param $app string app name * @param $image string image file name (svg required) - * @return DataDisplayResponse + * @return FileDisplayResponse */ public function getThemedIcon($app, $image) { - $image = $this->util->getAppImage($app, $image); - $svg = file_get_contents($image); - $color = $this->util->elementColor($this->themingDefaults->getMailHeaderColor()); - $svg = $this->util->colorizeSvg($svg, $color); - $response = new DataDisplayResponse($svg, Http::STATUS_OK, ['Content-Type' => 'image/svg+xml']); + $iconFile = $this->imageManager->getCachedImage("icon-" . $app . '-' . str_replace("/","_",$image)); + if ($iconFile === null) { + $icon = $this->iconBuilder->colorSvg($app, $image); + $iconFile = $this->imageManager->setCachedImage("icon-" . $app . '-' . str_replace("/","_",$image), $icon); + } + $response = new FileDisplayResponse($iconFile, Http::STATUS_OK, ['Content-Type' => 'image/svg+xml']); $response->cacheFor(86400); $response->addHeader('Expires', date(\DateTime::RFC2822, $this->timeFactory->getTime())); $response->addHeader('Pragma', 'cache'); @@ -94,12 +108,16 @@ class IconController extends Controller { * @NoCSRFRequired * * @param $app string app name - * @return DataDisplayResponse + * @return FileDisplayResponse|DataDisplayResponse */ - public function getFavicon($app="core") { - if($this->themingDefaults->shouldReplaceIcons()) { + public function getFavicon($app = "core") { + $iconFile = $this->imageManager->getCachedImage('favIcon-' . $app); + if($iconFile === null && $this->themingDefaults->shouldReplaceIcons()) { $icon = $this->iconBuilder->getFavicon($app); - $response = new DataDisplayResponse($icon, Http::STATUS_OK, ['Content-Type' => 'image/x-icon']); + $iconFile = $this->imageManager->setCachedImage('favIcon-' . $app, $icon); + } + if ($this->themingDefaults->shouldReplaceIcons()) { + $response = new FileDisplayResponse($iconFile, Http::STATUS_OK, ['Content-Type' => 'image/x-icon']); } else { $response = new DataDisplayResponse(null, Http::STATUS_NOT_FOUND); } @@ -116,12 +134,16 @@ class IconController extends Controller { * @NoCSRFRequired * * @param $app string app name - * @return DataDisplayResponse + * @return FileDisplayResponse|DataDisplayResponse */ - public function getTouchIcon($app="core") { - if($this->themingDefaults->shouldReplaceIcons()) { + public function getTouchIcon($app = "core") { + $iconFile = $this->imageManager->getCachedImage('touchIcon-' . $app); + if ($iconFile === null && $this->themingDefaults->shouldReplaceIcons()) { $icon = $this->iconBuilder->getTouchIcon($app); - $response = new DataDisplayResponse($icon, Http::STATUS_OK, ['Content-Type' => 'image/png']); + $iconFile = $this->imageManager->setCachedImage('touchIcon-' . $app, $icon); + } + if ($this->themingDefaults->shouldReplaceIcons()) { + $response = new FileDisplayResponse($iconFile, Http::STATUS_OK, ['Content-Type' => 'image/png']); } else { $response = new DataDisplayResponse(null, Http::STATUS_NOT_FOUND); } @@ -130,5 +152,4 @@ class IconController extends Controller { $response->addHeader('Pragma', 'cache'); return $response; } - }
\ No newline at end of file diff --git a/apps/theming/lib/IconBuilder.php b/apps/theming/lib/IconBuilder.php index edd7602a2e4..10ba3cacc43 100644 --- a/apps/theming/lib/IconBuilder.php +++ b/apps/theming/lib/IconBuilder.php @@ -80,19 +80,21 @@ class IconBuilder { */ public function renderAppIcon($app) { $appIcon = $this->util->getAppIcon($app); + $appIconContent = file_get_contents($appIcon); $color = $this->themingDefaults->getMailHeaderColor(); $mime = mime_content_type($appIcon); + // generate background image with rounded corners $background = '<?xml version="1.0" encoding="UTF-8"?>' . '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:cc="http://creativecommons.org/ns#" width="512" height="512" xmlns:xlink="http://www.w3.org/1999/xlink">' . '<rect x="0" y="0" rx="75" ry="75" width="512" height="512" style="fill:' . $color . ';" />' . '</svg>'; - // resize svg magic as this seems broken in Imagemagick - if($mime === "image/svg+xml") { - $svg = file_get_contents($appIcon); - + if($mime === "image/svg+xml" || substr($appIconContent, 0, 4) === "<svg") { + if(substr($appIconContent, 0, 5) !== "<?xml") { + $svg = "<?xml version=\"1.0\"?>".$appIconContent; + } $tmp = new Imagick(); $tmp->readImageBlob($svg); $x = $tmp->getImageWidth(); @@ -137,4 +139,12 @@ class IconBuilder { return $finalIconFile; } + public function colorSvg($app, $image) { + $imageFile = $this->util->getAppImage($app, $image); + $svg = file_get_contents($imageFile); + $color = $this->util->elementColor($this->themingDefaults->getMailHeaderColor()); + $svg = $this->util->colorizeSvg($svg, $color); + return $svg; + } + }
\ No newline at end of file diff --git a/apps/theming/lib/ImageManager.php b/apps/theming/lib/ImageManager.php new file mode 100644 index 00000000000..5e1b61e3a92 --- /dev/null +++ b/apps/theming/lib/ImageManager.php @@ -0,0 +1,118 @@ +<?php +/** + * @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net> + * + * @author Julius Härtl <jus@bitgrid.net> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCA\Theming; + +use OCP\IConfig; +use OCP\Files\IAppData; +use OCP\Files\NotFoundException; +use OCP\Files\NotPermittedException; + +class ImageManager { + + /** @var IConfig */ + private $config; + /** @var IAppData */ + private $appData; + + /** + * ImageManager constructor. + * + * @param IConfig $config + * @param IAppData $appData + */ + public function __construct(IConfig $config, + IAppData $appData + ) { + $this->config = $config; + $this->appData = $appData; + } + + /** + * Get folder for current theming files + * + * @return \OCP\Files\SimpleFS\ISimpleFolder + * @throws NotPermittedException + * @throws \RuntimeException + */ + public function getCacheFolder() { + $cacheBusterValue = $this->config->getAppValue('theming', 'cachebuster', '0'); + try { + $folder = $this->appData->getFolder($cacheBusterValue); + } catch (NotFoundException $e) { + $folder = $this->appData->newFolder($cacheBusterValue); + $this->cleanup(); + } + return $folder; + } + + /** + * Get a file from AppData + * + * @param string $filename + * @return null|\OCP\Files\SimpleFS\ISimpleFile + */ + public function getCachedImage($filename) { + $currentFolder = $this->getCacheFolder(); + if($currentFolder->fileExists($filename)) { + return $currentFolder->getFile($filename); + } else { + return null; + } + } + + /** + * Store a file for theming in AppData + * + * @param string $filename + * @param string $data + * @return \OCP\Files\SimpleFS\ISimpleFile + */ + public function setCachedImage($filename, $data) { + $currentFolder = $this->getCacheFolder(); + if ($currentFolder->fileExists($filename)) { + $file = $currentFolder->getFile($filename); + } else { + $file = $currentFolder->newFile($filename); + } + $file->putContent($data); + return $file; + } + + /** + * remove cached files that are not required any longer + */ + public function cleanup() { + $currentFolder = $this->getCacheFolder(); + $folders = $this->appData->getDirectoryListing(); + foreach ($folders as $folder) { + if ($folder->getName() !== $currentFolder->getName()) { + $folder->delete(); + } + } + } + + + +} |