summaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
authorMorris Jobke <hey@morrisjobke.de>2018-04-25 08:47:14 +0200
committerGitHub <noreply@github.com>2018-04-25 08:47:14 +0200
commitb3a0dec8d54e28aa9f3e91cd93877946f58d696a (patch)
tree6c603a06c82d42f9817800a332af1e26c2e4c433 /apps
parent3e14f21ae76a591902fddae74cafa958a0b4a0a8 (diff)
parentd771f6591153ff1ceabe69e0e1f91e99a1873eb0 (diff)
downloadnextcloud-server-b3a0dec8d54e28aa9f3e91cd93877946f58d696a.tar.gz
nextcloud-server-b3a0dec8d54e28aa9f3e91cd93877946f58d696a.zip
Merge pull request #8540 from nextcloud/theming-advanced
Add option for header logo and favicon in theming app
Diffstat (limited to 'apps')
-rw-r--r--apps/theming/appinfo/routes.php13
-rw-r--r--apps/theming/css/settings-admin.css107
-rw-r--r--apps/theming/css/settings-admin.scss120
-rw-r--r--apps/theming/css/theming.scss47
-rw-r--r--apps/theming/js/settings-admin.js114
-rw-r--r--apps/theming/lib/Controller/IconController.php46
-rw-r--r--apps/theming/lib/Controller/ThemingController.php173
-rw-r--r--apps/theming/lib/ImageManager.php85
-rw-r--r--apps/theming/lib/Settings/Admin.php24
-rw-r--r--apps/theming/lib/ThemingDefaults.php53
-rw-r--r--apps/theming/templates/settings-admin.php44
-rw-r--r--apps/theming/tests/Controller/IconControllerTest.php44
-rw-r--r--apps/theming/tests/Controller/ThemingControllerTest.php198
-rw-r--r--apps/theming/tests/ImageManagerTest.php111
-rw-r--r--apps/theming/tests/Settings/AdminTest.php31
-rw-r--r--apps/theming/tests/ThemingDefaultsTest.php123
16 files changed, 713 insertions, 620 deletions
diff --git a/apps/theming/appinfo/routes.php b/apps/theming/appinfo/routes.php
index a69ddc1a6c9..f3483dbf99b 100644
--- a/apps/theming/appinfo/routes.php
+++ b/apps/theming/appinfo/routes.php
@@ -39,8 +39,8 @@ return ['routes' => [
'verb' => 'POST'
],
[
- 'name' => 'Theming#updateLogo',
- 'url' => '/ajax/updateLogo',
+ 'name' => 'Theming#uploadImage',
+ 'url' => '/ajax/uploadImage',
'verb' => 'POST'
],
[
@@ -49,13 +49,8 @@ return ['routes' => [
'verb' => 'GET',
],
[
- 'name' => 'Theming#getLogo',
- 'url' => '/logo',
- 'verb' => 'GET',
- ],
- [
- 'name' => 'Theming#getLoginBackground',
- 'url' => '/loginbackground',
+ 'name' => 'Theming#getImage',
+ 'url' => '/image/{key}',
'verb' => 'GET',
],
[
diff --git a/apps/theming/css/settings-admin.css b/apps/theming/css/settings-admin.css
deleted file mode 100644
index b0fdb79b291..00000000000
--- a/apps/theming/css/settings-admin.css
+++ /dev/null
@@ -1,107 +0,0 @@
-#theming input {
- width: 230px;
-}
-
-#theming input:focus,
-#theming input:active {
- padding-right: 30px;
-}
-
-#theming .upload-logo-field {
- display: none;
-}
-
-#theming div > label {
- position: relative;
-}
-
-#theming .theme-undo {
- position: absolute;
- top: -7px;
- right: 7px;
- cursor: pointer;
- opacity: .3;
- padding: 7px;
- vertical-align: top;
- display: inline-block;
- visibility: hidden;
-}
-form.uploadButton {
- width: 356px;
-}
-#theming form .theme-undo,
-#theming .theme-remove-bg {
- cursor: pointer;
- opacity: .3;
- padding: 7px;
- vertical-align: top;
- display: inline-block;
- float: right;
- position: relative;
- top: 4px;
- right: 0px;
- visibility: visible;
-}
-#theming input[type='text']:hover + .theme-undo,
-#theming input[type='text'] + .theme-undo:hover,
-#theming input[type='text']:focus + .theme-undo,
-#theming input[type='text']:active + .theme-undo {
- visibility: visible;
-}
-
-#theming label span {
- display: inline-block;
- min-width: 120px;
- padding: 8px 0px;
- vertical-align: top;
-}
-
-#theming .icon-upload,
-#theming .uploadButton .icon-loading-small {
- padding: 8px 20px;
- width: 20px;
- margin: 2px 0px;
- min-height: 32px;
- display: inline-block;
-}
-
-#theming_settings_status {
- height: 26px;
- margin: 10px;
-}
-
-#theming_settings_loading {
- display: inline-block;
- vertical-align: middle;
- margin-right: 10px;
-}
-
-#theming_settings_msg {
- vertical-align: middle;
- border-radius: 3px;
-}
-
-#theming-preview-logo {
- cursor: pointer;
-}
-
-#theming-preview {
- width: 230px;
- height: 140px;
- background-size: cover;
- background-position: center center;
- text-align: center;
- margin-left: 123px;
- margin-top: 10px;
- cursor: pointer;
-}
-
-#theming-preview img {
- max-width: 20%;
- max-height: 20%;
- margin-top: 20px;
-}
-
-.theming-hints {
- margin-top: 20px;
-} \ No newline at end of file
diff --git a/apps/theming/css/settings-admin.scss b/apps/theming/css/settings-admin.scss
new file mode 100644
index 00000000000..ceb560f0f02
--- /dev/null
+++ b/apps/theming/css/settings-admin.scss
@@ -0,0 +1,120 @@
+#theming {
+ input {
+ width: 230px;
+ }
+
+ input:focus,
+ input:active {
+ padding-right: 30px;
+ }
+
+ .fileupload {
+ display: none;
+ }
+
+ div > label {
+ position: relative;
+ }
+
+ .theme-undo {
+ position: absolute;
+ top: -7px;
+ right: 7px;
+ cursor: pointer;
+ opacity: .3;
+ padding: 7px;
+ vertical-align: top;
+ display: inline-block;
+ visibility: hidden;
+ }
+ form.uploadButton {
+ width: 356px;
+ }
+ form .theme-undo,
+ .theme-remove-bg {
+ cursor: pointer;
+ opacity: .3;
+ padding: 7px;
+ vertical-align: top;
+ display: inline-block;
+ float: right;
+ position: relative;
+ top: 4px;
+ right: 0px;
+ visibility: visible;
+ }
+ input[type='text']:hover + .theme-undo,
+ input[type='text'] + .theme-undo:hover,
+ input[type='text']:focus + .theme-undo,
+ input[type='text']:active + .theme-undo {
+ visibility: visible;
+ }
+
+ label span {
+ display: inline-block;
+ min-width: 120px;
+ padding: 8px 0px;
+ vertical-align: top;
+ }
+
+ .icon-upload,
+ .uploadButton .icon-loading-small {
+ padding: 8px 20px;
+ width: 20px;
+ margin: 2px 0px;
+ min-height: 32px;
+ display: inline-block;
+ }
+
+ #theming_settings_status {
+ height: 26px;
+ margin: 10px;
+ }
+
+ #theming_settings_loading {
+ display: inline-block;
+ vertical-align: middle;
+ margin-right: 10px;
+ }
+
+ #theming_settings_msg {
+ vertical-align: middle;
+ border-radius: 3px;
+ }
+
+ #theming-preview {
+ width: 230px;
+ height: 140px;
+ background-size: cover;
+ background-position: center center;
+ text-align: center;
+ margin-left: 123px;
+ margin-top: 10px;
+ margin-bottom: 20px;
+ cursor: pointer;
+
+ #theming-preview-logo {
+ cursor: pointer;
+ width: 20%;
+ height: 20%;
+ margin-top: 20px;
+ display: inline-block;
+ background-position: center;
+ background-repeat: no-repeat;
+ background-size: contain;
+ }
+ }
+
+ .theming-hints {
+ margin-top: 20px;
+ }
+
+ .image-preview {
+ display: inline-block;
+ width: 80px;
+ height: 36px;
+ background-position: center;
+ background-repeat: no-repeat;
+ background-size: contain;
+ }
+} \ No newline at end of file
diff --git a/apps/theming/css/theming.scss b/apps/theming/css/theming.scss
index 3bb26a14814..f65e20fa9b7 100644
--- a/apps/theming/css/theming.scss
+++ b/apps/theming/css/theming.scss
@@ -92,6 +92,7 @@
/* override styles for login screen in guest.css */
@if variable_exists('theming-logo-mime') and $theming-logo-mime != '' {
+ #theming-preview-logo,
#header .logo {
background-image: url(#{$image-logo});
background-size: contain;
@@ -99,13 +100,45 @@
#body-login #header .logo {
margin-bottom: 22px;
}
+} @else {
+ #theming-preview-logo {
+ background-image: url(#{$image-logo});
+ }
}
-#body-login,
-#firstrunwizard .firstrunwizard-header,
-#theming-preview {
- background-image: url(#{$image-login-background});
- background-color: $color-primary;
+@if variable_exists('theming-background-mime') and $theming-background-mime != '' {
+ #body-login,
+ #firstrunwizard .firstrunwizard-header,
+ #theming-preview {
+ background-image: url(#{$image-login-background});
+ background-color: $color-primary;
+ }
+} @else {
+ #theming-preview {
+ background-image: url(#{$image-login-background});
+ background-color: $color-primary;
+ }
+}
+
+@if variable_exists('theming-logoheader-mime') and $theming-logoheader-mime != '' {
+ #theming .advanced-option-logoheader .image-preview,
+ body:not(#body-login) #header .logo {
+ background-image: url(#{$image-logoheader});
+ }
+} @else {
+ #theming .advanced-option-favicon .image-preview {
+ background-image: none;
+ }
+}
+
+@if variable_exists('theming-favicon-mime') and $theming-favicon-mime != '' {
+ #theming .advanced-option-favicon .image-preview {
+ background-image: url(#{$image-favicon});
+ }
+} @else {
+ #theming .advanced-option-favicon .image-preview {
+ background-image: none;
+ }
}
input.primary,
@@ -134,6 +167,10 @@ input.primary,
}
}
+} @else {
+ #body-login {
+ background-color: $color-primary;
+ }
}
@if ($color-primary == #ffffff) {
diff --git a/apps/theming/js/settings-admin.js b/apps/theming/js/settings-admin.js
index 1f416bb2940..25ac092a964 100644
--- a/apps/theming/js/settings-admin.js
+++ b/apps/theming/js/settings-admin.js
@@ -35,7 +35,6 @@ function setThemingValue(setting, value) {
OC.msg.finishedSaving('#theming_settings_msg', response);
$('#theming_settings_loading').hide();
});
-
}
function preview(setting, value, serverCssUrl) {
@@ -69,17 +68,6 @@ function preview(setting, value, serverCssUrl) {
}
reloadStylesheets(OC.generateUrl('/apps/theming/styles'));
- // Preview images
- var timestamp = new Date().getTime();
- if (setting === 'logoMime') {
- var previewImageLogo = document.getElementById('theming-preview-logo');
- if (value !== '') {
- previewImageLogo.src = OC.generateUrl('/apps/theming/logo') + "?v" + timestamp;
- } else {
- previewImageLogo.src = OC.getRootPath() + '/core/img/logo.svg?v' + timestamp;
- }
- }
-
if (setting === 'name') {
window.document.title = t('core', 'Admin') + " - " + value;
}
@@ -119,53 +107,36 @@ $(document).ready(function () {
$('#theming .theme-undo').each(function() {
var setting = $(this).data('setting');
var value = $('#theming-'+setting).val();
- if(setting === 'logoMime' || setting === 'backgroundMime') {
- var value = $('#current-'+setting).val();
- }
hideUndoButton(setting, value);
});
- var uploadParamsLogo = {
- pasteZone: null,
- dropZone: null,
- done: function (e, response) {
- preview('logoMime', response.result.data.name);
- OC.msg.finishedSaving('#theming_settings_msg', response.result);
- $('label#uploadlogo').addClass('icon-upload').removeClass('icon-loading-small');
- $('.theme-undo[data-setting=logoMime]').show();
- },
- submit: function(e, response) {
- startLoading();
- $('label#uploadlogo').removeClass('icon-upload').addClass('icon-loading-small');
- },
- fail: function (e, response){
- OC.msg.finishedError('#theming_settings_msg', response._response.jqXHR.responseJSON.data.message);
- $('label#uploadlogo').addClass('icon-upload').removeClass('icon-loading-small');
- $('#theming_settings_loading').hide();
- }
- };
- var uploadParamsLogin = {
+ $('.fileupload').fileupload({
pasteZone: null,
dropZone: null,
done: function (e, response) {
- preview('backgroundMime', response.result.data.name);
+ var $form = $(e.target).closest('form');
+ var key = $form.data('image-key');
+
+ preview(key + 'Mime', response.result.data.name, response.result.data.serverCssUrl);
+ $form.find('.image-preview').css('backgroundImage', response.result.data.url + '?v=' + new Date().getTime());
OC.msg.finishedSaving('#theming_settings_msg', response.result);
- $('label#upload-login-background').addClass('icon-upload').removeClass('icon-loading-small');
- $('.theme-undo[data-setting=backgroundMime]').show();
+ $form.find('label.button').addClass('icon-upload').removeClass('icon-loading-small');
+ $form.find('.theme-undo').show();
},
submit: function(e, response) {
+ var $form = $(e.target).closest('form');
+ var key = $form.data('image-key');
startLoading();
- $('label#upload-login-background').removeClass('icon-upload').addClass('icon-loading-small');
+ $form.find('label.button').removeClass('icon-upload').addClass('icon-loading-small');
},
fail: function (e, response){
- $('label#upload-login-background').removeClass('icon-loading-small').addClass('icon-upload');
+ var $form = $(e.target).closest('form');
OC.msg.finishedError('#theming_settings_msg', response._response.jqXHR.responseJSON.data.message);
+ $form.find('label.button').addClass('icon-upload').removeClass('icon-loading-small');
$('#theming_settings_loading').hide();
}
- };
+ });
- $('#uploadlogo').fileupload(uploadParamsLogo);
- $('#upload-login-background').fileupload(uploadParamsLogin);
// clicking preview should also trigger file upload dialog
$('#theming-preview-logo').on('click', function(e) {
e.stopPropagation();
@@ -202,46 +173,42 @@ $(document).ready(function () {
$('#theming-name').change(function(e) {
var el = $(this);
- if(checkName()){
- $.when(el.focusout()).then(function() {
- setThemingValue('name', $(this).val());
- });
- if (e.keyCode == 13) {
- setThemingValue('name', $(this).val());
- }
- }
});
- $('#theming-url').change(function(e) {
+ $('#theming input[type=text]').change(function(e) {
var el = $(this);
- $.when(el.focusout()).then(function() {
- setThemingValue('url', $(this).val());
- });
- if (e.keyCode == 13) {
- setThemingValue('url', $(this).val());
+ var setting = el.parent().find('div[data-setting]').data('setting');
+ var value = $(this).val();
+
+ if(setting === 'color') {
+ if (value.indexOf('#') !== 0) {
+ value = '#' + value;
+ }
+ }
+ if(setting === 'name') {
+ if(checkName()){
+ $.when(el.focusout()).then(function() {
+ setThemingValue('name', value);
+ });
+ if (e.keyCode == 13) {
+ setThemingValue('name', value);
+ }
+ }
}
- });
- $('#theming-slogan').change(function(e) {
- var el = $(this);
$.when(el.focusout()).then(function() {
- setThemingValue('slogan', $(this).val());
+ setThemingValue(setting, value);
});
if (e.keyCode == 13) {
- setThemingValue('slogan', $(this).val());
+ setThemingValue(setting, value);
}
});
- $('#theming-color').change(function (e) {
- var color = $(this).val();
- if (color.indexOf('#') !== 0) {
- color = '#' + color;
- }
- setThemingValue('color', color);
- });
-
$('.theme-undo').click(function (e) {
var setting = $(this).data('setting');
+ var $form = $(this).closest('form');
+ var image = $form.data('image-key');
+
startLoading();
$('.theme-undo[data-setting=' + setting + ']').hide();
$.post(
@@ -251,7 +218,7 @@ $(document).ready(function () {
var colorPicker = document.getElementById('theming-color');
colorPicker.style.backgroundColor = response.data.value;
colorPicker.value = response.data.value.slice(1).toUpperCase();
- } else if (setting !== 'logoMime' && setting !== 'backgroundMime') {
+ } else if (!image) {
var input = document.getElementById('theming-'+setting);
input.value = response.data.value;
}
@@ -262,11 +229,12 @@ $(document).ready(function () {
$('.theme-remove-bg').click(function() {
startLoading();
$.post(
- OC.generateUrl('/apps/theming/ajax/updateLogo'), {'backgroundColor' : true}
+ OC.generateUrl('/apps/theming/ajax/updateStylesheet'), {'setting' : 'backgroundMime', 'value' : 'backgroundColor'}
).done(function(response) {
- preview('backgroundMime', 'backgroundColor');
+ preview('backgroundMime', 'backgroundColor', response.data.serverCssUrl);
}).fail(function(response) {
OC.msg.finishedSaving('#theming_settings_msg', response);
+ $('#theming_settings_loading').hide();
});
});
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..421af051998 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.
@@ -97,6 +100,7 @@ class ThemingController extends Controller {
* @param SCSSCacher $scssCacher
* @param IURLGenerator $urlGenerator
* @param IAppManager $appManager
+ * @param ImageManager $imageManager
*/
public function __construct(
$appName,
@@ -110,7 +114,8 @@ class ThemingController extends Controller {
IAppData $appData,
SCSSCacher $scssCacher,
IURLGenerator $urlGenerator,
- IAppManager $appManager
+ IAppManager $appManager,
+ ImageManager $imageManager
) {
parent::__construct($appName, $request);
@@ -124,13 +129,14 @@ 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 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,27 +305,16 @@ 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') {
- 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->delete();
- } catch (NotFoundException $e) {
- } catch (NotPermittedException $e) {
- }
+ if (strpos($setting, 'Mime') !== -1) {
+ $imageKey = str_replace('Mime', '', $setting);
+ $this->imageManager->delete($imageKey);
}
return new DataResponse(
@@ -362,37 +334,13 @@ 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->imageManager->getImage($key);
} catch (NotFoundException $e) {
return new NotFoundResponse();
}
@@ -404,7 +352,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 +361,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');
diff --git a/apps/theming/lib/ImageManager.php b/apps/theming/lib/ImageManager.php
index 14dba0d0742..830ed7f34a9 100644
--- a/apps/theming/lib/ImageManager.php
+++ b/apps/theming/lib/ImageManager.php
@@ -24,11 +24,17 @@
namespace OCA\Theming;
+use OCP\Files\SimpleFS\ISimpleFile;
+use OCP\Files\SimpleFS\ISimpleFolder;
use OCP\IConfig;
use OCP\Files\IAppData;
use OCP\Files\NotFoundException;
use OCP\Files\NotPermittedException;
+use OCP\IURLGenerator;
+/**
+ * @property IURLGenerator urlGenerator
+ */
class ImageManager {
/** @var IConfig */
@@ -36,27 +42,79 @@ class ImageManager {
/** @var IAppData */
private $appData;
+ /** @var array */
+ private $supportedImageKeys = ['background', 'logo', 'logoheader', 'favicon'];
+
/**
* ImageManager constructor.
*
* @param IConfig $config
* @param IAppData $appData
+ * @param IURLGenerator $urlGenerator
*/
public function __construct(IConfig $config,
- IAppData $appData
+ IAppData $appData,
+ IURLGenerator $urlGenerator
) {
$this->config = $config;
$this->appData = $appData;
+ $this->urlGenerator = $urlGenerator;
+ }
+
+ public function getImageUrl(string $key): string {
+ $cacheBusterCounter = $this->config->getAppValue('theming', 'cachebuster', '0');
+ try {
+ $this->getImage($key);
+ return $this->urlGenerator->linkToRoute('theming.Theming.getImage', [ 'key' => $key ]) . '?v=' . $cacheBusterCounter;
+ } catch (NotFoundException $e) {
+ }
+
+ switch ($key) {
+ case 'logo':
+ case 'logoheader':
+ case 'favicon':
+ return $this->urlGenerator->imagePath('core', 'logo.png') . '?v=' . $cacheBusterCounter;
+ case 'background':
+ return $this->urlGenerator->imagePath('core', 'background.png') . '?v=' . $cacheBusterCounter;
+ }
+ }
+
+ public function getImageUrlAbsolute(string $key): string {
+ return $this->urlGenerator->getAbsoluteURL($this->getImageUrl($key));
+ }
+
+ /**
+ * @param $key
+ * @return ISimpleFile
+ * @throws NotFoundException
+ */
+ public function getImage(string $key): ISimpleFile {
+ $logo = $this->config->getAppValue('theming', $key . 'Mime', false);
+ if ($logo === false) {
+ throw new NotFoundException();
+ }
+ $folder = $this->appData->getFolder('images');
+ return $folder->getFile($key);
+ }
+
+ public function getCustomImages(): array {
+ $images = [];
+ foreach ($this->supportedImageKeys as $key) {
+ $images[$key] = [
+ 'mime' => $this->config->getAppValue('theming', $key . 'Mime', ''),
+ 'url' => $this->getImageUrl($key),
+ ];
+ }
+ return $images;
}
/**
* Get folder for current theming files
*
- * @return \OCP\Files\SimpleFS\ISimpleFolder
+ * @return ISimpleFolder
* @throws NotPermittedException
- * @throws \RuntimeException
*/
- public function getCacheFolder() {
+ public function getCacheFolder(): ISimpleFolder {
$cacheBusterValue = $this->config->getAppValue('theming', 'cachebuster', '0');
try {
$folder = $this->appData->getFolder($cacheBusterValue);
@@ -73,8 +131,9 @@ class ImageManager {
* @param string $filename
* @throws NotFoundException
* @return \OCP\Files\SimpleFS\ISimpleFile
+ * @throws NotPermittedException
*/
- public function getCachedImage($filename) {
+ public function getCachedImage(string $filename): ISimpleFile {
$currentFolder = $this->getCacheFolder();
return $currentFolder->getFile($filename);
}
@@ -85,8 +144,10 @@ class ImageManager {
* @param string $filename
* @param string $data
* @return \OCP\Files\SimpleFS\ISimpleFile
+ * @throws NotFoundException
+ * @throws NotPermittedException
*/
- public function setCachedImage($filename, $data) {
+ public function setCachedImage(string $filename, string $data): ISimpleFile {
$currentFolder = $this->getCacheFolder();
if ($currentFolder->fileExists($filename)) {
$file = $currentFolder->getFile($filename);
@@ -97,8 +158,20 @@ class ImageManager {
return $file;
}
+ public function delete(string $key) {
+ try {
+ $file = $this->appData->getFolder('images')->getFile($key);
+ $file->delete();
+ } catch (NotFoundException $e) {
+ } catch (NotPermittedException $e) {
+ }
+ }
+
/**
* remove cached files that are not required any longer
+ *
+ * @throws NotPermittedException
+ * @throws NotFoundException
*/
public function cleanup() {
$currentFolder = $this->getCacheFolder();
diff --git a/apps/theming/lib/Settings/Admin.php b/apps/theming/lib/Settings/Admin.php
index d26a5680637..7c937f19790 100644
--- a/apps/theming/lib/Settings/Admin.php
+++ b/apps/theming/lib/Settings/Admin.php
@@ -29,6 +29,7 @@
namespace OCA\Theming\Settings;
+use OCA\Theming\ImageManager;
use OCA\Theming\ThemingDefaults;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\IConfig;
@@ -45,23 +46,25 @@ class Admin implements ISettings {
private $themingDefaults;
/** @var IURLGenerator */
private $urlGenerator;
+ /** @var ImageManager */
+ private $imageManager;
public function __construct(IConfig $config,
IL10N $l,
ThemingDefaults $themingDefaults,
- IURLGenerator $urlGenerator) {
+ IURLGenerator $urlGenerator,
+ ImageManager $imageManager) {
$this->config = $config;
$this->l = $l;
$this->themingDefaults = $themingDefaults;
$this->urlGenerator = $urlGenerator;
+ $this->imageManager = $imageManager;
}
/**
* @return TemplateResponse
*/
- public function getForm() {
- $path = $this->urlGenerator->linkToRoute('theming.Theming.updateLogo');
-
+ public function getForm(): TemplateResponse {
$themable = true;
$errorMessage = '';
$theme = $this->config->getSystemValue('theme', '');
@@ -77,13 +80,10 @@ class Admin implements ISettings {
'url' => $this->themingDefaults->getBaseUrl(),
'slogan' => $this->themingDefaults->getSlogan(),
'color' => $this->themingDefaults->getColorPrimary(),
- 'logo' => $this->themingDefaults->getLogo(),
- 'logoMime' => $this->config->getAppValue('theming', 'logoMime', ''),
- 'background' => $this->themingDefaults->getBackground(),
- 'backgroundMime' => $this->config->getAppValue('theming', 'backgroundMime', ''),
- 'uploadLogoRoute' => $path,
+ 'uploadLogoRoute' => $this->urlGenerator->linkToRoute('theming.Theming.uploadImage'),
'canThemeIcons' => $this->themingDefaults->shouldReplaceIcons(),
- 'iconDocs' => $this->urlGenerator->linkToDocs('admin-theming-icons')
+ 'iconDocs' => $this->urlGenerator->linkToDocs('admin-theming-icons'),
+ 'images' => $this->imageManager->getCustomImages(),
];
return new TemplateResponse('theming', 'settings-admin', $parameters, '');
@@ -92,7 +92,7 @@ class Admin implements ISettings {
/**
* @return string the section ID, e.g. 'sharing'
*/
- public function getSection() {
+ public function getSection(): string {
return 'theming';
}
@@ -103,7 +103,7 @@ class Admin implements ISettings {
*
* E.g.: 70
*/
- public function getPriority() {
+ public function getPriority(): int {
return 5;
}
diff --git a/apps/theming/lib/ThemingDefaults.php b/apps/theming/lib/ThemingDefaults.php
index ce4ab0abb55..2e6b667b1f6 100644
--- a/apps/theming/lib/ThemingDefaults.php
+++ b/apps/theming/lib/ThemingDefaults.php
@@ -36,7 +36,7 @@ namespace OCA\Theming;
use OCP\App\AppPathNotFoundException;
use OCP\App\IAppManager;
-use OCP\Files\IAppData;
+use OCP\Files\NotFoundException;
use OCP\ICacheFactory;
use OCP\IConfig;
use OCP\IL10N;
@@ -48,10 +48,10 @@ class ThemingDefaults extends \OC_Defaults {
private $config;
/** @var IL10N */
private $l;
+ /** @var ImageManager */
+ private $imageManager;
/** @var IURLGenerator */
private $urlGenerator;
- /** @var IAppData */
- private $appData;
/** @var ICacheFactory */
private $cacheFactory;
/** @var Util */
@@ -83,9 +83,8 @@ class ThemingDefaults extends \OC_Defaults {
*
* @param IConfig $config
* @param IL10N $l
+ * @param ImageManager $imageManager
* @param IURLGenerator $urlGenerator
- * @param \OC_Defaults $defaults
- * @param IAppData $appData
* @param ICacheFactory $cacheFactory
* @param Util $util
* @param IAppManager $appManager
@@ -93,16 +92,16 @@ class ThemingDefaults extends \OC_Defaults {
public function __construct(IConfig $config,
IL10N $l,
IURLGenerator $urlGenerator,
- IAppData $appData,
ICacheFactory $cacheFactory,
Util $util,
+ ImageManager $imageManager,
IAppManager $appManager
) {
parent::__construct();
$this->config = $config;
$this->l = $l;
+ $this->imageManager = $imageManager;
$this->urlGenerator = $urlGenerator;
- $this->appData = $appData;
$this->cacheFactory = $cacheFactory;
$this->util = $util;
$this->appManager = $appManager;
@@ -166,12 +165,12 @@ class ThemingDefaults extends \OC_Defaults {
* @param bool $useSvg Whether to point to the SVG image or a fallback
* @return string
*/
- public function getLogo($useSvg = true) {
+ public function getLogo($useSvg = true): string {
$logo = $this->config->getAppValue('theming', 'logoMime', false);
$logoExists = true;
try {
- $this->appData->getFolder('images')->getFile('logo');
+ $this->imageManager->getImage('logo');
} catch (\Exception $e) {
$logoExists = false;
}
@@ -187,7 +186,7 @@ class ThemingDefaults extends \OC_Defaults {
return $logo . '?v=' . $cacheBusterCounter;
}
- return $this->urlGenerator->linkToRoute('theming.Theming.getLogo') . '?v=' . $cacheBusterCounter;
+ return $this->urlGenerator->linkToRoute('theming.Theming.getImage', [ 'key' => 'logo' ]) . '?v=' . $cacheBusterCounter;
}
/**
@@ -195,14 +194,8 @@ class ThemingDefaults extends \OC_Defaults {
*
* @return string
*/
- public function getBackground() {
- $cacheBusterCounter = $this->config->getAppValue('theming', 'cachebuster', '0');
-
- if($this->util->isBackgroundThemed()) {
- return $this->urlGenerator->linkToRoute('theming.Theming.getLoginBackground') . '?v=' . $cacheBusterCounter;
- }
-
- return $this->urlGenerator->imagePath('core','background.png') . '?v=' . $cacheBusterCounter;
+ public function getBackground(): string {
+ return $this->imageManager->getImageUrl('background');
}
/**
@@ -238,12 +231,16 @@ class ThemingDefaults extends \OC_Defaults {
$variables = [
'theming-cachebuster' => "'" . $this->config->getAppValue('theming', 'cachebuster', '0') . "'",
- 'theming-logo-mime' => "'" . $this->config->getAppValue('theming', 'logoMime', '') . "'",
- 'theming-background-mime' => "'" . $this->config->getAppValue('theming', 'backgroundMime', '') . "'"
+ 'theming-logo-mime' => "'" . $this->config->getAppValue('theming', 'logoMime') . "'",
+ 'theming-background-mime' => "'" . $this->config->getAppValue('theming', 'backgroundMime') . "'",
+ 'theming-logoheader-mime' => "'" . $this->config->getAppValue('theming', 'logoheaderMime') . "'",
+ 'theming-favicon-mime' => "'" . $this->config->getAppValue('theming', 'faviconMime') . "'"
];
- $variables['image-logo'] = "'".$this->getLogo()."'";
- $variables['image-login-background'] = "'".$this->getBackground()."'";
+ $variables['image-logo'] = "'".$this->imageManager->getImageUrl('logo')."'";
+ $variables['image-logoheader'] = "'".$this->imageManager->getImageUrl('logoheader')."'";
+ $variables['image-favicon'] = "'".$this->imageManager->getImageUrl('favicon')."'";
+ $variables['image-login-background'] = "'".$this->imageManager->getImageUrl('background')."'";
$variables['image-login-plain'] = 'false';
if ($this->config->getAppValue('theming', 'color', null) !== null) {
@@ -273,10 +270,16 @@ class ThemingDefaults extends \OC_Defaults {
}
$cacheBusterValue = $this->config->getAppValue('theming', 'cachebuster', '0');
- if ($image === 'favicon.ico' && $this->shouldReplaceIcons()) {
+ try {
+ $customFavicon = $this->imageManager->getImage('favicon');
+ } catch (NotFoundException $e) {
+ $customFavicon = null;
+ }
+
+ if ($image === 'favicon.ico' && ($customFavicon !== null || $this->shouldReplaceIcons())) {
return $this->urlGenerator->linkToRoute('theming.Icon.getFavicon', ['app' => $app]) . '?v=' . $cacheBusterValue;
}
- if ($image === 'favicon-touch.png' && $this->shouldReplaceIcons()) {
+ if ($image === 'favicon-touch.png' && ($customFavicon !== null || $this->shouldReplaceIcons())) {
return $this->urlGenerator->linkToRoute('theming.Icon.getTouchIcon', ['app' => $app]) . '?v=' . $cacheBusterValue;
}
if ($image === 'manifest.json') {
@@ -321,6 +324,8 @@ class ThemingDefaults extends \OC_Defaults {
$cacheBusterKey = $this->config->getAppValue('theming', 'cachebuster', '0');
$this->config->setAppValue('theming', 'cachebuster', (int)$cacheBusterKey+1);
$this->cacheFactory->createDistributed('theming-')->clear();
+ $this->cacheFactory->createDistributed('imagePath')->clear();
+
}
/**
diff --git a/apps/theming/templates/settings-admin.php b/apps/theming/templates/settings-admin.php
index 7e489199927..cb117c72a2b 100644
--- a/apps/theming/templates/settings-admin.php
+++ b/apps/theming/templates/settings-admin.php
@@ -67,27 +67,57 @@ style('theming', 'settings-admin');
</label>
</div>
<div>
- <form class="uploadButton" method="post" action="<?php p($_['uploadLogoRoute']) ?>">
- <input type="hidden" id="current-logoMime" name="current-logoMime" value="<?php p($_['logoMime']); ?>" />
+ <form class="uploadButton" method="post" action="<?php p($_['uploadLogoRoute']) ?>" data-image-key="logo">
+ <input type="hidden" id="theming-logoMime" value="<?php p($_['images']['logo']['mime']); ?>" />
+ <input type="hidden" name="key" value="logo" />
<label for="uploadlogo"><span><?php p($l->t('Logo')) ?></span></label>
- <input id="uploadlogo" class="upload-logo-field" name="uploadlogo" type="file" />
+ <input id="uploadlogo" class="fileupload" name="image" type="file" />
<label for="uploadlogo" class="button icon-upload svg" id="uploadlogo" title="<?php p($l->t('Upload new logo')) ?>"></label>
<div data-setting="logoMime" data-toggle="tooltip" data-original-title="<?php p($l->t('Reset to default')); ?>" class="theme-undo icon icon-history"></div>
</form>
</div>
<div>
- <form class="uploadButton" method="post" action="<?php p($_['uploadLogoRoute']) ?>">
- <input type="hidden" id="current-backgroundMime" name="current-backgroundMime" value="<?php p($_['backgroundMime']); ?>" />
+ <form class="uploadButton" method="post" action="<?php p($_['uploadLogoRoute']) ?>" data-image-key="background">
+ <input type="hidden" id="theming-backgroundMime" value="<?php p($_['images']['background']['mime']); ?>" />
+ <input type="hidden" name="key" value="background" />
<label for="upload-login-background"><span><?php p($l->t('Login image')) ?></span></label>
- <input id="upload-login-background" class="upload-logo-field" name="upload-login-background" type="file">
+ <input id="upload-login-background" class="fileupload" name="image" type="file">
<label for="upload-login-background" class="button icon-upload svg" id="upload-login-background" title="<?php p($l->t("Upload new login background")) ?>"></label>
<div data-setting="backgroundMime" data-toggle="tooltip" data-original-title="<?php p($l->t('Reset to default')); ?>" class="theme-undo icon icon-history"></div>
<div class="theme-remove-bg icon icon-delete" data-toggle="tooltip" data-original-title="<?php p($l->t('Remove background image')); ?>"></div>
</form>
</div>
<div id="theming-preview">
- <img src="<?php p($_['logo']); ?>" id="theming-preview-logo" />
+ <div id="theming-preview-logo"></div>
</div>
+
+ <h2 class="inlineblock"><?php p($l->t('Advanced options')); ?></h2>
+
+ <div class="advanced-options">
+ <div class="advanced-option-logoheader">
+ <form class="uploadButton" method="post" action="<?php p($_['uploadLogoRoute']) ?>" data-image-key="logoheader">
+ <input type="hidden" id="theming-logoheaderMime" value="<?php p($_['images']['logoheader']['mime']); ?>" />
+ <input type="hidden" name="key" value="logoheader" />
+ <label for="upload-login-logoheader"><span><?php p($l->t('Header logo')) ?></span></label>
+ <input id="upload-login-logoheader" class="fileupload" name="image" type="file">
+ <label for="upload-login-logoheader" class="button icon-upload svg" id="upload-login-logoheader" title="<?php p($l->t("Upload new header logo")) ?>"></label>
+ <div class="image-preview"></div>
+ <div data-setting="logoheaderMime" data-toggle="tooltip" data-original-title="<?php p($l->t('Reset to default')); ?>" class="theme-undo icon icon-history"></div>
+ </form>
+ </div>
+ <div class="advanced-option-favicon">
+ <form class="uploadButton" method="post" action="<?php p($_['uploadLogoRoute']) ?>" data-image-key="favicon">
+ <input type="hidden" id="theming-faviconMime" value="<?php p($_['images']['favicon']['mime']); ?>" />
+ <input type="hidden" name="key" value="favicon" />
+ <label for="upload-login-favicon"><span><?php p($l->t('Favicon')) ?></span></label>
+ <input id="upload-login-favicon" class="fileupload" name="image" type="file">
+ <label for="upload-login-favicon" class="button icon-upload svg" id="upload-login-favicon" title="<?php p($l->t("Upload new favion")) ?>"></label>
+ <div class="image-preview"></div>
+ <div data-setting="faviconMime" data-toggle="tooltip" data-original-title="<?php p($l->t('Reset to default')); ?>" class="theme-undo icon icon-history"></div>
+ </form>
+ </div>
+ </div>
+
<div class="theming-hints">
<?php if (!$_['canThemeIcons']) { ?>
<p class="info">
diff --git a/apps/theming/tests/Controller/IconControllerTest.php b/apps/theming/tests/Controller/IconControllerTest.php
index d92677e1f84..6539c6e0209 100644
--- a/apps/theming/tests/Controller/IconControllerTest.php
+++ b/apps/theming/tests/Controller/IconControllerTest.php
@@ -33,7 +33,6 @@ use OCA\Theming\ImageManager;
use OCA\Theming\ThemingDefaults;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\DataDisplayResponse;
-use OCP\AppFramework\Http\NotFoundResponse;
use OCP\Files\NotFoundException;
use OCP\IConfig;
use OCP\IRequest;
@@ -41,6 +40,7 @@ use Test\TestCase;
use OCA\Theming\Util;
use OCA\Theming\Controller\IconController;
use OCP\AppFramework\Http\FileDisplayResponse;
+use OCP\AppFramework\Utility\ITimeFactory;
class IconControllerTest extends TestCase {
@@ -48,8 +48,6 @@ class IconControllerTest extends TestCase {
private $request;
/** @var ThemingDefaults|\PHPUnit_Framework_MockObject_MockObject */
private $themingDefaults;
- /** @var Util */
- private $util;
/** @var \OCP\AppFramework\Utility\ITimeFactory */
private $timeFactory;
/** @var IconController|\PHPUnit_Framework_MockObject_MockObject */
@@ -64,18 +62,11 @@ class IconControllerTest extends TestCase {
private $imageManager;
public function setUp() {
- $this->request = $this->getMockBuilder(IRequest::class)->getMock();
- $this->themingDefaults = $this->getMockBuilder('OCA\Theming\ThemingDefaults')
- ->disableOriginalConstructor()->getMock();
- $this->util = $this->getMockBuilder('\OCA\Theming\Util')->disableOriginalConstructor()
- ->setMethods(['getAppImage', 'getAppIcon', 'elementColor'])->getMock();
- $this->timeFactory = $this->getMockBuilder('OCP\AppFramework\Utility\ITimeFactory')
- ->disableOriginalConstructor()
- ->getMock();
- $this->config = $this->getMockBuilder(IConfig::class)->getMock();
- $this->iconBuilder = $this->getMockBuilder('OCA\Theming\IconBuilder')
- ->disableOriginalConstructor()->getMock();
- $this->imageManager = $this->getMockBuilder('OCA\Theming\ImageManager')->disableOriginalConstructor()->getMock();
+ $this->request = $this->createMock(IRequest::class);
+ $this->themingDefaults = $this->createMock(ThemingDefaults::class);
+ $this->timeFactory = $this->createMock(ITimeFactory::class);
+ $this->iconBuilder = $this->createMock(IconBuilder::class);
+ $this->imageManager = $this->createMock(ImageManager::class);
$this->fileAccessHelper = $this->createMock(FileAccessHelper::class);
$this->timeFactory->expects($this->any())
->method('getTime')
@@ -85,9 +76,7 @@ class IconControllerTest extends TestCase {
'theming',
$this->request,
$this->themingDefaults,
- $this->util,
$this->timeFactory,
- $this->config,
$this->iconBuilder,
$this->imageManager,
$this->fileAccessHelper
@@ -129,18 +118,21 @@ class IconControllerTest extends TestCase {
if (count($checkImagick->queryFormats('SVG')) < 1) {
$this->markTestSkipped('No SVG provider present.');
}
+ $file = $this->iconFileMock('filename', 'filecontent');
+ $this->imageManager->expects($this->once())
+ ->method('getImage')
+ ->with('favicon')
+ ->will($this->throwException(new NotFoundException()));
$this->themingDefaults->expects($this->any())
->method('shouldReplaceIcons')
->willReturn(true);
-
+ $this->imageManager->expects($this->once())
+ ->method('getCachedImage')
+ ->will($this->throwException(new NotFoundException()));
$this->iconBuilder->expects($this->once())
->method('getFavicon')
->with('core')
->willReturn('filecontent');
- $file = $this->iconFileMock('filename', 'filecontent');
- $this->imageManager->expects($this->once())
- ->method('getCachedImage')
- ->will($this->throwException(new NotFoundException()));
$this->imageManager->expects($this->once())
->method('setCachedImage')
->willReturn($file);
@@ -156,6 +148,10 @@ class IconControllerTest extends TestCase {
}
public function testGetFaviconFail() {
+ $this->imageManager->expects($this->once())
+ ->method('getImage')
+ ->with('favicon')
+ ->will($this->throwException(new NotFoundException()));
$this->themingDefaults->expects($this->any())
->method('shouldReplaceIcons')
->willReturn(false);
@@ -209,6 +205,10 @@ class IconControllerTest extends TestCase {
}
public function testGetTouchIconFail() {
+ $this->imageManager->expects($this->once())
+ ->method('getImage')
+ ->with('favicon')
+ ->will($this->throwException(new NotFoundException()));
$this->themingDefaults->expects($this->any())
->method('shouldReplaceIcons')
->willReturn(false);
diff --git a/apps/theming/tests/Controller/ThemingControllerTest.php b/apps/theming/tests/Controller/ThemingControllerTest.php
index 08af13f994b..dda881525f0 100644
--- a/apps/theming/tests/Controller/ThemingControllerTest.php
+++ b/apps/theming/tests/Controller/ThemingControllerTest.php
@@ -34,6 +34,7 @@ use OC\Files\AppData\Factory;
use OC\L10N\L10N;
use OC\Template\SCSSCacher;
use OCA\Theming\Controller\ThemingController;
+use OCA\Theming\ImageManager;
use OCA\Theming\Util;
use OCP\App\IAppManager;
use OCP\AppFramework\Http;
@@ -74,6 +75,8 @@ class ThemingControllerTest extends TestCase {
private $appManager;
/** @var IAppData|\PHPUnit_Framework_MockObject_MockObject */
private $appData;
+ /** @var ImageManager|\PHPUnit_Framework_MockObject_MockObject */
+ private $imageManager;
/** @var SCSSCacher */
private $scssCacher;
/** @var IURLGenerator */
@@ -94,6 +97,7 @@ class ThemingControllerTest extends TestCase {
$this->tempManager = \OC::$server->getTempManager();
$this->scssCacher = $this->createMock(SCSSCacher::class);
$this->urlGenerator = $this->createMock(IURLGenerator::class);
+ $this->imageManager = $this->createMock(ImageManager::class);
$this->themingController = new ThemingController(
'theming',
@@ -107,7 +111,8 @@ class ThemingControllerTest extends TestCase {
$this->appData,
$this->scssCacher,
$this->urlGenerator,
- $this->appManager
+ $this->appManager,
+ $this->imageManager
);
return parent::setUp();
@@ -211,17 +216,12 @@ class ThemingControllerTest extends TestCase {
$this->request
->expects($this->at(0))
->method('getParam')
- ->with('backgroundColor')
- ->willReturn(false);
+ ->with('key')
+ ->willReturn('logo');
$this->request
->expects($this->at(1))
->method('getUploadedFile')
- ->with('uploadlogo')
- ->willReturn(null);
- $this->request
- ->expects($this->at(2))
- ->method('getUploadedFile')
- ->with('upload-login-background')
+ ->with('image')
->willReturn(null);
$this->l10n
->expects($this->any())
@@ -241,30 +241,25 @@ class ThemingControllerTest extends TestCase {
Http::STATUS_UNPROCESSABLE_ENTITY
);
- $this->assertEquals($expected, $this->themingController->updateLogo());
+ $this->assertEquals($expected, $this->themingController->uploadImage());
}
public function testUpdateLogoInvalidMimeType() {
$this->request
->expects($this->at(0))
->method('getParam')
- ->with('backgroundColor')
- ->willReturn(false);
+ ->with('key')
+ ->willReturn('logo');
$this->request
->expects($this->at(1))
->method('getUploadedFile')
- ->with('uploadlogo')
+ ->with('image')
->willReturn([
'tmp_name' => 'logo.pdf',
'type' => 'application/pdf',
'name' => 'logo.pdf',
'error' => 0,
]);
- $this->request
- ->expects($this->at(2))
- ->method('getUploadedFile')
- ->with('upload-login-background')
- ->willReturn(null);
$this->l10n
->expects($this->any())
->method('t')
@@ -290,30 +285,7 @@ class ThemingControllerTest extends TestCase {
Http::STATUS_UNPROCESSABLE_ENTITY
);
- $this->assertEquals($expected, $this->themingController->updateLogo());
- }
-
- public function testUpdateBackgroundColor() {
- $this->request
- ->expects($this->at(0))
- ->method('getParam')
- ->with('backgroundColor')
- ->willReturn(true);
- $this->themingDefaults
- ->expects($this->once())
- ->method('set')
- ->with('backgroundMime', 'backgroundColor');
- $expected = new DataResponse(
- [
- 'data' =>
- [
- 'name' => 'backgroundColor',
- 'message' => $this->l10n->t('Saved')
- ],
- 'status' => 'success'
- ]
- );
- $this->assertEquals($expected, $this->themingController->updateLogo());
+ $this->assertEquals($expected, $this->themingController->uploadImage());
}
public function dataUpdateImages() {
@@ -336,23 +308,18 @@ class ThemingControllerTest extends TestCase {
$this->request
->expects($this->at(0))
->method('getParam')
- ->with('backgroundColor')
- ->willReturn(false);
+ ->with('key')
+ ->willReturn('logo');
$this->request
->expects($this->at(1))
->method('getUploadedFile')
- ->with('uploadlogo')
+ ->with('image')
->willReturn([
'tmp_name' => $tmpLogo,
'type' => $mimeType,
'name' => 'logo.svg',
'error' => 0,
]);
- $this->request
- ->expects($this->at(2))
- ->method('getUploadedFile')
- ->with('upload-login-background')
- ->willReturn(null);
$this->l10n
->expects($this->any())
->method('t')
@@ -385,18 +352,27 @@ class ThemingControllerTest extends TestCase {
->method('newFile')
->with('logo')
->willReturn($file);
+ $this->urlGenerator->expects($this->once())
+ ->method('linkTo')
+ ->willReturn('serverCss');
+ $this->imageManager->expects($this->once())
+ ->method('getImageUrl')
+ ->with('logo')
+ ->willReturn('imageUrl');
$expected = new DataResponse(
[
'data' =>
[
'name' => 'logo.svg',
'message' => 'Saved',
+ 'url' => 'imageUrl',
+ 'serverCssUrl' => 'serverCss'
],
'status' => 'success'
]
);
- $this->assertEquals($expected, $this->themingController->updateLogo());
+ $this->assertEquals($expected, $this->themingController->uploadImage());
}
/** @dataProvider dataUpdateImages */
@@ -408,17 +384,12 @@ class ThemingControllerTest extends TestCase {
$this->request
->expects($this->at(0))
->method('getParam')
- ->with('backgroundColor')
- ->willReturn(false);
+ ->with('key')
+ ->willReturn('background');
$this->request
->expects($this->at(1))
->method('getUploadedFile')
- ->with('uploadlogo')
- ->willReturn(null);
- $this->request
- ->expects($this->at(2))
- ->method('getUploadedFile')
- ->with('upload-login-background')
+ ->with('image')
->willReturn([
'tmp_name' => $tmpLogo,
'type' => 'text/svg',
@@ -457,17 +428,26 @@ class ThemingControllerTest extends TestCase {
->with('background')
->willReturn($file);
+ $this->urlGenerator->expects($this->once())
+ ->method('linkTo')
+ ->willReturn('serverCss');
+ $this->imageManager->expects($this->once())
+ ->method('getImageUrl')
+ ->with('background')
+ ->willReturn('imageUrl');
$expected = new DataResponse(
[
'data' =>
[
'name' => 'logo.svg',
'message' => 'Saved',
+ 'url' => 'imageUrl',
+ 'serverCssUrl' => 'serverCss'
],
'status' => 'success'
]
);
- $this->assertEquals($expected, $this->themingController->updateLogo());
+ $this->assertEquals($expected, $this->themingController->uploadImage());
}
public function testUpdateLogoLoginScreenUploadWithInvalidImage() {
@@ -478,20 +458,15 @@ class ThemingControllerTest extends TestCase {
$this->request
->expects($this->at(0))
->method('getParam')
- ->with('backgroundColor')
- ->willReturn(false);
+ ->with('key')
+ ->willReturn('logo');
$this->request
->expects($this->at(1))
->method('getUploadedFile')
- ->with('uploadlogo')
- ->willReturn(null);
- $this->request
- ->expects($this->at(2))
- ->method('getUploadedFile')
- ->with('upload-login-background')
+ ->with('image')
->willReturn([
'tmp_name' => $tmpLogo,
- 'type' => 'text/svg',
+ 'type' => 'foobar',
'name' => 'logo.svg',
'error' => 0,
]);
@@ -519,7 +494,7 @@ class ThemingControllerTest extends TestCase {
],
Http::STATUS_UNPROCESSABLE_ENTITY
);
- $this->assertEquals($expected, $this->themingController->updateLogo());
+ $this->assertEquals($expected, $this->themingController->uploadImage());
}
public function dataPhpUploadErrors() {
@@ -541,17 +516,12 @@ class ThemingControllerTest extends TestCase {
$this->request
->expects($this->at(0))
->method('getParam')
- ->with('backgroundColor')
- ->willReturn(false);
+ ->with('key')
+ ->willReturn('background');
$this->request
->expects($this->at(1))
->method('getUploadedFile')
- ->with('uploadlogo')
- ->willReturn(null);
- $this->request
- ->expects($this->at(2))
- ->method('getUploadedFile')
- ->with('upload-login-background')
+ ->with('image')
->willReturn([
'tmp_name' => '',
'type' => 'text/svg',
@@ -575,7 +545,7 @@ class ThemingControllerTest extends TestCase {
],
Http::STATUS_UNPROCESSABLE_ENTITY
);
- $this->assertEquals($expected, $this->themingController->updateLogo());
+ $this->assertEquals($expected, $this->themingController->uploadImage());
}
/**
@@ -585,23 +555,18 @@ class ThemingControllerTest extends TestCase {
$this->request
->expects($this->at(0))
->method('getParam')
- ->with('backgroundColor')
- ->willReturn(false);
+ ->with('key')
+ ->willReturn('background');
$this->request
->expects($this->at(1))
->method('getUploadedFile')
- ->with('uploadlogo')
+ ->with('image')
->willReturn([
'tmp_name' => '',
'type' => 'text/svg',
'name' => 'logo.svg',
'error' => $error,
]);
- $this->request
- ->expects($this->at(2))
- ->method('getUploadedFile')
- ->with('upload-login-background')
- ->willReturn(null);
$this->l10n
->expects($this->any())
->method('t')
@@ -619,7 +584,7 @@ class ThemingControllerTest extends TestCase {
],
Http::STATUS_UNPROCESSABLE_ENTITY
);
- $this->assertEquals($expected, $this->themingController->updateLogo());
+ $this->assertEquals($expected, $this->themingController->uploadImage());
}
public function testUndo() {
@@ -687,21 +652,9 @@ class ThemingControllerTest extends TestCase {
->method('linkTo')
->with('', '/core/css/someHash-server.scss')
->willReturn('/nextcloudWebroot/core/css/someHash-server.scss');
- $folder = $this->createMock(ISimpleFolder::class);
- $file = $this->createMock(ISimpleFile::class);
- $this->appData
- ->expects($this->once())
- ->method('getFolder')
- ->with('images')
- ->willReturn($folder);
- $folder
- ->expects($this->once())
- ->method('getFile')
- ->with($filename)
- ->willReturn($file);
- $file
- ->expects($this->once())
- ->method('delete');
+ $this->imageManager->expects($this->once())
+ ->method('delete')
+ ->with($filename);
$expected = new DataResponse(
[
@@ -720,27 +673,19 @@ class ThemingControllerTest extends TestCase {
public function testGetLogoNotExistent() {
- $this->appData->method('getFolder')
- ->with($this->equalTo('images'))
+ $this->imageManager->method('getImage')
+ ->with($this->equalTo('logo'))
->willThrowException(new NotFoundException());
$expected = new Http\NotFoundResponse();
- $this->assertEquals($expected, $this->themingController->getLogo());
+ $this->assertEquals($expected, $this->themingController->getImage('logo'));
}
public function testGetLogo() {
$file = $this->createMock(ISimpleFile::class);
- $folder = $this->createMock(ISimpleFolder::class);
- $this->appData
- ->expects($this->once())
- ->method('getFolder')
- ->with('images')
- ->willReturn($folder);
- $folder->expects($this->once())
- ->method('getFile')
- ->with('logo')
+ $this->imageManager->expects($this->once())
+ ->method('getImage')
->willReturn($file);
-
$this->config
->expects($this->once())
->method('getAppValue')
@@ -755,29 +700,22 @@ class ThemingControllerTest extends TestCase {
$expected->addHeader('Expires', $expires->format(\DateTime::RFC2822));
$expected->addHeader('Pragma', 'cache');
$expected->addHeader('Content-Type', 'text/svg');
- @$this->assertEquals($expected, $this->themingController->getLogo());
+ @$this->assertEquals($expected, $this->themingController->getImage('logo'));
}
public function testGetLoginBackgroundNotExistent() {
- $this->appData->method('getFolder')
- ->with($this->equalTo('images'))
+ $this->imageManager->method('getImage')
+ ->with($this->equalTo('background'))
->willThrowException(new NotFoundException());
$expected = new Http\NotFoundResponse();
- $this->assertEquals($expected, $this->themingController->getLoginBackground());
+ $this->assertEquals($expected, $this->themingController->getImage('background'));
}
public function testGetLoginBackground() {
$file = $this->createMock(ISimpleFile::class);
- $folder = $this->createMock(ISimpleFolder::class);
- $this->appData
- ->expects($this->once())
- ->method('getFolder')
- ->with('images')
- ->willReturn($folder);
- $folder->expects($this->once())
- ->method('getFile')
- ->with('background')
+ $this->imageManager->expects($this->once())
+ ->method('getImage')
->willReturn($file);
$this->config
@@ -794,7 +732,7 @@ class ThemingControllerTest extends TestCase {
$expected->addHeader('Expires', $expires->format(\DateTime::RFC2822));
$expected->addHeader('Pragma', 'cache');
$expected->addHeader('Content-Type', 'image/png');
- @$this->assertEquals($expected, $this->themingController->getLoginBackground());
+ @$this->assertEquals($expected, $this->themingController->getImage('background'));
}
diff --git a/apps/theming/tests/ImageManagerTest.php b/apps/theming/tests/ImageManagerTest.php
index 6c0b31528fc..4e258ce7162 100644
--- a/apps/theming/tests/ImageManagerTest.php
+++ b/apps/theming/tests/ImageManagerTest.php
@@ -23,14 +23,16 @@
*/
namespace OCA\Theming\Tests;
+use OCA\Theming\ImageManager;
use OCP\Files\SimpleFS\ISimpleFile;
use OCP\IConfig;
+use OCP\IURLGenerator;
use Test\TestCase;
use OCP\Files\SimpleFS\ISimpleFolder;
use OCP\Files\IAppData;
use OCP\Files\NotFoundException;
-class ImageManager extends TestCase {
+class ImageManagerTest extends TestCase {
/** @var IConfig|\PHPUnit_Framework_MockObject_MockObject */
protected $config;
@@ -38,17 +40,112 @@ class ImageManager extends TestCase {
protected $appData;
/** @var ImageManager */
protected $imageManager;
+ /** @var IURLGenerator|\PHPUnit_Framework_MockObject_MockObject */
+ private $urlGenerator;
protected function setUp() {
parent::setUp();
- $this->config = $this->getMockBuilder(IConfig::class)->getMock();
- $this->appData = $this->getMockBuilder('OCP\Files\IAppData')->getMock();
- $this->imageManager = new \OCA\Theming\ImageManager(
+ $this->config = $this->createMock(IConfig::class);
+ $this->appData = $this->createMock(IAppData::class);
+ $this->urlGenerator = $this->createMock(IURLGenerator::class);
+ $this->imageManager = new ImageManager(
$this->config,
- $this->appData
+ $this->appData,
+ $this->urlGenerator
);
}
+ public function mockGetImage($key, $file) {
+ /** @var \PHPUnit_Framework_MockObject_MockObject $folder */
+ $folder = $this->createMock(ISimpleFolder::class);
+ if ($file === null) {
+ $folder->expects($this->once())
+ ->method('getFile')
+ ->with('logo')
+ ->willThrowException(new NotFoundException());
+ } else {
+ $folder->expects($this->once())
+ ->method('getFile')
+ ->with('logo')
+ ->willReturn($file);
+ $this->appData->expects($this->once())
+ ->method('getFolder')
+ ->with('images')
+ ->willReturn($folder);
+ }
+ }
+
+ public function testGetImageUrl() {
+ $file = $this->createMock(ISimpleFile::class);
+ $this->config->expects($this->exactly(2))
+ ->method('getAppValue')
+ ->withConsecutive(
+ ['theming', 'cachebuster', '0'],
+ ['theming', 'logoMime', false]
+ )
+ ->willReturn(0);
+ $this->mockGetImage('logo', $file);
+ $this->urlGenerator->expects($this->once())
+ ->method('linkToRoute')
+ ->willReturn('url-to-image');
+ $this->assertEquals('url-to-image?v=0', $this->imageManager->getImageUrl('logo'));
+ }
+
+ public function testGetImageUrlDefault() {
+ $this->config->expects($this->exactly(2))
+ ->method('getAppValue')
+ ->withConsecutive(
+ ['theming', 'cachebuster', '0'],
+ ['theming', 'logoMime', false]
+ )
+ ->willReturnOnConsecutiveCalls(0, false);
+ $this->urlGenerator->expects($this->once())
+ ->method('imagePath')
+ ->with('core', 'logo.png')
+ ->willReturn('logo.png');
+ $this->assertEquals('logo.png?v=0', $this->imageManager->getImageUrl('logo'));
+ }
+
+ public function testGetImageUrlAbsolute() {
+ $file = $this->createMock(ISimpleFile::class);
+ $this->config->expects($this->exactly(2))
+ ->method('getAppValue')
+ ->withConsecutive(
+ ['theming', 'cachebuster', '0'],
+ ['theming', 'logoMime', false]
+ )
+ ->willReturn(0);
+ $this->mockGetImage('logo', $file);
+ $this->urlGenerator->expects($this->at(0))
+ ->method('linkToRoute')
+ ->willReturn('url-to-image');
+ $this->urlGenerator->expects($this->at(1))
+ ->method('getAbsoluteUrl')
+ ->with('url-to-image?v=0')
+ ->willReturn('url-to-image-absolute?v=0');
+ $this->assertEquals('url-to-image-absolute?v=0', $this->imageManager->getImageUrlAbsolute('logo'));
+
+ }
+
+ public function testGetImage() {
+ $this->config->expects($this->once())
+ ->method('getAppValue')->with('theming', 'logoMime', false)
+ ->willReturn('png');
+ $file = $this->createMock(ISimpleFile::class);
+ $this->mockGetImage('logo', $file);
+ $this->assertEquals($file, $this->imageManager->getImage('logo'));
+ }
+
+ /**
+ * @expectedException OCP\Files\NotFoundException
+ */
+ public function testGetImageUnset() {
+ $this->config->expects($this->once())
+ ->method('getAppValue')->with('theming', 'logoMime', false)
+ ->willReturn(false);
+ $this->imageManager->getImage('logo');
+ }
+
public function testGetCacheFolder() {
$folder = $this->createMock(ISimpleFolder::class);
$this->config->expects($this->once())
@@ -85,12 +182,12 @@ class ImageManager extends TestCase {
}
public function testGetCachedImage() {
+ $expected = $this->createMock(ISimpleFile::class);
$folder = $this->setupCacheFolder();
$folder->expects($this->once())
->method('getFile')
->with('filename')
- ->willReturn('filecontent');
- $expected = 'filecontent';
+ ->willReturn($expected);
$this->assertEquals($expected, $this->imageManager->getCachedImage('filename'));
}
diff --git a/apps/theming/tests/Settings/AdminTest.php b/apps/theming/tests/Settings/AdminTest.php
index ee49cf0f1f6..4eac689fb3f 100644
--- a/apps/theming/tests/Settings/AdminTest.php
+++ b/apps/theming/tests/Settings/AdminTest.php
@@ -27,6 +27,7 @@
namespace OCA\Theming\Tests\Settings;
+use OCA\Theming\ImageManager;
use OCA\Theming\Settings\Admin;
use OCA\Theming\ThemingDefaults;
use OCP\AppFramework\Http\TemplateResponse;
@@ -44,21 +45,25 @@ class AdminTest extends TestCase {
private $themingDefaults;
/** @var IURLGenerator */
private $urlGenerator;
+ /** @var ImageManager */
+ private $imageManager;
/** @var IL10N */
private $l10n;
public function setUp() {
parent::setUp();
- $this->config = $this->getMockBuilder(IConfig::class)->getMock();
- $this->l10n = $this->getMockBuilder(IL10N::class)->getMock();
- $this->themingDefaults = $this->getMockBuilder('\OCA\Theming\ThemingDefaults')->disableOriginalConstructor()->getMock();
- $this->urlGenerator = $this->getMockBuilder(IURLGenerator::class)->getMock();
+ $this->config = $this->createMock(IConfig::class);
+ $this->l10n = $this->createMock(IL10N::class);
+ $this->themingDefaults = $this->createMock(ThemingDefaults::class);
+ $this->urlGenerator = $this->createMock(IURLGenerator::class);
+ $this->imageManager = $this->createMock(ImageManager::class);
$this->admin = new Admin(
$this->config,
$this->l10n,
$this->themingDefaults,
- $this->urlGenerator
+ $this->urlGenerator,
+ $this->imageManager
);
}
@@ -87,7 +92,7 @@ class AdminTest extends TestCase {
$this->urlGenerator
->expects($this->once())
->method('linkToRoute')
- ->with('theming.Theming.updateLogo')
+ ->with('theming.Theming.uploadImage')
->willReturn('/my/route');
$params = [
'themable' => true,
@@ -97,12 +102,9 @@ class AdminTest extends TestCase {
'slogan' => 'MySlogan',
'color' => '#fff',
'uploadLogoRoute' => '/my/route',
- 'logo' => null,
- 'logoMime' => null,
- 'background' => null,
- 'backgroundMime' => null,
'canThemeIcons' => null,
'iconDocs' => null,
+ 'images' => [],
];
$expected = new TemplateResponse('theming', 'settings-admin', $params, '');
@@ -139,7 +141,7 @@ class AdminTest extends TestCase {
$this->urlGenerator
->expects($this->once())
->method('linkToRoute')
- ->with('theming.Theming.updateLogo')
+ ->with('theming.Theming.uploadImage')
->willReturn('/my/route');
$params = [
'themable' => false,
@@ -149,12 +151,9 @@ class AdminTest extends TestCase {
'slogan' => 'MySlogan',
'color' => '#fff',
'uploadLogoRoute' => '/my/route',
- 'logo' => null,
- 'logoMime' => null,
- 'background' => null,
- 'backgroundMime' => null,
'canThemeIcons' => null,
- 'iconDocs' => null,
+ 'iconDocs' => '',
+ 'images' => [],
];
$expected = new TemplateResponse('theming', 'settings-admin', $params, '');
diff --git a/apps/theming/tests/ThemingDefaultsTest.php b/apps/theming/tests/ThemingDefaultsTest.php
index 2485a471bf4..c943af01c6c 100644
--- a/apps/theming/tests/ThemingDefaultsTest.php
+++ b/apps/theming/tests/ThemingDefaultsTest.php
@@ -29,6 +29,7 @@
*/
namespace OCA\Theming\Tests;
+use OCA\Theming\ImageManager;
use OCA\Theming\ThemingDefaults;
use OCP\App\IAppManager;
use OCP\Files\IAppData;
@@ -64,30 +65,31 @@ class ThemingDefaultsTest extends TestCase {
private $cache;
/** @var IAppManager|\PHPUnit_Framework_MockObject_MockObject */
private $appManager;
+ /** @var ImageManager|\PHPUnit_Framework_MockObject_MockObject */
+ private $imageManager;
public function setUp() {
parent::setUp();
$this->config = $this->createMock(IConfig::class);
$this->l10n = $this->createMock(IL10N::class);
$this->urlGenerator = $this->createMock(IURLGenerator::class);
- $this->appData = $this->createMock(IAppData::class);
$this->cacheFactory = $this->createMock(ICacheFactory::class);
$this->cache = $this->createMock(ICache::class);
$this->util = $this->createMock(Util::class);
+ $this->imageManager = $this->createMock(ImageManager::class);
$this->appManager = $this->createMock(IAppManager::class);
$this->defaults = new \OC_Defaults();
- $this->cacheFactory
+ $this->urlGenerator
->expects($this->any())
- ->method('createDistributed')
- ->with('theming-')
- ->willReturn($this->cache);
+ ->method('getBaseUrl')
+ ->willReturn('');
$this->template = new ThemingDefaults(
$this->config,
$this->l10n,
$this->urlGenerator,
- $this->appData,
$this->cacheFactory,
$this->util,
+ $this->imageManager,
$this->appManager
);
}
@@ -273,8 +275,18 @@ class ThemingDefaultsTest extends TestCase {
->expects($this->at(2))
->method('setAppValue')
->with('theming', 'cachebuster', 16);
+ $this->cacheFactory
+ ->expects($this->at(0))
+ ->method('createDistributed')
+ ->with('theming-')
+ ->willReturn($this->cache);
+ $this->cacheFactory
+ ->expects($this->at(1))
+ ->method('createDistributed')
+ ->with('imagePath')
+ ->willReturn($this->cache);
$this->cache
- ->expects($this->once())
+ ->expects($this->any())
->method('clear')
->with('');
$this->template->set('MySetting', 'MyValue');
@@ -390,41 +402,19 @@ class ThemingDefaultsTest extends TestCase {
$this->assertSame('', $this->template->undo('defaultitem'));
}
- public function testGetBackgroundDefault() {
- $this->config
+ public function testGetBackground() {
+ $this->imageManager
->expects($this->once())
- ->method('getAppValue')
- ->with('theming', 'cachebuster', '0')
- ->willReturn('0');
- $this->util->expects($this->once())
- ->method('isBackgroundThemed')
- ->willReturn(false);
- $this->urlGenerator->expects($this->once())
- ->method('imagePath')
- ->with('core', 'background.png')
- ->willReturn('core-background');
- $this->assertEquals('core-background?v=0', $this->template->getBackground());
- }
-
- public function testGetBackgroundCustom() {
- $this->config
- ->expects($this->once())
- ->method('getAppValue')
- ->with('theming', 'cachebuster', '0')
- ->willReturn('0');
- $this->util->expects($this->once())
- ->method('isBackgroundThemed')
- ->willReturn(true);
- $this->urlGenerator->expects($this->once())
- ->method('linkToRoute')
- ->with('theming.Theming.getLoginBackground')
- ->willReturn('custom-background');
+ ->method('getImageUrl')
+ ->with('background')
+ ->willReturn('custom-background?v=0');
$this->assertEquals('custom-background?v=0', $this->template->getBackground());
}
private function getLogoHelper($withName, $useSvg) {
- $this->appData->expects($this->once())
- ->method('getFolder')
+ $this->imageManager->expects($this->any())
+ ->method('getImage')
+ ->with('logo')
->willThrowException(new NotFoundException());
$this->config
->expects($this->at(0))
@@ -436,11 +426,6 @@ class ThemingDefaultsTest extends TestCase {
->method('getAppValue')
->with('theming', 'cachebuster', '0')
->willReturn('0');
- $this->appData
- ->expects($this->once())
- ->method('getFolder')
- ->with('images')
- ->willThrowException(new \Exception());
$this->urlGenerator->expects($this->once())
->method('imagePath')
->with('core', $withName)
@@ -457,14 +442,11 @@ class ThemingDefaultsTest extends TestCase {
}
public function testGetLogoCustom() {
- $folder = $this->createMock(ISimpleFolder::class);
$file = $this->createMock(ISimpleFile::class);
- $folder->expects($this->once())
- ->method('getFile')
+ $this->imageManager->expects($this->once())
+ ->method('getImage')
+ ->with('logo')
->willReturn($file);
- $this->appData->expects($this->once())
- ->method('getFolder')
- ->willReturn($folder);
$this->config
->expects($this->at(0))
->method('getAppValue')
@@ -477,12 +459,16 @@ class ThemingDefaultsTest extends TestCase {
->willReturn('0');
$this->urlGenerator->expects($this->once())
->method('linkToRoute')
- ->with('theming.Theming.getLogo')
+ ->with('theming.Theming.getImage')
->willReturn('custom-logo');
$this->assertEquals('custom-logo' . '?v=0', $this->template->getLogo());
}
public function testGetScssVariablesCached() {
+ $this->cacheFactory->expects($this->once())
+ ->method('createDistributed')
+ ->with('theming-')
+ ->willReturn($this->cache);
$this->cache->expects($this->once())->method('get')->with('getScssVariables')->willReturn(['foo'=>'bar']);
$this->assertEquals(['foo'=>'bar'], $this->template->getScssVariables());
}
@@ -491,31 +477,25 @@ class ThemingDefaultsTest extends TestCase {
$this->config->expects($this->at(0))->method('getAppValue')->with('theming', 'cachebuster', '0')->willReturn('0');
$this->config->expects($this->at(1))->method('getAppValue')->with('theming', 'logoMime', false)->willReturn('jpeg');
$this->config->expects($this->at(2))->method('getAppValue')->with('theming', 'backgroundMime', false)->willReturn('jpeg');
- $this->config->expects($this->at(3))->method('getAppValue')->with('theming', 'logoMime', false)->willReturn('jpeg');
- $this->config->expects($this->at(4))->method('getAppValue')->with('theming', 'cachebuster', '0')->willReturn('0');
- $this->util->expects($this->once())->method('isBackgroundThemed')->willReturn(true);
- $this->config->expects($this->at(5))->method('getAppValue')->with('theming', 'cachebuster', '0')->willReturn('0');
- $this->config->expects($this->at(6))->method('getAppValue')->with('theming', 'color', null)->willReturn($this->defaults->getColorPrimary());
+ $this->config->expects($this->at(3))->method('getAppValue')->with('theming', 'logoheaderMime', false)->willReturn('jpeg');
+ $this->config->expects($this->at(4))->method('getAppValue')->with('theming', 'faviconMime', false)->willReturn('jpeg');
+
+ $this->config->expects($this->at(5))->method('getAppValue')->with('theming', 'color', null)->willReturn($this->defaults->getColorPrimary());
+ $this->config->expects($this->at(6))->method('getAppValue')->with('theming', 'color', $this->defaults->getColorPrimary())->willReturn($this->defaults->getColorPrimary());
$this->config->expects($this->at(7))->method('getAppValue')->with('theming', 'color', $this->defaults->getColorPrimary())->willReturn($this->defaults->getColorPrimary());
$this->config->expects($this->at(8))->method('getAppValue')->with('theming', 'color', $this->defaults->getColorPrimary())->willReturn($this->defaults->getColorPrimary());
- $this->config->expects($this->at(9))->method('getAppValue')->with('theming', 'color', $this->defaults->getColorPrimary())->willReturn($this->defaults->getColorPrimary());
$this->util->expects($this->any())->method('invertTextColor')->with($this->defaults->getColorPrimary())->willReturn(false);
$this->util->expects($this->any())->method('elementColor')->with($this->defaults->getColorPrimary())->willReturn('#aaaaaa');
+ $this->cacheFactory->expects($this->once())
+ ->method('createDistributed')
+ ->with('theming-')
+ ->willReturn($this->cache);
$this->cache->expects($this->once())->method('get')->with('getScssVariables')->willReturn(null);
- $folder = $this->createMock(ISimpleFolder::class);
- $file = $this->createMock(ISimpleFile::class);
- $folder->expects($this->any())->method('getFile')->willReturn($file);
- $this->appData->expects($this->any())
- ->method('getFolder')
- ->willReturn($folder);
-
- $this->urlGenerator->expects($this->exactly(2))
- ->method('linkToRoute')
- ->willReturnMap([
- ['theming.Theming.getLogo', [], 'custom-logo'],
- ['theming.Theming.getLoginBackground', [], 'custom-background'],
- ]);
+ $this->imageManager->expects($this->at(0))->method('getImageUrl')->with('logo')->willReturn('custom-logo?v=0');
+ $this->imageManager->expects($this->at(1))->method('getImageUrl')->with('logoheader')->willReturn('custom-logoheader?v=0');
+ $this->imageManager->expects($this->at(2))->method('getImageUrl')->with('favicon')->willReturn('custom-favicon?v=0');
+ $this->imageManager->expects($this->at(3))->method('getImageUrl')->with('background')->willReturn('custom-background?v=0');
$expected = [
'theming-cachebuster' => '\'0\'',
@@ -526,8 +506,11 @@ class ThemingDefaultsTest extends TestCase {
'color-primary' => $this->defaults->getColorPrimary(),
'color-primary-text' => '#ffffff',
'image-login-plain' => 'false',
- 'color-primary-element' => '#aaaaaa'
-
+ 'color-primary-element' => '#aaaaaa',
+ 'theming-logoheader-mime' => '\'jpeg\'',
+ 'theming-favicon-mime' => '\'jpeg\'',
+ 'image-logoheader' => '\'custom-logoheader?v=0\'',
+ 'image-favicon' => '\'custom-favicon?v=0\''
];
$this->assertEquals($expected, $this->template->getScssVariables());
}