also add a privacy link
Signed-off-by: Arthur Schiwon <blizzz@arthur-schiwon.de>
This commit is contained in:
parent
eefe256abc
commit
16c061818e
8 changed files with 151 additions and 21 deletions
|
@ -84,7 +84,8 @@ function hideUndoButton(setting, value) {
|
||||||
color: '#0082c9',
|
color: '#0082c9',
|
||||||
logoMime: '',
|
logoMime: '',
|
||||||
backgroundMime: '',
|
backgroundMime: '',
|
||||||
imprintUrl: ''
|
imprintUrl: '',
|
||||||
|
privacyUrl: ''
|
||||||
};
|
};
|
||||||
|
|
||||||
if (value === themingDefaults[setting] || value === '') {
|
if (value === themingDefaults[setting] || value === '') {
|
||||||
|
|
|
@ -171,6 +171,16 @@ class ThemingController extends Controller {
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'privacyUrl':
|
||||||
|
if (strlen($value) > 500) {
|
||||||
|
return new DataResponse([
|
||||||
|
'data' => [
|
||||||
|
'message' => $this->l10n->t('The given privacy policy 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([
|
||||||
|
@ -419,6 +429,7 @@ class ThemingController extends Controller {
|
||||||
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()) . ',
|
imprintUrl: ' . json_encode($this->themingDefaults->getImprintUrl()) . ',
|
||||||
|
privacyUrl: ' . json_encode($this->themingDefaults->getPrivacyUrl()) . ',
|
||||||
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) . '
|
||||||
};
|
};
|
||||||
|
|
|
@ -85,6 +85,7 @@ class Admin implements ISettings {
|
||||||
'iconDocs' => $this->urlGenerator->linkToDocs('admin-theming-icons'),
|
'iconDocs' => $this->urlGenerator->linkToDocs('admin-theming-icons'),
|
||||||
'images' => $this->imageManager->getCustomImages(),
|
'images' => $this->imageManager->getCustomImages(),
|
||||||
'imprintUrl' => $this->themingDefaults->getImprintUrl(),
|
'imprintUrl' => $this->themingDefaults->getImprintUrl(),
|
||||||
|
'privacyUrl' => $this->themingDefaults->getPrivacyUrl(),
|
||||||
];
|
];
|
||||||
|
|
||||||
return new TemplateResponse('theming', 'settings-admin', $parameters, '');
|
return new TemplateResponse('theming', 'settings-admin', $parameters, '');
|
||||||
|
|
|
@ -145,20 +145,41 @@ class ThemingDefaults extends \OC_Defaults {
|
||||||
return $this->config->getAppValue('theming', 'imprintUrl', '');
|
return $this->config->getAppValue('theming', 'imprintUrl', '');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getPrivacyUrl() {
|
||||||
|
return $this->config->getAppValue('theming', 'privacyUrl', '');
|
||||||
|
}
|
||||||
|
|
||||||
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();
|
$links = [
|
||||||
if($imprintUrl !== ''
|
[
|
||||||
&& filter_var($imprintUrl, FILTER_VALIDATE_URL, [
|
'text' => $this->l->t('Legal notice'),
|
||||||
'flags' => FILTER_FLAG_SCHEME_REQUIRED | FILTER_FLAG_HOST_REQUIRED
|
'url' => (string)$this->getImprintUrl()
|
||||||
])
|
],
|
||||||
) {
|
[
|
||||||
$footer .= '<br/><a href="' . $imprintUrl . '" class="legal" target="_blank"' .
|
'text' => $this->l->t('Privacy policy'),
|
||||||
' rel="noreferrer noopener">' . $this->l->t('Legal notice') . '</a>';
|
'url' => (string)$this->getPrivacyUrl()
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
$legalLinks = ''; $divider = '';
|
||||||
|
foreach($links as $link) {
|
||||||
|
if($link['url'] !== ''
|
||||||
|
&& filter_var($link['url'], FILTER_VALIDATE_URL, [
|
||||||
|
'flags' => FILTER_FLAG_SCHEME_REQUIRED | FILTER_FLAG_HOST_REQUIRED
|
||||||
|
])
|
||||||
|
) {
|
||||||
|
$legalLinks .= $divider . '<a href="' . $link['url'] . '" class="legal" target="_blank"' .
|
||||||
|
' rel="noreferrer noopener">' . $link['text'] . '</a>';
|
||||||
|
$divider = ' · ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if($legalLinks !== '' ) {
|
||||||
|
$footer .= '<br/>' . $legalLinks;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $footer;
|
return $footer;
|
||||||
|
|
|
@ -96,9 +96,16 @@ style('theming', 'settings-admin');
|
||||||
<div class="advanced-options">
|
<div class="advanced-options">
|
||||||
<div>
|
<div>
|
||||||
<label>
|
<label>
|
||||||
<span><?php p($l->t('Legal notice link')) ?></span>
|
<span><?php p($l->t('Legal notice link')) ?></span>
|
||||||
<input id="theming-imprintUrl" type="url" placeholder="<?php p($l->t('https://…')); ?>" value="<?php p($_['imprintUrl']) ?>" maxlength="500" />
|
<input id="theming-imprintUrl" type="url" 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>
|
<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>
|
||||||
|
<label>
|
||||||
|
<span><?php p($l->t('Privacy policy link')) ?></span>
|
||||||
|
<input id="theming-privacyUrl" type="url" placeholder="<?php p($l->t('https://…')); ?>" value="<?php p($_['privacyUrl']) ?>" maxlength="500" />
|
||||||
|
<div data-setting="privacyUrl" data-toggle="tooltip" data-original-title="<?php p($l->t('Reset to default')); ?>" class="theme-undo icon icon-history"></div>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="advanced-option-logoheader">
|
<div class="advanced-option-logoheader">
|
||||||
|
|
|
@ -818,6 +818,7 @@ class ThemingControllerTest extends TestCase {
|
||||||
slogan: "",
|
slogan: "",
|
||||||
color: "#000",
|
color: "#000",
|
||||||
imprintUrl: null,
|
imprintUrl: null,
|
||||||
|
privacyUrl: null,
|
||||||
inverted: false,
|
inverted: false,
|
||||||
cacheBuster: null
|
cacheBuster: null
|
||||||
};
|
};
|
||||||
|
@ -853,6 +854,7 @@ class ThemingControllerTest extends TestCase {
|
||||||
slogan: "awesome",
|
slogan: "awesome",
|
||||||
color: "#ffffff",
|
color: "#ffffff",
|
||||||
imprintUrl: null,
|
imprintUrl: null,
|
||||||
|
privacyUrl: null,
|
||||||
inverted: true,
|
inverted: true,
|
||||||
cacheBuster: null
|
cacheBuster: null
|
||||||
};
|
};
|
||||||
|
|
|
@ -85,6 +85,10 @@ class AdminTest extends TestCase {
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
->method('getImprintUrl')
|
->method('getImprintUrl')
|
||||||
->willReturn('');
|
->willReturn('');
|
||||||
|
$this->themingDefaults
|
||||||
|
->expects($this->once())
|
||||||
|
->method('getPrivacyUrl')
|
||||||
|
->willReturn('');
|
||||||
$this->themingDefaults
|
$this->themingDefaults
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
->method('getSlogan')
|
->method('getSlogan')
|
||||||
|
@ -110,6 +114,7 @@ class AdminTest extends TestCase {
|
||||||
'iconDocs' => null,
|
'iconDocs' => null,
|
||||||
'images' => [],
|
'images' => [],
|
||||||
'imprintUrl' => '',
|
'imprintUrl' => '',
|
||||||
|
'privacyUrl' => '',
|
||||||
];
|
];
|
||||||
|
|
||||||
$expected = new TemplateResponse('theming', 'settings-admin', $params, '');
|
$expected = new TemplateResponse('theming', 'settings-admin', $params, '');
|
||||||
|
@ -139,6 +144,10 @@ class AdminTest extends TestCase {
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
->method('getImprintUrl')
|
->method('getImprintUrl')
|
||||||
->willReturn('');
|
->willReturn('');
|
||||||
|
$this->themingDefaults
|
||||||
|
->expects($this->once())
|
||||||
|
->method('getPrivacyUrl')
|
||||||
|
->willReturn('');
|
||||||
$this->themingDefaults
|
$this->themingDefaults
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
->method('getSlogan')
|
->method('getSlogan')
|
||||||
|
@ -164,6 +173,7 @@ class AdminTest extends TestCase {
|
||||||
'iconDocs' => '',
|
'iconDocs' => '',
|
||||||
'images' => [],
|
'images' => [],
|
||||||
'imprintUrl' => '',
|
'imprintUrl' => '',
|
||||||
|
'privacyUrl' => '',
|
||||||
];
|
];
|
||||||
|
|
||||||
$expected = new TemplateResponse('theming', 'settings-admin', $params, '');
|
$expected = new TemplateResponse('theming', 'settings-admin', $params, '');
|
||||||
|
|
|
@ -195,16 +195,16 @@ class ThemingDefaultsTest extends TestCase {
|
||||||
$this->assertEquals('https://example.com/', $this->template->getBaseUrl());
|
$this->assertEquals('https://example.com/', $this->template->getBaseUrl());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function imprintUrlProvider() {
|
public function legalUrlProvider() {
|
||||||
return [
|
return [
|
||||||
[ '' ],
|
[ '' ],
|
||||||
[ 'https://example.com/imprint.html']
|
[ 'https://example.com/legal.html']
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $imprintUrl
|
* @param $imprintUrl
|
||||||
* @dataProvider imprintUrlProvider
|
* @dataProvider legalUrlProvider
|
||||||
*/
|
*/
|
||||||
public function testGetImprintURL($imprintUrl) {
|
public function testGetImprintURL($imprintUrl) {
|
||||||
$this->config
|
$this->config
|
||||||
|
@ -216,6 +216,20 @@ class ThemingDefaultsTest extends TestCase {
|
||||||
$this->assertEquals($imprintUrl, $this->template->getImprintUrl());
|
$this->assertEquals($imprintUrl, $this->template->getImprintUrl());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $privacyUrl
|
||||||
|
* @dataProvider legalUrlProvider
|
||||||
|
*/
|
||||||
|
public function testGetPrivacyURL($privacyUrl) {
|
||||||
|
$this->config
|
||||||
|
->expects($this->once())
|
||||||
|
->method('getAppValue')
|
||||||
|
->with('theming', 'privacyUrl', '')
|
||||||
|
->willReturn($privacyUrl);
|
||||||
|
|
||||||
|
$this->assertEquals($privacyUrl, $this->template->getPrivacyUrl());
|
||||||
|
}
|
||||||
|
|
||||||
public function testGetSloganWithDefault() {
|
public function testGetSloganWithDefault() {
|
||||||
$this->config
|
$this->config
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
|
@ -238,13 +252,14 @@ class ThemingDefaultsTest extends TestCase {
|
||||||
|
|
||||||
public function testGetShortFooter() {
|
public function testGetShortFooter() {
|
||||||
$this->config
|
$this->config
|
||||||
->expects($this->exactly(4))
|
->expects($this->exactly(5))
|
||||||
->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', '', ''],
|
['theming', 'imprintUrl', '', ''],
|
||||||
|
['theming', 'privacyUrl', '', ''],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$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());
|
||||||
|
@ -252,13 +267,14 @@ class ThemingDefaultsTest extends TestCase {
|
||||||
|
|
||||||
public function testGetShortFooterEmptySlogan() {
|
public function testGetShortFooterEmptySlogan() {
|
||||||
$this->config
|
$this->config
|
||||||
->expects($this->exactly(4))
|
->expects($this->exactly(5))
|
||||||
->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', '', ''],
|
['theming', 'imprintUrl', '', ''],
|
||||||
|
['theming', 'privacyUrl', '', ''],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$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());
|
||||||
|
@ -266,13 +282,14 @@ class ThemingDefaultsTest extends TestCase {
|
||||||
|
|
||||||
public function testGetShortFooterImprint() {
|
public function testGetShortFooterImprint() {
|
||||||
$this->config
|
$this->config
|
||||||
->expects($this->exactly(4))
|
->expects($this->exactly(5))
|
||||||
->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', '', 'https://example.com/imprint'],
|
['theming', 'imprintUrl', '', 'https://example.com/imprint'],
|
||||||
|
['theming', 'privacyUrl', '', ''],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->l10n
|
$this->l10n
|
||||||
|
@ -283,26 +300,86 @@ class ThemingDefaultsTest extends TestCase {
|
||||||
$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());
|
$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() {
|
public function testGetShortFooterPrivacy() {
|
||||||
|
$this->config
|
||||||
|
->expects($this->exactly(5))
|
||||||
|
->method('getAppValue')
|
||||||
|
->willReturnMap([
|
||||||
|
['theming', 'url', $this->defaults->getBaseUrl(), 'url'],
|
||||||
|
['theming', 'name', 'Nextcloud', 'Name'],
|
||||||
|
['theming', 'slogan', $this->defaults->getSlogan(), 'Slogan'],
|
||||||
|
['theming', 'imprintUrl', '', ''],
|
||||||
|
['theming', 'privacyUrl', '', 'https://example.com/privacy'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$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/privacy" class="legal" target="_blank" rel="noreferrer noopener">Privacy policy</a>', $this->template->getShortFooter());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetShortFooterAllLegalLinks() {
|
||||||
|
$this->config
|
||||||
|
->expects($this->exactly(5))
|
||||||
|
->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'],
|
||||||
|
['theming', 'privacyUrl', '', 'https://example.com/privacy'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$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> · <a href="https://example.com/privacy" class="legal" target="_blank" rel="noreferrer noopener">Privacy policy</a>', $this->template->getShortFooter());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function invalidLegalUrlProvider() {
|
||||||
return [
|
return [
|
||||||
['example.com/imprint'], # missing scheme
|
['example.com/legal'], # missing scheme
|
||||||
['https:///imprint'], # missing host
|
['https:///legal'], # missing host
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $invalidImprintUrl
|
* @param $invalidImprintUrl
|
||||||
* @dataProvider invalidImprintUrlProvider
|
* @dataProvider invalidLegalUrlProvider
|
||||||
*/
|
*/
|
||||||
public function testGetShortFooterInvalidImprint($invalidImprintUrl) {
|
public function testGetShortFooterInvalidImprint($invalidImprintUrl) {
|
||||||
$this->config
|
$this->config
|
||||||
->expects($this->exactly(4))
|
->expects($this->exactly(5))
|
||||||
->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', '', $invalidImprintUrl],
|
['theming', 'imprintUrl', '', $invalidImprintUrl],
|
||||||
|
['theming', 'privacyUrl', '', ''],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->assertEquals('<a href="url" target="_blank" rel="noreferrer noopener">Name</a> – Slogan', $this->template->getShortFooter());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $invalidPrivacyUrl
|
||||||
|
* @dataProvider invalidLegalUrlProvider
|
||||||
|
*/
|
||||||
|
public function testGetShortFooterInvalidPrivacy($invalidPrivacyUrl) {
|
||||||
|
$this->config
|
||||||
|
->expects($this->exactly(5))
|
||||||
|
->method('getAppValue')
|
||||||
|
->willReturnMap([
|
||||||
|
['theming', 'url', $this->defaults->getBaseUrl(), 'url'],
|
||||||
|
['theming', 'name', 'Nextcloud', 'Name'],
|
||||||
|
['theming', 'slogan', $this->defaults->getSlogan(), 'Slogan'],
|
||||||
|
['theming', 'imprintUrl', '', ''],
|
||||||
|
['theming', 'privacyUrl', '', $invalidPrivacyUrl],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$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());
|
||||||
|
|
Loading…
Reference in a new issue