"name": "{PAGE_TITLE|language}",
"logo": {
"@type": "ImageObject",
- "url": "{@$__wcf->getPath()}images/default-logo.png",{* @TODO *}
- "width": 288,
- "height": 40
+ "url": "{$__wcf->getStyleHandler()->getStyle()->getPageLogo()}",
+ "width": {@$__wcf->getStyleHandler()->getStyle()->getVariable('pageLogoWidth')},
+ "height": {@$__wcf->getStyleHandler()->getStyle()->getVariable('pageLogoHeight')}
}
}
{if $articleContent->getImage()}
<body>
<header class="header">
<div class="logo">
- <a href="{link}{/link}"><amp-img width="288" height="40" src="{@$__wcf->getPath()}images/default-logo.png"></amp-img></a>{* @TODO *}
+ <a href="{link}{/link}"><amp-img width="{@$__wcf->getStyleHandler()->getStyle()->getVariable('pageLogoWidth')}" height="{@$__wcf->getStyleHandler()->getStyle()->getVariable('pageLogoHeight')}" src="{$__wcf->getStyleHandler()->getStyle()->getPageLogo()}"></amp-img></a>
</div>
<button on='tap:sidebar.toggle'>{lang}wcf.global.page.pagination{/lang}</button>
<div itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="{PAGE_TITLE|language}">
<div itemprop="logo" itemscope itemtype="http://schema.org/ImageObject">
- <meta itemprop="url" content="{@$__wcf->getPath()}images/default-logo.png">{* @TODO *}
+ <meta itemprop="url" content="{$__wcf->getStyleHandler()->getStyle()->getPageLogo()}">
</div>
</div>
</div>
{if MODULE_WCF_AD && $__disableAds|empty}{@$__wcf->getAdHandler()->getAds('com.woltlab.wcf.logo')}{/if}
<a href="{link}{/link}">
- {* @TODO *}
- <img src="{@$__wcf->getPath()}images/default-logo.png" alt="" class="pageHeaderLogoLarge">
- <img src="{@$__wcf->getPath()}images/default-logo-small.png" alt="" class="pageHeaderLogoSmall">
- {*if $__wcf->getStyleHandler()->getStyle()->getPageLogo()}
- <img src="{$__wcf->getStyleHandler()->getStyle()->getPageLogo()}" alt="">
- {/if*}
+ <img src="{$__wcf->getStyleHandler()->getStyle()->getPageLogo()}" alt="" class="pageHeaderLogoLarge" style="width: {@$__wcf->getStyleHandler()->getStyle()->getVariable('pageLogoWidth')}px; height: {@$__wcf->getStyleHandler()->getStyle()->getVariable('pageLogoHeight')}px">
+ <img src="{$__wcf->getStyleHandler()->getStyle()->getPageLogoMobile()}" alt="" class="pageHeaderLogoSmall">
+
{event name='headerLogo'}
</a>
</div>
\ No newline at end of file
{* main menu / page options / breadcrumbs *}
-<div id="pageMainMenuMobile" class="pageMainMenuMobile menuOverlayMobile" data-page-logo="{$__wcf->getPath()}images/default-logo.png"> {* TODO: use real path *}
+<div id="pageMainMenuMobile" class="pageMainMenuMobile menuOverlayMobile" data-page-logo="{$__wcf->getStyleHandler()->getStyle()->getPageLogo()}">
<ol class="menuOverlayItemList" data-title="{lang}wcf.menu.page{/lang}">
<li class="menuOverlayTitle">{lang}wcf.menu.page.navigation{/lang}</li>
{*<li class="menuOverlayItem">
</div>
{* user menu *}
-<div id="pageUserMenuMobile" class="pageUserMenuMobile menuOverlayMobile" data-page-logo="{$__wcf->getPath()}images/default-logo.png">
+<div id="pageUserMenuMobile" class="pageUserMenuMobile menuOverlayMobile" data-page-logo="{$__wcf->getStyleHandler()->getStyle()->getPageLogo()}">
<ol class="menuOverlayItemList" data-title="{lang}wcf.menu.user{/lang}">
{if $__wcf->user->userID}
{* logged-in *}
}
else {
// no logo defined, fallback to application logo
- $src = $('#logo > a > img').prop('src');
+ $src = WCF_PATH + 'images/default-logo.png';
+ $('#pageLogoWidth').val(288);
+ $('#pageLogoHeight').val(40);
}
this._image.attr('src', $src + '?timestamp=' + Date.now());
// hide error
this._button.next('.innerError').remove();
+ $('#pageLogoWidth').val(data.returnValues.width);
+ $('#pageLogoHeight').val(data.returnValues.height);
+
// show success message
var $notification = new WCF.System.Notification(WCF.Language.get('wcf.global.success'));
$notification.show();
}
});
+/**
+ * Handles the mobile logo upload.
+ *
+ * @param string tmpHash
+ */
+WCF.ACP.Style.LogoUploadMobile = WCF.Upload.extend({
+ /**
+ * upload button
+ * @var jQuery
+ */
+ _button: null,
+
+ /**
+ * image path
+ * @var jQuery
+ */
+ _imagePath: null,
+
+ /**
+ * logo
+ * @var jQuery
+ */
+ _logo: null,
+
+ /**
+ * page logo input field
+ * @var jQuery
+ */
+ _pageLogo: null,
+
+ /**
+ * tmp hash
+ * @var string
+ */
+ _tmpHash: '',
+
+ /**
+ * absolute path to WCF directory
+ * @var string
+ */
+ _wcfPath: '',
+
+ /**
+ * @see WCF.Upload.init()
+ */
+ init: function(tmpHash, wcfPath) {
+ this._tmpHash = tmpHash;
+ this._wcfPath = wcfPath;
+
+ this._button = $('#uploadLogoMobile');
+ this._image = $('#styleLogoMobile');
+ this._imagePath = $('#imagePathMobile');
+ this._pageLogo = $('#pageLogoMobile');
+
+ this._super(this._button, undefined, 'wcf\\data\\style\\StyleAction', { action: 'uploadLogoMobile' });
+
+ if (!this._image.attr('src').length) {
+ this._updateLogo();
+ }
+
+ this._pageLogo.blur($.proxy(this._updateLogo, this));
+ },
+
+ /**
+ * Updates the logo preview.
+ */
+ _updateLogo: function() {
+ var $src = this._pageLogo.val();
+ if ($src.length) {
+ if (!$src.match(/^https?:\/\//)) {
+ var $path = this._imagePath.val();
+ if (!$path) {
+ $path = 'images/';
+ }
+
+ $path = this._wcfPath + $path.replace(/^\/?images\/?/, '');
+ if ($path.substr(-1) !== '/') {
+ $path += '/';
+ }
+
+ $src = $path + $src;
+ }
+ }
+ else {
+ // no logo defined, fallback to application logo
+ $src = WCF_PATH + 'images/default-logo-small.png';
+ }
+
+ this._image.attr('src', $src + '?timestamp=' + Date.now());
+ },
+
+ /**
+ * @see WCF.Upload._initFile()
+ */
+ _initFile: function(file) {
+ return this._image;
+ },
+
+ /**
+ * @see WCF.Upload._getParameters()
+ */
+ _getParameters: function() {
+ return {
+ tmpHash: this._tmpHash
+ };
+ },
+
+ /**
+ * @see WCF.Upload._success()
+ */
+ _success: function(uploadID, data) {
+ if (data.returnValues.url) {
+ // show image
+ this._image.attr('src', data.returnValues.url + '?timestamp=' + Date.now());
+ this._pageLogo.val(data.returnValues.url);
+
+ // hide error
+ this._button.next('.innerError').remove();
+
+ // show success message
+ var $notification = new WCF.System.Notification(WCF.Language.get('wcf.global.success'));
+ $notification.show();
+ }
+ else if (data.returnValues.errorType) {
+ // show error
+ this._getInnerErrorElement().text(WCF.Language.get('wcf.acp.style.image.error.' + data.returnValues.errorType));
+ }
+ },
+
+ /**
+ * Returns error display element.
+ *
+ * @return jQuery
+ */
+ _getInnerErrorElement: function() {
+ var $span = this._button.next('.innerError');
+ if (!$span.length) {
+ $span = $('<small class="innerError" />').insertAfter(this._button);
+ }
+
+ return $span;
+ }
+});
+
/**
* Handles style list management buttons.
*/
}
}
}
+
+#styleLogo,
+#styleLogoMobile {
+ background-color: #fff;
+ background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEX////MzMw46qqDAAAAD0lEQVQI12P4z4Ad4ZAAAH6/D/Hgw85/AAAAAElFTkSuQmCC);
+ border: 1px solid #ccc;
+}
'wcf.acp.style.image.error.invalidExtension': '{lang}wcf.acp.style.image.error.invalidExtension{/lang}'
});
new WCF.ACP.Style.LogoUpload('{$tmpHash}', '{@$__wcf->getPath()}images/');
+ new WCF.ACP.Style.LogoUploadMobile('{$tmpHash}', '{@$__wcf->getPath()}images/');
{if $action == 'edit'}
new WCF.ACP.Style.CopyStyle({@$style->styleID});
<dd>
<img src="{if $action == 'add'}{@$__wcf->getPath()}images/stylePreview.png{else}{@$style->getPreviewImage()}{/if}" alt="" id="styleImage">
<div id="uploadImage"></div>
- {if $errorField == 'image'}
- <small class="innerError">
- {if $errorType == 'empty'}
- {lang}wcf.global.form.error.empty{/lang}
- {else}
- {lang}wcf.acp.style.image.error.{$errorType}{/lang}
- {/if}
- </small>
- {/if}
<small>{lang}wcf.acp.style.image.description{/lang}</small>
</dd>
</dl>
<dd>
<img src="" alt="" id="styleLogo" style="max-width: 100%">
<div id="uploadLogo"></div>
- {if $errorField == 'image'}
- <small class="innerError">
- {if $errorType == 'empty'}
- {lang}wcf.global.form.error.empty{/lang}
- {else}
- {lang}wcf.acp.style.image.error.{$errorType}{/lang}
- {/if}
- </small>
- {/if}
</dd>
<dd>
<input type="text" name="pageLogo" id="pageLogo" value="{$variables[pageLogo]}" class="long">
</dd>
</dl>
+ <dl>
+ <dt><label for="pageLogoWidth">{lang}wcf.acp.style.globals.pageLogo.width{/lang}</label></dt>
+ <dd>
+ <input type="number" name="pageLogoWidth" id="pageLogoWidth" value="{$variables[pageLogoWidth]}" class="tiny">
+ </dd>
+ </dl>
+ <dl>
+ <dt><label for="pageLogoHeight">{lang}wcf.acp.style.globals.pageLogo.height{/lang}</label></dt>
+ <dd>
+ <input type="number" name="pageLogoHeight" id="pageLogoHeight" value="{$variables[pageLogoHeight]}" class="tiny">
+ </dd>
+ </dl>
+
+ <dl>
+ <dt><label for="pageLogoMobile">{lang}wcf.acp.style.globals.pageLogoMobile{/lang}</label></dt>
+ <dd>
+ <img src="" alt="" id="styleLogoMobile" style="max-width: 100%">
+ <div id="uploadLogoMobile"></div>
+ </dd>
+ <dd>
+ <input type="text" name="pageLogoMobile" id="pageLogoMobile" value="{$variables[pageLogoMobile]}" class="long">
+ <small>{lang}wcf.acp.style.globals.pageLogoMobile.description{/lang}</small>
+ </dd>
+ </dl>
+
{event name='logoFields'}
</section>
'individualScss',
'overrideScss',
'pageLogo',
+ 'pageLogoWidth',
+ 'pageLogoHeight',
+ 'pageLogoMobile',
'useFluidLayout',
'useGoogleFont',
'wcfFontFamilyGoogle',
$this->saved();
// reset variables
- $this->authorName = $this->authorURL = $this->copyright = $this->packageName = $this->image = '';
+ $this->authorName = $this->authorURL = $this->copyright = $this->packageName = '';
$this->license = $this->styleDate = $this->styleDescription = $this->styleName = $this->styleVersion = '';
$this->imagePath = 'images/';
return $this->getImage($this->getDecoratedObject()->getVariable('pageLogo'));
}
- return '';
+ return WCF::getPath() . 'images/default-logo.png';
+ }
+
+ /**
+ * Returns mobile page logo.
+ *
+ * @return string
+ */
+ public function getPageLogoMobile() {
+ if ($this->getDecoratedObject()->getVariable('pageLogoMobile')) {
+ return $this->getImage($this->getDecoratedObject()->getVariable('pageLogoMobile'));
+ }
+
+ return WCF::getPath() . 'images/default-logo-small.png';
}
}
/**
* @inheritDoc
*/
- protected $requireACP = ['copy', 'delete', 'markAsTainted', 'setAsDefault', 'toggle', 'update', 'upload', 'uploadLogo'];
+ protected $requireACP = ['copy', 'delete', 'markAsTainted', 'setAsDefault', 'toggle', 'update', 'upload', 'uploadLogo', 'uploadLogoMobile'];
/**
* style object
// store extension within session variables
WCF::getSession()->register('styleLogo-'.$this->parameters['tmpHash'], $file->getFileExtension());
+ // get logo size
+ list($width, $height) = getimagesize(WCF_DIR.'images/styleLogo-'.$this->parameters['tmpHash'].'.'.$file->getFileExtension());
+
+ // return result
+ return [
+ 'url' => WCF::getPath().'images/styleLogo-'.$this->parameters['tmpHash'].'.'.$file->getFileExtension(),
+ 'width' => $width,
+ 'height' => $height
+ ];
+ }
+ else {
+ throw new UserInputException('image', 'uploadFailed');
+ }
+ }
+ }
+ catch (UserInputException $e) {
+ $file->setValidationErrorType($e->getType());
+ }
+
+ return ['errorType' => $file->getValidationErrorType()];
+ }
+
+ /**
+ * Validates parameters to update a mobile logo.
+ */
+ public function validateUploadLogoMobile() {
+ $this->validateUpload();
+ }
+
+ /**
+ * Handles mobile logo upload.
+ *
+ * @return string[]
+ */
+ public function uploadLogoMobile() {
+ // save files
+ /** @noinspection PhpUndefinedMethodInspection */
+ /** @var UploadFile[] $files */
+ $files = $this->parameters['__files']->getFiles();
+ $file = $files[0];
+
+ try {
+ if (!$file->getValidationErrorType()) {
+ // shrink avatar if necessary
+ $fileLocation = $file->getLocation();
+
+ // move uploaded file
+ if (@copy($fileLocation, WCF_DIR.'images/styleLogo-mobile-'.$this->parameters['tmpHash'].'.'.$file->getFileExtension())) {
+ @unlink($fileLocation);
+
+ // store extension within session variables
+ WCF::getSession()->register('styleLogo-mobile-'.$this->parameters['tmpHash'], $file->getFileExtension());
+
// return result
return [
- 'url' => WCF::getPath().'images/styleLogo-'.$this->parameters['tmpHash'].'.'.$file->getFileExtension()
+ 'url' => WCF::getPath().'images/styleLogo-mobile-'.$this->parameters['tmpHash'].'.'.$file->getFileExtension()
];
}
else {
display: none;
}
}
+
+ .pageHeaderLogoLarge {
+ max-width: 100%;
+ }
+
+ .pageHeaderLogoSmall {
+ max-height: 30px;
+ }
}
/* MAIN MENU */
INSERT INTO wcf1_style_variable (variableName, defaultValue) VALUES ('messageSidebarOrientation', 'left');
INSERT INTO wcf1_style_variable (variableName, defaultValue) VALUES ('overrideScss', '');
INSERT INTO wcf1_style_variable (variableName, defaultValue) VALUES ('pageLogo', '');
+INSERT INTO wcf1_style_variable (variableName, defaultValue) VALUES ('pageLogoWidth', '288');
+INSERT INTO wcf1_style_variable (variableName, defaultValue) VALUES ('pageLogoHeight', '40');
+INSERT INTO wcf1_style_variable (variableName, defaultValue) VALUES ('pageLogoMobile', '');
INSERT INTO wcf1_style_variable (variableName, defaultValue) VALUES ('useFluidLayout', '1');
INSERT INTO wcf1_style_variable (variableName, defaultValue) VALUES ('useGoogleFont', '1');
INSERT INTO wcf1_style_variable (variableName, defaultValue) VALUES ('wcfButtonBackground', 'rgba(224, 224, 224, 1)');