Merge pull request #9516 from nextcloud/backport/9437/stable13

[stable13] allow to specify a link to a legal notice
This commit is contained in:
Morris Jobke 2018-05-22 16:54:07 +02:00 committed by GitHub
commit 5744827696
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 136 additions and 9 deletions

View File

@ -27,7 +27,7 @@
visibility: hidden; visibility: hidden;
} }
form.uploadButton { form.uploadButton {
width: 356px; width: 411px;
} }
#theming form .theme-undo, #theming form .theme-undo,
#theming .theme-remove-bg { #theming .theme-remove-bg {
@ -51,7 +51,7 @@ form.uploadButton {
#theming label span { #theming label span {
display: inline-block; display: inline-block;
min-width: 120px; min-width: 175px;
padding: 8px 0px; padding: 8px 0px;
vertical-align: top; vertical-align: top;
} }
@ -91,7 +91,7 @@ form.uploadButton {
background-size: cover; background-size: cover;
background-position: center center; background-position: center center;
text-align: center; text-align: center;
margin-left: 123px; margin-left: 178px;
margin-top: 10px; margin-top: 10px;
cursor: pointer; cursor: pointer;
} }
@ -104,4 +104,4 @@ form.uploadButton {
.theming-hints { .theming-hints {
margin-top: 20px; margin-top: 20px;
} }

View File

@ -95,7 +95,8 @@ function hideUndoButton(setting, value) {
url: 'https://nextcloud.com', url: 'https://nextcloud.com',
color: '#0082c9', color: '#0082c9',
logoMime: '', logoMime: '',
backgroundMime: '' backgroundMime: '',
imprintUrl: ''
}; };
if (value === themingDefaults[setting] || value === '') { if (value === themingDefaults[setting] || value === '') {
@ -195,6 +196,16 @@ $(document).ready(function () {
} }
}); });
$('#theming-imprintUrl').change(function(e) {
var el = $(this);
$.when(el.focusout()).then(function () {
setThemingValue('imprintUrl', $(this).val());
});
if (e.keyCode == 13) {
setThemingValue('imprintUrl', $(this).val());
}
});
$('#theming-slogan').change(function(e) { $('#theming-slogan').change(function(e) {
var el = $(this); var el = $(this);
$.when(el.focusout()).then(function() { $.when(el.focusout()).then(function() {

View File

@ -157,6 +157,16 @@ class ThemingController extends Controller {
]); ]);
} }
break; break;
case 'imprintUrl':
if (strlen($value) > 500) {
return new DataResponse([
'data' => [
'message' => $this->l10n->t('The given legal notice address is too long'),
],
'status' => 'error'
]);
}
break;
case 'slogan': case 'slogan':
if (strlen($value) > 500) { if (strlen($value) > 500) {
return new DataResponse([ return new DataResponse([
@ -459,6 +469,7 @@ class ThemingController extends Controller {
url: ' . json_encode($this->themingDefaults->getBaseUrl()) . ', url: ' . json_encode($this->themingDefaults->getBaseUrl()) . ',
slogan: ' . json_encode($this->themingDefaults->getSlogan()) . ', slogan: ' . json_encode($this->themingDefaults->getSlogan()) . ',
color: ' . json_encode($this->themingDefaults->getColorPrimary()) . ', color: ' . json_encode($this->themingDefaults->getColorPrimary()) . ',
imprintUrl: ' . json_encode($this->themingDefaults->getImprintUrl()) . ',
inverted: ' . json_encode($this->util->invertTextColor($this->themingDefaults->getColorPrimary())) . ', inverted: ' . json_encode($this->util->invertTextColor($this->themingDefaults->getColorPrimary())) . ',
cacheBuster: ' . json_encode($cacheBusterValue) . ' cacheBuster: ' . json_encode($cacheBusterValue) . '
}; };

View File

@ -83,7 +83,8 @@ class Admin implements ISettings {
'backgroundMime' => $this->config->getAppValue('theming', 'backgroundMime', ''), 'backgroundMime' => $this->config->getAppValue('theming', 'backgroundMime', ''),
'uploadLogoRoute' => $path, 'uploadLogoRoute' => $path,
'canThemeIcons' => $this->themingDefaults->shouldReplaceIcons(), 'canThemeIcons' => $this->themingDefaults->shouldReplaceIcons(),
'iconDocs' => $this->urlGenerator->linkToDocs('admin-theming-icons') 'iconDocs' => $this->urlGenerator->linkToDocs('admin-theming-icons'),
'imprintUrl' => $this->themingDefaults->getImprintUrl(),
]; ];
return new TemplateResponse('theming', 'settings-admin', $parameters, ''); return new TemplateResponse('theming', 'settings-admin', $parameters, '');

View File

@ -142,12 +142,26 @@ class ThemingDefaults extends \OC_Defaults {
return \OCP\Util::sanitizeHTML($this->config->getAppValue('theming', 'slogan', $this->slogan)); return \OCP\Util::sanitizeHTML($this->config->getAppValue('theming', 'slogan', $this->slogan));
} }
public function getImprintUrl() {
return $this->config->getAppValue('theming', 'imprintUrl', '');
}
public function getShortFooter() { public function getShortFooter() {
$slogan = $this->getSlogan(); $slogan = $this->getSlogan();
$footer = '<a href="'. $this->getBaseUrl() . '" target="_blank"' . $footer = '<a href="'. $this->getBaseUrl() . '" target="_blank"' .
' rel="noreferrer noopener">' .$this->getEntity() . '</a>'. ' rel="noreferrer noopener">' .$this->getEntity() . '</a>'.
($slogan !== '' ? ' ' . $slogan : ''); ($slogan !== '' ? ' ' . $slogan : '');
$imprintUrl = (string)$this->getImprintUrl();
if($imprintUrl !== ''
&& filter_var($imprintUrl, FILTER_VALIDATE_URL, [
'flags' => FILTER_FLAG_SCHEME_REQUIRED | FILTER_FLAG_HOST_REQUIRED
])
) {
$footer .= '<br/><a href="' . $imprintUrl . '" class="legal" target="_blank"' .
' rel="noreferrer noopener">' . $this->l->t('Legal notice') . '</a>';
}
return $footer; return $footer;
} }

View File

@ -47,7 +47,7 @@ style('theming', 'settings-admin');
</div> </div>
<div> <div>
<label> <label>
<span><?php p($l->t('Web address')) ?></span> <span><?php p($l->t('Web link')) ?></span>
<input id="theming-url" type="text" placeholder="<?php p($l->t('Web address https://…')); ?>" value="<?php p($_['url']) ?>" maxlength="500" /> <input id="theming-url" type="text" placeholder="<?php p($l->t('Web address https://…')); ?>" value="<?php p($_['url']) ?>" maxlength="500" />
<div data-setting="url" data-toggle="tooltip" data-original-title="<?php p($l->t('Reset to default')); ?>" class="theme-undo icon icon-history"></div> <div data-setting="url" data-toggle="tooltip" data-original-title="<?php p($l->t('Reset to default')); ?>" class="theme-undo icon icon-history"></div>
</label> </label>
@ -88,6 +88,13 @@ style('theming', 'settings-admin');
<div id="theming-preview"> <div id="theming-preview">
<img src="<?php p($_['logo']); ?>" id="theming-preview-logo" /> <img src="<?php p($_['logo']); ?>" id="theming-preview-logo" />
</div> </div>
<div>
<label>
<span><?php p($l->t('Legal notice link')) ?></span>
<input id="theming-imprintUrl" type="text" placeholder="<?php p($l->t('https://…')); ?>" value="<?php p($_['imprintUrl']) ?>" maxlength="500" />
<div data-setting="imprintUrl" data-toggle="tooltip" data-original-title="<?php p($l->t('Reset to default')); ?>" class="theme-undo icon icon-history"></div>
</label>
</div>
<div class="theming-hints"> <div class="theming-hints">
<?php if (!$_['canThemeIcons']) { ?> <?php if (!$_['canThemeIcons']) { ?>
<p class="info"> <p class="info">

View File

@ -876,6 +876,7 @@ class ThemingControllerTest extends TestCase {
url: "", url: "",
slogan: "", slogan: "",
color: "#000", color: "#000",
imprintUrl: null,
inverted: false, inverted: false,
cacheBuster: null cacheBuster: null
}; };
@ -910,6 +911,7 @@ class ThemingControllerTest extends TestCase {
url: "nextcloudurl", url: "nextcloudurl",
slogan: "awesome", slogan: "awesome",
color: "#ffffff", color: "#ffffff",
imprintUrl: null,
inverted: true, inverted: true,
cacheBuster: null cacheBuster: null
}; };

View File

@ -76,6 +76,10 @@ class AdminTest extends TestCase {
->expects($this->once()) ->expects($this->once())
->method('getBaseUrl') ->method('getBaseUrl')
->willReturn('https://example.com'); ->willReturn('https://example.com');
$this->themingDefaults
->expects($this->once())
->method('getImprintUrl')
->willReturn('');
$this->themingDefaults $this->themingDefaults
->expects($this->once()) ->expects($this->once())
->method('getSlogan') ->method('getSlogan')
@ -103,6 +107,7 @@ class AdminTest extends TestCase {
'backgroundMime' => null, 'backgroundMime' => null,
'canThemeIcons' => null, 'canThemeIcons' => null,
'iconDocs' => null, 'iconDocs' => null,
'imprintUrl' => '',
]; ];
$expected = new TemplateResponse('theming', 'settings-admin', $params, ''); $expected = new TemplateResponse('theming', 'settings-admin', $params, '');
@ -128,6 +133,10 @@ class AdminTest extends TestCase {
->expects($this->once()) ->expects($this->once())
->method('getBaseUrl') ->method('getBaseUrl')
->willReturn('https://example.com'); ->willReturn('https://example.com');
$this->themingDefaults
->expects($this->once())
->method('getImprintUrl')
->willReturn('');
$this->themingDefaults $this->themingDefaults
->expects($this->once()) ->expects($this->once())
->method('getSlogan') ->method('getSlogan')
@ -155,6 +164,7 @@ class AdminTest extends TestCase {
'backgroundMime' => null, 'backgroundMime' => null,
'canThemeIcons' => null, 'canThemeIcons' => null,
'iconDocs' => null, 'iconDocs' => null,
'imprintUrl' => '',
]; ];
$expected = new TemplateResponse('theming', 'settings-admin', $params, ''); $expected = new TemplateResponse('theming', 'settings-admin', $params, '');

View File

@ -193,6 +193,27 @@ class ThemingDefaultsTest extends TestCase {
$this->assertEquals('https://example.com/', $this->template->getBaseUrl()); $this->assertEquals('https://example.com/', $this->template->getBaseUrl());
} }
public function imprintUrlProvider() {
return [
[ '' ],
[ 'https://example.com/imprint.html']
];
}
/**
* @param $imprintUrl
* @dataProvider imprintUrlProvider
*/
public function testGetImprintURL($imprintUrl) {
$this->config
->expects($this->once())
->method('getAppValue')
->with('theming', 'imprintUrl', '')
->willReturn($imprintUrl);
$this->assertEquals($imprintUrl, $this->template->getImprintUrl());
}
public function testGetSloganWithDefault() { public function testGetSloganWithDefault() {
$this->config $this->config
->expects($this->once()) ->expects($this->once())
@ -215,12 +236,13 @@ class ThemingDefaultsTest extends TestCase {
public function testGetShortFooter() { public function testGetShortFooter() {
$this->config $this->config
->expects($this->exactly(3)) ->expects($this->exactly(4))
->method('getAppValue') ->method('getAppValue')
->willReturnMap([ ->willReturnMap([
['theming', 'url', $this->defaults->getBaseUrl(), 'url'], ['theming', 'url', $this->defaults->getBaseUrl(), 'url'],
['theming', 'name', 'Nextcloud', 'Name'], ['theming', 'name', 'Nextcloud', 'Name'],
['theming', 'slogan', $this->defaults->getSlogan(), 'Slogan'], ['theming', 'slogan', $this->defaults->getSlogan(), 'Slogan'],
['theming', 'imprintUrl', '', ''],
]); ]);
$this->assertEquals('<a href="url" target="_blank" rel="noreferrer noopener">Name</a> Slogan', $this->template->getShortFooter()); $this->assertEquals('<a href="url" target="_blank" rel="noreferrer noopener">Name</a> Slogan', $this->template->getShortFooter());
@ -228,17 +250,62 @@ class ThemingDefaultsTest extends TestCase {
public function testGetShortFooterEmptySlogan() { public function testGetShortFooterEmptySlogan() {
$this->config $this->config
->expects($this->exactly(3)) ->expects($this->exactly(4))
->method('getAppValue') ->method('getAppValue')
->willReturnMap([ ->willReturnMap([
['theming', 'url', $this->defaults->getBaseUrl(), 'url'], ['theming', 'url', $this->defaults->getBaseUrl(), 'url'],
['theming', 'name', 'Nextcloud', 'Name'], ['theming', 'name', 'Nextcloud', 'Name'],
['theming', 'slogan', $this->defaults->getSlogan(), ''], ['theming', 'slogan', $this->defaults->getSlogan(), ''],
['theming', 'imprintUrl', '', ''],
]); ]);
$this->assertEquals('<a href="url" target="_blank" rel="noreferrer noopener">Name</a>', $this->template->getShortFooter()); $this->assertEquals('<a href="url" target="_blank" rel="noreferrer noopener">Name</a>', $this->template->getShortFooter());
} }
public function testGetShortFooterImprint() {
$this->config
->expects($this->exactly(4))
->method('getAppValue')
->willReturnMap([
['theming', 'url', $this->defaults->getBaseUrl(), 'url'],
['theming', 'name', 'Nextcloud', 'Name'],
['theming', 'slogan', $this->defaults->getSlogan(), 'Slogan'],
['theming', 'imprintUrl', '', 'https://example.com/imprint'],
]);
$this->l10n
->expects($this->any())
->method('t')
->willReturnArgument(0);
$this->assertEquals('<a href="url" target="_blank" rel="noreferrer noopener">Name</a> Slogan<br/><a href="https://example.com/imprint" class="legal" target="_blank" rel="noreferrer noopener">Legal notice</a>', $this->template->getShortFooter());
}
public function invalidImprintUrlProvider() {
return [
['example.com/imprint'], # missing scheme
['https:///imprint'], # missing host
];
}
/**
* @param $invalidImprintUrl
* @dataProvider invalidImprintUrlProvider
*/
public function testGetShortFooterInvalidImprint($invalidImprintUrl) {
$this->config
->expects($this->exactly(4))
->method('getAppValue')
->willReturnMap([
['theming', 'url', $this->defaults->getBaseUrl(), 'url'],
['theming', 'name', 'Nextcloud', 'Name'],
['theming', 'slogan', $this->defaults->getSlogan(), 'Slogan'],
['theming', 'imprintUrl', '', $invalidImprintUrl],
]);
$this->assertEquals('<a href="url" target="_blank" rel="noreferrer noopener">Name</a> Slogan', $this->template->getShortFooter());
}
public function testgetColorPrimaryWithDefault() { public function testgetColorPrimaryWithDefault() {
$this->config $this->config
->expects($this->once()) ->expects($this->once())

View File

@ -741,6 +741,10 @@ footer .info a {
overflow: hidden; overflow: hidden;
} }
a.legal {
font-size: smaller;
}
/* for low-res screens, use Regular font-weight instead of Light */ /* for low-res screens, use Regular font-weight instead of Light */
@media (-webkit-max-device-pixel-ratio: 1.3), (max-resolution: 124.8dpi) { @media (-webkit-max-device-pixel-ratio: 1.3), (max-resolution: 124.8dpi) {
@font-face { @font-face {