From 272b392cacdf34d2166105c91b0a06de3e51ed06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julius=20H=C3=A4rtl?= Date: Mon, 26 Feb 2018 13:54:00 +0100 Subject: Move to more generic image handling and add extra images MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Julius Härtl --- apps/theming/lib/Controller/IconController.php | 46 +++--- apps/theming/lib/Controller/ThemingController.php | 167 ++++++++-------------- 2 files changed, 87 insertions(+), 126 deletions(-) (limited to 'apps/theming/lib/Controller') diff --git a/apps/theming/lib/Controller/IconController.php b/apps/theming/lib/Controller/IconController.php index 7a5f76de6b6..61df7b0b353 100644 --- a/apps/theming/lib/Controller/IconController.php +++ b/apps/theming/lib/Controller/IconController.php @@ -33,21 +33,16 @@ use OCP\AppFramework\Http; use OCP\AppFramework\Http\NotFoundResponse; use OCP\AppFramework\Http\FileDisplayResponse; use OCP\AppFramework\Http\DataDisplayResponse; +use OCP\AppFramework\Http\Response; use OCP\AppFramework\Utility\ITimeFactory; use OCP\Files\NotFoundException; use OCP\IRequest; -use OCA\Theming\Util; -use OCP\IConfig; class IconController extends Controller { /** @var ThemingDefaults */ private $themingDefaults; - /** @var Util */ - private $util; /** @var ITimeFactory */ private $timeFactory; - /** @var IConfig */ - private $config; /** @var IconBuilder */ private $iconBuilder; /** @var ImageManager */ @@ -61,19 +56,16 @@ class IconController extends Controller { * @param string $appName * @param IRequest $request * @param ThemingDefaults $themingDefaults - * @param Util $util * @param ITimeFactory $timeFactory - * @param IConfig $config * @param IconBuilder $iconBuilder * @param ImageManager $imageManager + * @param FileAccessHelper $fileAccessHelper */ public function __construct( $appName, IRequest $request, ThemingDefaults $themingDefaults, - Util $util, ITimeFactory $timeFactory, - IConfig $config, IconBuilder $iconBuilder, ImageManager $imageManager, FileAccessHelper $fileAccessHelper @@ -81,9 +73,7 @@ class IconController extends Controller { parent::__construct($appName, $request); $this->themingDefaults = $themingDefaults; - $this->util = $util; $this->timeFactory = $timeFactory; - $this->config = $config; $this->iconBuilder = $iconBuilder; $this->imageManager = $imageManager; $this->fileAccessHelper = $fileAccessHelper; @@ -96,16 +86,17 @@ class IconController extends Controller { * @param $app string app name * @param $image string image file name (svg required) * @return FileDisplayResponse|NotFoundResponse + * @throws \Exception */ - public function getThemedIcon($app, $image) { + public function getThemedIcon(string $app, string $image): Response { try { - $iconFile = $this->imageManager->getCachedImage("icon-" . $app . '-' . str_replace("/","_",$image)); + $iconFile = $this->imageManager->getCachedImage('icon-' . $app . '-' . str_replace('/', '_',$image)); } catch (NotFoundException $exception) { $icon = $this->iconBuilder->colorSvg($app, $image); - if ($icon === false || $icon === "") { + if ($icon === false || $icon === '') { return new NotFoundResponse(); } - $iconFile = $this->imageManager->setCachedImage("icon-" . $app . '-' . str_replace("/","_",$image), $icon); + $iconFile = $this->imageManager->setCachedImage('icon-' . $app . '-' . str_replace('/', '_',$image), $icon); } if ($iconFile !== false) { $response = new FileDisplayResponse($iconFile, Http::STATUS_OK, ['Content-Type' => 'image/svg+xml']); @@ -116,9 +107,9 @@ class IconController extends Controller { $response->addHeader('Expires', $expires->format(\DateTime::RFC2822)); $response->addHeader('Pragma', 'cache'); return $response; - } else { - return new NotFoundResponse(); } + + return new NotFoundResponse(); } /** @@ -129,10 +120,17 @@ class IconController extends Controller { * * @param $app string app name * @return FileDisplayResponse|DataDisplayResponse + * @throws \Exception */ - public function getFavicon($app = "core") { + public function getFavicon(string $app = 'core'): Response { $response = null; - if ($this->themingDefaults->shouldReplaceIcons()) { + $iconFile = null; + try { + $iconFile = $this->imageManager->getImage('favicon'); + $response = new FileDisplayResponse($iconFile, Http::STATUS_OK, ['Content-Type' => 'image/x-icon']); + } catch (NotFoundException $e) { + } + if ($iconFile === null && $this->themingDefaults->shouldReplaceIcons()) { try { $iconFile = $this->imageManager->getCachedImage('favIcon-' . $app); } catch (NotFoundException $exception) { @@ -164,9 +162,15 @@ class IconController extends Controller { * * @param $app string app name * @return FileDisplayResponse|NotFoundResponse + * @throws \Exception */ - public function getTouchIcon($app = "core") { + public function getTouchIcon(string $app = 'core'): Response { $response = null; + try { + $iconFile = $this->imageManager->getImage('favicon'); + $response = new FileDisplayResponse($iconFile, Http::STATUS_OK, ['Content-Type' => 'image/x-icon']); + } catch (NotFoundException $e) { + } if ($this->themingDefaults->shouldReplaceIcons()) { try { $iconFile = $this->imageManager->getCachedImage('touchIcon-' . $app); diff --git a/apps/theming/lib/Controller/ThemingController.php b/apps/theming/lib/Controller/ThemingController.php index 47f806d16f9..fc282f20885 100644 --- a/apps/theming/lib/Controller/ThemingController.php +++ b/apps/theming/lib/Controller/ThemingController.php @@ -33,6 +33,7 @@ namespace OCA\Theming\Controller; use OC\Template\SCSSCacher; +use OCA\Theming\ImageManager; use OCA\Theming\ThemingDefaults; use OCP\AppFramework\Controller; use OCP\AppFramework\Http; @@ -81,6 +82,8 @@ class ThemingController extends Controller { private $urlGenerator; /** @var IAppManager */ private $appManager; + /** @var ImageManager */ + private $imageManager; /** * ThemingController constructor. @@ -110,7 +113,8 @@ class ThemingController extends Controller { IAppData $appData, SCSSCacher $scssCacher, IURLGenerator $urlGenerator, - IAppManager $appManager + IAppManager $appManager, + ImageManager $imageManager ) { parent::__construct($appName, $request); @@ -124,13 +128,15 @@ class ThemingController extends Controller { $this->scssCacher = $scssCacher; $this->urlGenerator = $urlGenerator; $this->appManager = $appManager; + $this->imageManager = $imageManager; } /** * @param string $setting * @param string $value * @return DataResponse - * @internal param string $color + * @throws NotFoundException + * @throws NotPermittedException */ public function updateStylesheet($setting, $value) { $value = trim($value); @@ -195,27 +201,15 @@ class ThemingController extends Controller { } /** - * Update the logos and background image - * * @return DataResponse + * @throws NotPermittedException */ - public function updateLogo() { - $backgroundColor = $this->request->getParam('backgroundColor', false); - if($backgroundColor) { - $this->themingDefaults->set('backgroundMime', 'backgroundColor'); - return new DataResponse( - [ - 'data' => - [ - 'name' => 'backgroundColor', - 'message' => $this->l10n->t('Saved') - ], - 'status' => 'success' - ] - ); - } - $newLogo = $this->request->getUploadedFile('uploadlogo'); - $newBackgroundLogo = $this->request->getUploadedFile('upload-login-background'); + public function uploadImage(): DataResponse { + // logo / background + // new: favicon logo-header + // + $key = $this->request->getParam('key'); + $image = $this->request->getUploadedFile('image'); $error = null; $phpFileUploadErrors = [ UPLOAD_ERR_OK => $this->l10n->t('The file was uploaded'), @@ -227,14 +221,11 @@ class ThemingController extends Controller { UPLOAD_ERR_CANT_WRITE => $this->l10n->t('Could not write file to disk'), UPLOAD_ERR_EXTENSION => $this->l10n->t('A PHP extension stopped the file upload'), ]; - if (empty($newLogo) && empty($newBackgroundLogo)) { + if (empty($image)) { $error = $this->l10n->t('No file uploaded'); } - if (!empty($newLogo) && array_key_exists('error', $newLogo) && $newLogo['error'] !== UPLOAD_ERR_OK) { - $error = $phpFileUploadErrors[$newLogo['error']]; - } - if (!empty($newBackgroundLogo) && array_key_exists('error', $newBackgroundLogo) && $newBackgroundLogo['error'] !== UPLOAD_ERR_OK) { - $error = $phpFileUploadErrors[$newBackgroundLogo['error']]; + if (!empty($image) && array_key_exists('error', $image) && $image['error'] !== UPLOAD_ERR_OK) { + $error = $phpFileUploadErrors[$image['error']]; } if ($error !== null) { @@ -256,61 +247,53 @@ class ThemingController extends Controller { $folder = $this->appData->newFolder('images'); } - if (!empty($newLogo)) { - $target = $folder->newFile('logo'); - $supportedFormats = ['image/jpeg', 'image/png', 'image/gif', 'image/svg+xml', 'text/svg']; - if (!in_array($newLogo['type'], $supportedFormats)) { - return new DataResponse( - [ - 'data' => [ - 'message' => $this->l10n->t('Unsupported image type'), - ], - 'status' => 'failure', + $target = $folder->newFile($key); + $supportedFormats = ['image/jpeg', 'image/png', 'image/gif', 'image/svg+xml', 'text/svg']; + if (!in_array($image['type'], $supportedFormats)) { + return new DataResponse( + [ + 'data' => [ + 'message' => $this->l10n->t('Unsupported image type'), ], - Http::STATUS_UNPROCESSABLE_ENTITY - ); - } - $target->putContent(file_get_contents($newLogo['tmp_name'], 'r')); - $this->themingDefaults->set('logoMime', $newLogo['type']); - $name = $newLogo['name']; + 'status' => 'failure', + ], + Http::STATUS_UNPROCESSABLE_ENTITY + ); } - if (!empty($newBackgroundLogo)) { - $target = $folder->newFile('background'); - $image = @imagecreatefromstring(file_get_contents($newBackgroundLogo['tmp_name'], 'r')); - if ($image === false) { - return new DataResponse( - [ - 'data' => [ - 'message' => $this->l10n->t('Unsupported image type'), - ], - 'status' => 'failure', - ], - Http::STATUS_UNPROCESSABLE_ENTITY - ); - } + $resizeKeys = ['background']; + if (in_array($key, $resizeKeys, true)) { // 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($image['tmp_name'], 'r')); + $tmpFile = $this->tempManager->getTemporaryFile(); - $newWidth = imagesx($image) < 4096 ? imagesx($image) : 4096; - $newHeight = imagesy($image) / (imagesx($image) / $newWidth); - $image = imagescale($image, $newWidth, $newHeight); + $newWidth = imagesx($newImage) < 4096 ? imagesx($newImage) : 4096; + $newHeight = imagesy($newImage) / (imagesx($newImage) / $newWidth); + $outputImage = imagescale($newImage, $newWidth, $newHeight); - imageinterlace($image, 1); - imagejpeg($image, $tmpFile, 75); - imagedestroy($image); + imageinterlace($outputImage, 1); + imagejpeg($outputImage, $tmpFile, 75); + imagedestroy($outputImage); $target->putContent(file_get_contents($tmpFile, 'r')); - $this->themingDefaults->set('backgroundMime', $newBackgroundLogo['type']); - $name = $newBackgroundLogo['name']; + } else { + $target->putContent(file_get_contents($image['tmp_name'], 'r')); } + $name = $image['name']; + + $this->themingDefaults->set($key.'Mime', $image['type']); + + $cssCached = $this->scssCacher->process(\OC::$SERVERROOT, 'core/css/server.scss', 'core'); return new DataResponse( [ 'data' => [ 'name' => $name, - 'message' => $this->l10n->t('Saved') + 'url' => $this->imageManager->getImageUrl($key), + 'message' => $this->l10n->t('Saved'), + 'serverCssUrl' => $this->urlGenerator->linkTo('', $this->scssCacher->getCachedSCSS('core', '/core/css/server.scss')) ], 'status' => 'success' ] @@ -322,23 +305,17 @@ class ThemingController extends Controller { * * @param string $setting setting which should be reverted * @return DataResponse + * @throws NotPermittedException */ - public function undo($setting) { + public function undo(string $setting): DataResponse { $value = $this->themingDefaults->undo($setting); // reprocess server scss for preview $cssCached = $this->scssCacher->process(\OC::$SERVERROOT, 'core/css/server.scss', 'core'); - if($setting === 'logoMime') { + if (strpos($setting, 'Mime') !== -1) { + $imageKey = str_replace('Mime', '', $setting); try { - $file = $this->appData->getFolder('images')->getFile('logo'); - $file->delete(); - } catch (NotFoundException $e) { - } catch (NotPermittedException $e) { - } - } - if($setting === 'backgroundMime') { - try { - $file = $this->appData->getFolder('images')->getFile('background'); + $file = $this->appData->getFolder('images')->getFile($imageKey); $file->delete(); } catch (NotFoundException $e) { } catch (NotPermittedException $e) { @@ -362,37 +339,14 @@ class ThemingController extends Controller { * @PublicPage * @NoCSRFRequired * + * @param string $key * @return FileDisplayResponse|NotFoundResponse + * @throws \Exception */ - public function getLogo() { - try { - /** @var File $file */ - $file = $this->appData->getFolder('images')->getFile('logo'); - } catch (NotFoundException $e) { - return new NotFoundResponse(); - } - - $response = new FileDisplayResponse($file); - $response->cacheFor(3600); - $expires = new \DateTime(); - $expires->setTimestamp($this->timeFactory->getTime()); - $expires->add(new \DateInterval('PT24H')); - $response->addHeader('Expires', $expires->format(\DateTime::RFC2822)); - $response->addHeader('Pragma', 'cache'); - $response->addHeader('Content-Type', $this->config->getAppValue($this->appName, 'logoMime', '')); - return $response; - } - - /** - * @PublicPage - * @NoCSRFRequired - * - * @return FileDisplayResponse|NotFoundResponse - */ - public function getLoginBackground() { + public function getImage(string $key) { try { /** @var File $file */ - $file = $this->appData->getFolder('images')->getFile('background'); + $file = $this->appData->getFolder('images')->getFile($key); } catch (NotFoundException $e) { return new NotFoundResponse(); } @@ -404,7 +358,7 @@ class ThemingController extends Controller { $expires->add(new \DateInterval('PT24H')); $response->addHeader('Expires', $expires->format(\DateTime::RFC2822)); $response->addHeader('Pragma', 'cache'); - $response->addHeader('Content-Type', $this->config->getAppValue($this->appName, 'backgroundMime', '')); + $response->addHeader('Content-Type', $this->config->getAppValue($this->appName, $key . 'Mime', '')); return $response; } @@ -413,6 +367,9 @@ class ThemingController extends Controller { * @PublicPage * * @return FileDisplayResponse|NotFoundResponse + * @throws NotPermittedException + * @throws \Exception + * @throws \OCP\App\AppPathNotFoundException */ public function getStylesheet() { $appPath = $this->appManager->getAppPath('theming'); -- cgit v1.2.3